gfxstream: simplify codegen

This simplifies the amount of code imported from Vulkan
docs.  It vendors the code to just a subset needed by
the cerealgenerator.  The files that are kept are:

    - generator.py
    - cgenerator.py
    - reg.py
    - genvk.py

Since these files originate with Khronos, they are
Apache licensed.

Long-term, there are various ideas on how to proceed
with codegen.  Probably the above files can be nuked
in the event some of those ideas come to pass.

Reviewed-by: Aaron Ruby <aruby@blackberry.com>
Acked-by: Yonggang Luo <luoyonggang@gmail.com>
Acked-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27246>
This commit is contained in:
Gurchetan Singh
2024-09-16 14:34:48 -07:00
committed by Marge Bot
parent 13c4d98bc6
commit 94f641d120
9 changed files with 115 additions and 2154 deletions

View File

@@ -661,15 +661,12 @@ def parse_func_expr(parsed_sexp):
def parseFilterFuncExpr(expr):
res = parse_func_expr(parse_sexp(expr))
print("parseFilterFuncExpr: parsed %s" % res)
return res
def parseLetBodyExpr(expr):
res = parse_func_expr(parse_sexp(expr))
print("parseLetBodyExpr: parsed %s" % res)
return res
def makeVulkanTypeFromXMLTag(typeInfo, parentName: str, tag: Element) -> VulkanType:
res = VulkanType()

View File

@@ -418,9 +418,6 @@ class VulkanCountingCodegen(VulkanTypeIterator):
self.beginFilterGuard(vulkanType)
self.doAllocSpace(vulkanType)
if vulkanType.filterVar != None:
print("onPointer Needs filter: %s filterVar %s" % (access, vulkanType.filterVar))
if vulkanType.isHandleType() and self.mapHandles:
self.genHandleMappingCall(vulkanType, access, lenAccess)
else:
@@ -457,8 +454,6 @@ class VulkanCountingCodegen(VulkanTypeIterator):
if vulkanType.isHandleType() and self.mapHandles:
access = self.exprAccessor(vulkanType)
if vulkanType.filterVar != None:
print("onValue Needs filter: %s filterVar %s" % (access, vulkanType.filterVar))
self.genHandleMappingCall(
vulkanType.getForAddressAccess(), access, "1")
elif self.typeInfo.isNonAbiPortableType(vulkanType.typeName):

View File

@@ -540,9 +540,6 @@ class VulkanMarshalingCodegen(VulkanTypeIterator):
self.beginFilterGuard(vulkanType)
self.doAllocSpace(vulkanType)
if vulkanType.filterVar != None:
print("onPointer Needs filter: %s filterVar %s" % (access, vulkanType.filterVar))
if vulkanType.isHandleType() and self.mapHandles:
self.genHandleMappingCall(vulkanType, access, lenAccess)
else:
@@ -576,8 +573,6 @@ class VulkanMarshalingCodegen(VulkanTypeIterator):
if vulkanType.isHandleType() and self.mapHandles:
access = self.exprAccessor(vulkanType)
if vulkanType.filterVar != None:
print("onValue Needs filter: %s filterVar %s" % (access, vulkanType.filterVar))
self.genHandleMappingCall(
vulkanType.getForAddressAccess(), access, "1")
elif self.typeInfo.isNonAbiPortableType(vulkanType.typeName):

View File

@@ -638,9 +638,6 @@ class VulkanReservedMarshalingCodegen(VulkanTypeIterator):
self.beginFilterGuard(vulkanType)
self.doAllocSpace(vulkanType)
if vulkanType.filterVar != None:
print("onPointer Needs filter: %s filterVar %s" % (access, vulkanType.filterVar))
if vulkanType.isHandleType() and self.mapHandles:
self.genHandleMappingCall(
vulkanType, access, lenAccess, lenAccessGuard)
@@ -675,8 +672,6 @@ class VulkanReservedMarshalingCodegen(VulkanTypeIterator):
if vulkanType.isHandleType() and self.mapHandles:
access = self.exprAccessor(vulkanType)
if vulkanType.filterVar != None:
print("onValue Needs filter: %s filterVar %s" % (access, vulkanType.filterVar))
self.genHandleMappingCall(
vulkanType.getForAddressAccess(), access, "1", None)
elif self.typeInfo.isNonAbiPortableType(vulkanType.typeName):

View File

@@ -241,7 +241,6 @@ def banner_command(argv):
def envGetOrDefault(key, default=None):
if key in os.environ:
return os.environ[key]
print("envGetOrDefault: notfound: %s" % key)
return default
# ---- methods overriding base class ----

View File

@@ -1,6 +1,7 @@
#!/usr/bin/python3 -i
#
# Copyright 2013-2023 The Khronos Group Inc.
# Copyright 2023-2024 Google Inc.
#
# SPDX-License-Identifier: Apache-2.0
@@ -8,7 +9,6 @@ import os
import re
from generator import (GeneratorOptions,
MissingGeneratorOptionsConventionsError,
MissingGeneratorOptionsError, MissingRegistryError,
OutputGenerator, noneStr, regSortFeatures, write)
@@ -20,25 +20,9 @@ class CGeneratorOptions(GeneratorOptions):
def __init__(self,
prefixText='',
genFuncPointers=True,
protectFile=True,
protectFeature=True,
protectProto=None,
protectProtoStr=None,
protectExtensionProto=None,
protectExtensionProtoStr=None,
apicall='',
apientry='',
apientryp='',
indentFuncProto=True,
indentFuncPointer=False,
alignFuncParam=0,
genEnumBeginEndRange=False,
genAliasMacro=False,
genStructExtendsComment=False,
aliasMacro='',
misracstyle=False,
misracppstyle=False,
**kwargs
):
"""Constructor.
@@ -46,115 +30,27 @@ class CGeneratorOptions(GeneratorOptions):
- prefixText - list of strings to prefix generated header with
(usually a copyright statement + calling convention macros)
- protectFile - True if multiple inclusion protection should be
generated (based on the filename) around the entire header
- protectFeature - True if #ifndef..#endif protection should be
generated around a feature interface in the header file
- genFuncPointers - True if function pointer typedefs should be
generated
- protectProto - If conditional protection should be generated
around prototype declarations, set to either '#ifdef'
to require opt-in (#ifdef protectProtoStr) or '#ifndef'
to require opt-out (#ifndef protectProtoStr). Otherwise
set to None.
- protectProtoStr - #ifdef/#ifndef symbol to use around prototype
declarations, if protectProto is set
- protectExtensionProto - If conditional protection should be generated
around extension prototype declarations, set to either '#ifdef'
to require opt-in (#ifdef protectExtensionProtoStr) or '#ifndef'
to require opt-out (#ifndef protectExtensionProtoStr). Otherwise
set to None
- protectExtensionProtoStr - #ifdef/#ifndef symbol to use around
extension prototype declarations, if protectExtensionProto is set
- apicall - string to use for the function declaration prefix,
such as APICALL on Windows
- apientry - string to use for the calling convention macro,
in typedefs, such as APIENTRY
- apientryp - string to use for the calling convention macro
in function pointer typedefs, such as APIENTRYP
- indentFuncProto - True if prototype declarations should put each
parameter on a separate line
- indentFuncPointer - True if typedefed function pointers should put each
parameter on a separate line
- alignFuncParam - if nonzero and parameters are being put on a
separate line, align parameter names at the specified column
- genEnumBeginEndRange - True if BEGIN_RANGE / END_RANGE macros should
be generated for enumerated types
- genAliasMacro - True if the OpenXR alias macro should be generated
for aliased types (unclear what other circumstances this is useful)
- genStructExtendsComment - True if comments showing the structures
whose pNext chain a structure extends are included before its
definition
- aliasMacro - alias macro to inject when genAliasMacro is True
- misracstyle - generate MISRA C-friendly headers
- misracppstyle - generate MISRA C++-friendly headers"""
separate line, align parameter names at the specified column"""
GeneratorOptions.__init__(self, **kwargs)
self.prefixText = prefixText
"""list of strings to prefix generated header with (usually a copyright statement + calling convention macros)."""
self.genFuncPointers = genFuncPointers
"""True if function pointer typedefs should be generated"""
self.protectFile = protectFile
"""True if multiple inclusion protection should be generated (based on the filename) around the entire header."""
self.protectFeature = protectFeature
"""True if #ifndef..#endif protection should be generated around a feature interface in the header file."""
self.protectProto = protectProto
"""If conditional protection should be generated around prototype declarations, set to either '#ifdef' to require opt-in (#ifdef protectProtoStr) or '#ifndef' to require opt-out (#ifndef protectProtoStr). Otherwise set to None."""
self.protectProtoStr = protectProtoStr
"""#ifdef/#ifndef symbol to use around prototype declarations, if protectProto is set"""
self.protectExtensionProto = protectExtensionProto
"""If conditional protection should be generated around extension prototype declarations, set to either '#ifdef' to require opt-in (#ifdef protectExtensionProtoStr) or '#ifndef' to require opt-out (#ifndef protectExtensionProtoStr). Otherwise set to None."""
self.protectExtensionProtoStr = protectExtensionProtoStr
"""#ifdef/#ifndef symbol to use around extension prototype declarations, if protectExtensionProto is set"""
self.apicall = apicall
"""string to use for the function declaration prefix, such as APICALL on Windows."""
self.apientry = apientry
"""string to use for the calling convention macro, in typedefs, such as APIENTRY."""
self.apientryp = apientryp
"""string to use for the calling convention macro in function pointer typedefs, such as APIENTRYP."""
self.indentFuncProto = indentFuncProto
"""True if prototype declarations should put each parameter on a separate line"""
self.indentFuncPointer = indentFuncPointer
"""True if typedefed function pointers should put each parameter on a separate line"""
self.alignFuncParam = alignFuncParam
"""if nonzero and parameters are being put on a separate line, align parameter names at the specified column"""
self.genEnumBeginEndRange = genEnumBeginEndRange
"""True if BEGIN_RANGE / END_RANGE macros should be generated for enumerated types"""
self.genAliasMacro = genAliasMacro
"""True if the OpenXR alias macro should be generated for aliased types (unclear what other circumstances this is useful)"""
self.genStructExtendsComment = genStructExtendsComment
"""True if comments showing the structures whose pNext chain a structure extends are included before its definition"""
self.aliasMacro = aliasMacro
"""alias macro to inject when genAliasMacro is True"""
self.misracstyle = misracstyle
"""generate MISRA C-friendly headers"""
self.misracppstyle = misracppstyle
"""generate MISRA C++-friendly headers"""
self.codeGenerator = True
"""True if this generator makes compilable code"""
class COutputGenerator(OutputGenerator):
"""Generates C-language API interfaces."""
@@ -168,21 +64,11 @@ class COutputGenerator(OutputGenerator):
# Internal state - accumulators for different inner block text
self.sections = {section: [] for section in self.ALL_SECTIONS}
self.feature_not_empty = False
self.may_alias = None
def beginFile(self, genOpts):
OutputGenerator.beginFile(self, genOpts)
if self.genOpts is None:
raise MissingGeneratorOptionsError()
# C-specific
#
# Multiple inclusion protection & C++ wrappers.
if self.genOpts.protectFile and self.genOpts.filename:
headerSym = re.sub(r'\.h', '_h_',
os.path.basename(self.genOpts.filename)).upper()
write('#ifndef', headerSym, file=self.outFile)
write('#define', headerSym, '1', file=self.outFile)
self.newline()
# User-supplied prefix text, if any (list of strings)
if genOpts.prefixText:
@@ -205,9 +91,6 @@ class COutputGenerator(OutputGenerator):
write('#ifdef __cplusplus', file=self.outFile)
write('}', file=self.outFile)
write('#endif', file=self.outFile)
if self.genOpts.protectFile and self.genOpts.filename:
self.newline()
write('#endif', file=self.outFile)
# Finish processing in superclass
OutputGenerator.endFile(self)
@@ -221,18 +104,6 @@ class COutputGenerator(OutputGenerator):
self.sections = {section: [] for section in self.ALL_SECTIONS}
self.feature_not_empty = False
def _endProtectComment(self, protect_str, protect_directive='#ifdef'):
if protect_directive is None or protect_str is None:
raise RuntimeError('Should not call in here without something to protect')
# Do not put comments after #endif closing blocks if this is not set
if not self.genOpts.conventions.protectProtoComment:
return ''
elif 'ifdef' in protect_directive:
return f' /* {protect_str} */'
else:
return f' /* !{protect_str} */'
def endFeature(self):
"Actually write the interface to the output file."
# C-specific
@@ -240,63 +111,24 @@ class COutputGenerator(OutputGenerator):
if self.feature_not_empty:
if self.genOpts is None:
raise MissingGeneratorOptionsError()
if self.genOpts.conventions is None:
raise MissingGeneratorOptionsConventionsError()
is_core = self.featureName and self.featureName.startswith(self.conventions.api_prefix + 'VERSION_')
if self.genOpts.conventions.writeFeature(self.featureExtraProtect, self.genOpts.filename):
self.newline()
if self.genOpts.protectFeature:
write('#ifndef', self.featureName, file=self.outFile)
is_core = self.featureName and self.featureName.startswith('VK_VERSION_')
self.newline()
# If type declarations are needed by other features based on
# this one, it may be necessary to suppress the ExtraProtect,
# or move it below the 'for section...' loop.
if self.featureExtraProtect is not None:
write('#ifdef', self.featureExtraProtect, file=self.outFile)
# Generate warning of possible use in IDEs
write(f'// {self.featureName} is a preprocessor guard. Do not pass it to API calls.', file=self.outFile)
write('#define', self.featureName, '1', file=self.outFile)
for section in self.TYPE_SECTIONS:
contents = self.sections[section]
if contents:
write('\n'.join(contents), file=self.outFile)
if self.sections['commandPointer']:
write('\n'.join(self.sections['commandPointer']), file=self.outFile)
self.newline()
# Generate warning of possible use in IDEs
write(f'// {self.featureName} is a preprocessor guard. Do not pass it to API calls.', file=self.outFile)
write('#define', self.featureName, '1', file=self.outFile)
for section in self.TYPE_SECTIONS:
contents = self.sections[section]
if contents:
write('\n'.join(contents), file=self.outFile)
if self.sections['command']:
write('\n'.join(self.sections['command']), end='', file=self.outFile)
if self.genOpts.genFuncPointers and self.sections['commandPointer']:
write('\n'.join(self.sections['commandPointer']), file=self.outFile)
self.newline()
if self.sections['command']:
if self.genOpts.protectProto:
write(self.genOpts.protectProto,
self.genOpts.protectProtoStr, file=self.outFile)
if self.genOpts.protectExtensionProto and not is_core:
write(self.genOpts.protectExtensionProto,
self.genOpts.protectExtensionProtoStr, file=self.outFile)
write('\n'.join(self.sections['command']), end='', file=self.outFile)
if self.genOpts.protectExtensionProto and not is_core:
write('#endif' +
self._endProtectComment(protect_directive=self.genOpts.protectExtensionProto,
protect_str=self.genOpts.protectExtensionProtoStr),
file=self.outFile)
if self.genOpts.protectProto:
write('#endif' +
self._endProtectComment(protect_directive=self.genOpts.protectProto,
protect_str=self.genOpts.protectProtoStr),
file=self.outFile)
else:
self.newline()
if self.featureExtraProtect is not None:
write('#endif' +
self._endProtectComment(protect_str=self.featureExtraProtect),
file=self.outFile)
if self.genOpts.protectFeature:
write('#endif' +
self._endProtectComment(protect_str=self.featureName),
file=self.outFile)
# Finish processing in superclass
OutputGenerator.endFeature(self)
@@ -304,7 +136,6 @@ class COutputGenerator(OutputGenerator):
"Append a definition to the specified section"
if section is None:
self.logMsg('error', 'Missing section in appendSection (probably a <type> element missing its \'category\' attribute. Text:', text)
exit(1)
self.sections[section].append(text)
@@ -334,22 +165,15 @@ class COutputGenerator(OutputGenerator):
else:
if self.genOpts is None:
raise MissingGeneratorOptionsError()
# OpenXR: this section was not under 'else:' previously, just fell through
if alias:
# If the type is an alias, just emit a typedef declaration
body = 'typedef ' + alias + ' ' + name + ';\n'
else:
# Replace <apientry /> tags with an APIENTRY-style string
# (from self.genOpts). Copy other text through unchanged.
# If the resulting text is an empty string, do not emit it.
body = noneStr(typeElem.text)
for elem in typeElem:
if elem.tag == 'apientry':
body += self.genOpts.apientry + noneStr(elem.tail)
else:
body += noneStr(elem.text) + noneStr(elem.tail)
if category == 'define' and self.misracppstyle():
body = body.replace("(uint32_t)", "static_cast<uint32_t>")
# Replace <apientry /> tags with an APIENTRY-style string
# (from self.genOpts). Copy other text through unchanged.
# If the resulting text is an empty string, do not emit it.
body = noneStr(typeElem.text)
for elem in typeElem:
if elem.tag == 'apientry':
body += self.genOpts.apientry + noneStr(elem.tail)
else:
body += noneStr(elem.text) + noneStr(elem.tail)
if body:
# Add extra newline after multi-line entries.
if '\n' in body[0:-1]:
@@ -380,25 +204,6 @@ class COutputGenerator(OutputGenerator):
return (protect_if_str, protect_end_str)
def typeMayAlias(self, typeName):
if not self.may_alias:
if self.registry is None:
raise MissingRegistryError()
# First time we have asked if a type may alias.
# So, populate the set of all names of types that may.
# Everyone with an explicit mayalias="true"
self.may_alias = set(typeName
for typeName, data in self.registry.typedict.items()
if data.elem.get('mayalias') == 'true')
# Every type mentioned in some other type's parentstruct attribute.
polymorphic_bases = (otherType.elem.get('parentstruct')
for otherType in self.registry.typedict.values())
self.may_alias.update(set(x for x in polymorphic_bases
if x is not None))
return typeName in self.may_alias
def genStruct(self, typeinfo, typeName, alias):
"""Generate struct (e.g. C "struct" type).
@@ -426,18 +231,8 @@ class COutputGenerator(OutputGenerator):
if protect_begin:
body += protect_begin
if self.genOpts.genStructExtendsComment:
structextends = typeElem.get('structextends')
body += '// ' + typeName + ' extends ' + structextends + '\n' if structextends else ''
body += 'typedef ' + typeElem.get('category')
# This is an OpenXR-specific alternative where aliasing refers
# to an inheritance hierarchy of types rather than C-level type
# aliases.
if self.genOpts.genAliasMacro and self.typeMayAlias(typeName):
body += ' ' + self.genOpts.aliasMacro
body += ' ' + typeName + ' {\n'
targetLen = self.getMaxCParamTypeLength(typeinfo)
@@ -472,11 +267,6 @@ class COutputGenerator(OutputGenerator):
# for the alias.
body = 'typedef ' + alias + ' ' + groupName + ';\n'
self.appendSection(section, body)
else:
if self.genOpts is None:
raise MissingGeneratorOptionsError()
(section, body) = self.buildEnumCDecl(self.genOpts.genEnumBeginEndRange, groupinfo, groupName)
self.appendSection(section, '\n' + body)
def genEnum(self, enuminfo, name, alias):
"""Generate the C declaration for a constant (a single <enum> value).
@@ -493,21 +283,10 @@ class COutputGenerator(OutputGenerator):
"Command generation"
OutputGenerator.genCmd(self, cmdinfo, name, alias)
# if alias:
# prefix = '// ' + name + ' is an alias of command ' + alias + '\n'
# else:
# prefix = ''
if self.genOpts is None:
raise MissingGeneratorOptionsError()
prefix = ''
decls = self.makeCDecls(cmdinfo.elem)
self.appendSection('command', prefix + decls[0] + '\n')
if self.genOpts.genFuncPointers:
self.appendSection('commandPointer', decls[1])
def misracstyle(self):
return self.genOpts.misracstyle;
def misracppstyle(self):
return self.genOpts.misracppstyle;
self.appendSection('commandPointer', decls[1])

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,14 @@
#!/usr/bin/python3
#
# Copyright 2013-2023 The Khronos Group Inc.
# Copyright 2023-2024 Google Inc.
#
# SPDX-License-Identifier: Apache-2.0
import argparse
import os
import pdb
import re
import sys
import copy
import time
import xml.etree.ElementTree as etree
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
@@ -19,28 +17,12 @@ from cgenerator import CGeneratorOptions, COutputGenerator
from generator import write
from reg import Registry
from apiconventions import APIConventions
# gfxstream + cereal modules
from cerealgenerator import CerealGenerator
# Simple timer functions
startTime = None
from typing import Optional
def startTimer(timeit):
global startTime
if timeit:
startTime = time.process_time()
def endTimer(timeit, msg):
global startTime
if timeit and startTime is not None:
endTime = time.process_time()
startTime = None
def makeREstring(strings, default=None, strings_are_regex=False):
"""Turn a list of strings into a regexp string matching exactly those strings."""
if strings or default is None:
@@ -59,53 +41,17 @@ def makeGenOpts(args):
global genOpts
genOpts = {}
# Default class of extensions to include, or None
defaultExtensions = args.defaultExtensions
# Additional extensions to include (list of extensions)
extensions = args.extension
# Extensions to remove (list of extensions)
removeExtensions = args.removeExtensions
# Extensions to emit (list of extensions)
emitExtensions = args.emitExtensions
# SPIR-V capabilities / features to emit (list of extensions & capabilities)
emitSpirv = args.emitSpirv
# Vulkan Formats to emit
emitFormats = args.emitFormats
# Features to include (list of features)
features = args.feature
# Whether to disable inclusion protect in headers
protect = args.protect
# Output target directory
directory = args.directory
# Path to generated files, particularly apimap.py
genpath = args.genpath
# Generate MISRA C-friendly headers
misracstyle = args.misracstyle;
# Generate MISRA C++-friendly headers
misracppstyle = args.misracppstyle;
# Descriptive names for various regexp patterns used to select
# versions and extensions
allFormats = allSpirv = allFeatures = allExtensions = r'.*'
allFormats = allFeatures = allExtensions = r'.*'
# Turn lists of names/patterns into matching regular expressions
addExtensionsPat = makeREstring(extensions, None)
removeExtensionsPat = makeREstring(removeExtensions, None)
emitExtensionsPat = makeREstring(emitExtensions, allExtensions)
emitSpirvPat = makeREstring(emitSpirv, allSpirv)
emitFormatsPat = makeREstring(emitFormats, allFormats)
featuresPat = makeREstring(features, allFeatures)
emitExtensionsPat = makeREstring([], allExtensions)
emitFormatsPat = makeREstring([], allFormats)
featuresPat = makeREstring([], allFeatures)
# Copyright text prefixing all headers (list of strings).
# The SPDX formatting below works around constraints of the 'reuse' tool
@@ -127,200 +73,15 @@ def makeGenOpts(args):
''
]
vulkanLayer = args.vulkanLayer
# Defaults for generating re-inclusion protection wrappers (or not)
protectFile = protect
# An API style conventions object
conventions = APIConventions()
if args.apiname is not None:
defaultAPIName = args.apiname
else:
defaultAPIName = conventions.xml_api_name
# APIs to merge
mergeApiNames = args.mergeApiNames
isCTS = args.isCTS
# Platform extensions, in their own header files
# Each element of the platforms[] array defines information for
# generating a single platform:
# [0] is the generated header file name
# [1] is the set of platform extensions to generate
# [2] is additional extensions whose interfaces should be considered,
# but suppressed in the output, to avoid duplicate definitions of
# dependent types like VkDisplayKHR and VkSurfaceKHR which come from
# non-platform extensions.
# Track all platform extensions, for exclusion from vulkan_core.h
allPlatformExtensions = []
# Extensions suppressed for all WSI platforms (WSI extensions required
# by all platforms)
commonSuppressExtensions = [ 'VK_KHR_display', 'VK_KHR_swapchain' ]
# Extensions required and suppressed for beta "platform". This can
# probably eventually be derived from the requires= attributes of
# the extension blocks.
betaRequireExtensions = [
'VK_KHR_portability_subset',
'VK_KHR_video_encode_queue',
'VK_EXT_video_encode_h264',
'VK_EXT_video_encode_h265',
'VK_NV_displacement_micromap',
'VK_AMDX_shader_enqueue',
]
betaSuppressExtensions = [
'VK_KHR_video_queue',
'VK_EXT_opacity_micromap',
'VK_KHR_pipeline_library',
]
platforms = [
[ 'vulkan_android.h', [ 'VK_KHR_android_surface',
'VK_ANDROID_external_memory_android_hardware_buffer',
'VK_ANDROID_external_format_resolve'
], commonSuppressExtensions +
[ 'VK_KHR_format_feature_flags2',
] ],
[ 'vulkan_fuchsia.h', [ 'VK_FUCHSIA_imagepipe_surface',
'VK_FUCHSIA_external_memory',
'VK_FUCHSIA_external_semaphore',
'VK_FUCHSIA_buffer_collection' ], commonSuppressExtensions ],
[ 'vulkan_ggp.h', [ 'VK_GGP_stream_descriptor_surface',
'VK_GGP_frame_token' ], commonSuppressExtensions ],
[ 'vulkan_ios.h', [ 'VK_MVK_ios_surface' ], commonSuppressExtensions ],
[ 'vulkan_macos.h', [ 'VK_MVK_macos_surface' ], commonSuppressExtensions ],
[ 'vulkan_vi.h', [ 'VK_NN_vi_surface' ], commonSuppressExtensions ],
[ 'vulkan_wayland.h', [ 'VK_KHR_wayland_surface' ], commonSuppressExtensions ],
[ 'vulkan_win32.h', [ 'VK_.*_win32(|_.*)', 'VK_.*_winrt(|_.*)', 'VK_EXT_full_screen_exclusive' ],
commonSuppressExtensions +
[ 'VK_KHR_external_semaphore',
'VK_KHR_external_memory_capabilities',
'VK_KHR_external_fence',
'VK_KHR_external_fence_capabilities',
'VK_KHR_get_surface_capabilities2',
'VK_NV_external_memory_capabilities',
] ],
[ 'vulkan_xcb.h', [ 'VK_KHR_xcb_surface' ], commonSuppressExtensions ],
[ 'vulkan_xlib.h', [ 'VK_KHR_xlib_surface' ], commonSuppressExtensions ],
[ 'vulkan_directfb.h', [ 'VK_EXT_directfb_surface' ], commonSuppressExtensions ],
[ 'vulkan_xlib_xrandr.h', [ 'VK_EXT_acquire_xlib_display' ], commonSuppressExtensions ],
[ 'vulkan_metal.h', [ 'VK_EXT_metal_surface',
'VK_EXT_metal_objects' ], commonSuppressExtensions ],
[ 'vulkan_screen.h', [ 'VK_QNX_screen_surface',
'VK_QNX_external_memory_screen_buffer' ], commonSuppressExtensions ],
[ 'vulkan_sci.h', [ 'VK_NV_external_sci_sync',
'VK_NV_external_sci_sync2',
'VK_NV_external_memory_sci_buf'], commonSuppressExtensions ],
[ 'vulkan_beta.h', betaRequireExtensions, betaSuppressExtensions ],
]
for platform in platforms:
headername = platform[0]
allPlatformExtensions += platform[1]
addPlatformExtensionsRE = makeREstring(
platform[1] + platform[2], strings_are_regex=True)
emitPlatformExtensionsRE = makeREstring(
platform[1], strings_are_regex=True)
opts = CGeneratorOptions(
conventions = conventions,
filename = headername,
directory = directory,
genpath = None,
apiname = defaultAPIName,
mergeApiNames = mergeApiNames,
profile = None,
versions = featuresPat,
emitversions = None,
defaultExtensions = None,
addExtensions = addPlatformExtensionsRE,
removeExtensions = None,
emitExtensions = emitPlatformExtensionsRE,
prefixText = prefixStrings + vkPrefixStrings,
genFuncPointers = True,
protectFile = protectFile,
protectFeature = False,
protectProto = '#ifndef',
protectProtoStr = 'VK_NO_PROTOTYPES',
apicall = 'VKAPI_ATTR ',
apientry = 'VKAPI_CALL ',
apientryp = 'VKAPI_PTR *',
alignFuncParam = 48,
misracstyle = misracstyle,
misracppstyle = misracppstyle)
genOpts[headername] = [ COutputGenerator, opts ]
# Header for core API + extensions.
# To generate just the core API,
# change to 'defaultExtensions = None' below.
#
# By default this adds all enabled, non-platform extensions.
# It removes all platform extensions (from the platform headers options
# constructed above) as well as any explicitly specified removals.
removeExtensionsPat = makeREstring(
allPlatformExtensions + removeExtensions, None, strings_are_regex=True)
genOpts['vulkan_core.h'] = [
COutputGenerator,
CGeneratorOptions(
conventions = conventions,
filename = 'vulkan_core.h',
directory = directory,
genpath = None,
apiname = defaultAPIName,
mergeApiNames = mergeApiNames,
profile = None,
versions = featuresPat,
emitversions = featuresPat,
defaultExtensions = defaultExtensions,
addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat,
prefixText = prefixStrings + vkPrefixStrings,
genFuncPointers = True,
protectFile = protectFile,
protectFeature = False,
protectProto = '#ifndef',
protectProtoStr = 'VK_NO_PROTOTYPES',
apicall = 'VKAPI_ATTR ',
apientry = 'VKAPI_CALL ',
apientryp = 'VKAPI_PTR *',
alignFuncParam = 48,
misracstyle = misracstyle,
misracppstyle = misracppstyle)
]
# Serializer for spec
genOpts['cereal'] = [
CerealGenerator,
CGeneratorOptions(
conventions = conventions,
directory = directory,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
emitversions = featuresPat,
defaultExtensions = defaultExtensions,
addExtensions = None,
removeExtensions = None,
emitExtensions = emitExtensionsPat,
prefixText = prefixStrings + vkPrefixStrings,
genFuncPointers = True,
protectFile = protectFile,
protectFeature = False,
protectProto = '#ifndef',
protectProtoStr = 'VK_NO_PROTOTYPES',
apicall = 'VKAPI_ATTR ',
apientry = 'VKAPI_CALL ',
apientryp = 'VKAPI_PTR *',
alignFuncParam = 48)
@@ -337,32 +98,18 @@ def makeGenOpts(args):
genOpts['vulkan_gfxstream.h'] = [
COutputGenerator,
CGeneratorOptions(
conventions = conventions,
filename = 'vulkan_gfxstream.h',
directory = directory,
genpath = None,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
emitversions = None,
defaultExtensions = None,
addExtensions = makeREstring(['VK_GOOGLE_gfxstream'], None),
removeExtensions = None,
emitExtensions = makeREstring(['VK_GOOGLE_gfxstream'], None),
prefixText = prefixStrings + vkPrefixStrings + gfxstreamPrefixStrings,
genFuncPointers = True,
# Use #pragma once in the prefixText instead, so that we can put the copyright comments
# at the beginning of the file.
protectFile = False,
protectFeature = False,
protectProto = '#ifndef',
protectProtoStr = 'VK_NO_PROTOTYPES',
apicall = 'VKAPI_ATTR ',
apientry = 'VKAPI_CALL ',
apientryp = 'VKAPI_PTR *',
alignFuncParam = 48,
misracstyle = misracstyle,
misracppstyle = misracppstyle)
alignFuncParam = 48)
]
def genTarget(args):
@@ -375,7 +122,6 @@ def genTarget(args):
- target - target to generate
- directory - directory to generate it in
- protect - True if re-inclusion wrappers should be created
- extensions - list of additional extensions to include in generated interfaces"""
# Create generator options with parameters specified on command line
@@ -400,92 +146,22 @@ def genTarget(args):
# of names, or a regular expression.
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-apiname', action='store',
default=None,
help='Specify API to generate (defaults to repository-specific conventions object value)')
parser.add_argument('-mergeApiNames', action='store',
default=None,
help='Specify a comma separated list of APIs to merge into the target API')
parser.add_argument('-defaultExtensions', action='store',
default=APIConventions().xml_api_name,
help='Specify a single class of extensions to add to targets')
parser.add_argument('-extension', action='append',
default=[],
help='Specify an extension or extensions to add to targets')
parser.add_argument('-removeExtensions', action='append',
default=[],
help='Specify an extension or extensions to remove from targets')
parser.add_argument('-emitExtensions', action='append',
default=[],
help='Specify an extension or extensions to emit in targets')
parser.add_argument('-emitSpirv', action='append',
default=[],
help='Specify a SPIR-V extension or capability to emit in targets')
parser.add_argument('-emitFormats', action='append',
default=[],
help='Specify Vulkan Formats to emit in targets')
parser.add_argument('-feature', action='append',
default=[],
help='Specify a core API feature name or names to add to targets')
parser.add_argument('-debug', action='store_true',
help='Enable debugging')
parser.add_argument('-dump', action='store_true',
help='Enable dump to stderr')
parser.add_argument('-diagfile', action='store',
default=None,
help='Write diagnostics to specified file')
parser.add_argument('-errfile', action='store',
default=None,
help='Write errors and warnings to specified file instead of stderr')
parser.add_argument('-noprotect', dest='protect', action='store_false',
help='Disable inclusion protection in output headers')
parser.add_argument('-profile', action='store_true',
help='Enable profiling')
parser.add_argument('-registry', action='store',
default='vk.xml',
help='Use specified registry file instead of vk.xml')
parser.add_argument('-registryGfxstream', action='store',
default=None,
help='Use specified gfxstream registry file')
parser.add_argument('-time', action='store_true',
help='Enable timing')
parser.add_argument('-genpath', action='store', default='gen',
help='Path to generated files')
parser.add_argument('-o', action='store', dest='directory',
default='.',
help='Create target and related files in specified directory')
parser.add_argument('target', metavar='target', nargs='?',
help='Specify target')
parser.add_argument('-quiet', action='store_true', default=True,
help='Suppress script output during normal execution.')
parser.add_argument('-verbose', action='store_false', dest='quiet', default=True,
help='Enable script output during normal execution.')
parser.add_argument('--vulkanLayer', action='store_true', dest='vulkanLayer',
help='Enable scripts to generate VK specific vulkan_json_data.hpp for json_gen_layer.')
parser.add_argument('-misracstyle', dest='misracstyle', action='store_true',
help='generate MISRA C-friendly headers')
parser.add_argument('-misracppstyle', dest='misracppstyle', action='store_true',
help='generate MISRA C++-friendly headers')
parser.add_argument('--iscts', action='store_true', dest='isCTS',
help='Specify if this should generate CTS compatible code')
args = parser.parse_args()
# This splits arguments which are space-separated lists
args.feature = [name for arg in args.feature for name in arg.split()]
args.extension = [name for arg in args.extension for name in arg.split()]
# create error/warning & diagnostic files
if args.errfile:
errWarn = open(args.errfile, 'w', encoding='utf-8')
else:
errWarn = sys.stderr
if args.diagfile:
diag = open(args.diagfile, 'w', encoding='utf-8')
else:
diag = None
errWarn = sys.stderr
diag = None
# Create the API generator & generator options
(gen, options) = genTarget(args)
@@ -495,9 +171,7 @@ if __name__ == '__main__':
reg = Registry(gen, options)
# Parse the specified registry XML into an ElementTree object
startTimer(args.time)
tree = etree.parse(args.registry)
endTimer(args.time, '* Time to make ElementTree =')
# Merge the gfxstream registry with the official Vulkan registry if the
# target is the cereal generator
@@ -530,7 +204,6 @@ if __name__ == '__main__':
if name not in originalEntryDict.keys():
treeEntries.append(entry)
continue
print(f'Entry {entriesName}:{name}')
originalEntry = originalEntryDict[name]
@@ -553,17 +226,5 @@ if __name__ == '__main__':
originalEntry.append(child)
# Load the XML tree into the registry object
startTimer(args.time)
reg.loadElementTree(tree)
endTimer(args.time, '* Time to parse ElementTree =')
if args.dump:
reg.dumpReg(filehandle=open('regdump.txt', 'w', encoding='utf-8'))
# Finally, use the output generator to create the requested target
if args.debug:
pdb.run('reg.apiGen()')
else:
startTimer(args.time)
reg.apiGen()
endTimer(args.time, '* Time to generate ' + args.target + ' =')
reg.apiGen()

File diff suppressed because it is too large Load Diff