early-access version 2729

This commit is contained in:
pineappleEA
2022-05-17 21:04:11 +02:00
parent dab6a0fe35
commit c7aa528a40
49 changed files with 98614 additions and 79650 deletions

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python3 -i
#
# Copyright 2021 The Khronos Group Inc.
# Copyright 2021-2022 The Khronos Group Inc.
# SPDX-License-Identifier: Apache-2.0
# Generic alias for working group-specific API conventions interface.

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python3 -i
#
# Copyright 2013-2021 The Khronos Group Inc.
# Copyright 2013-2022 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0
@@ -234,7 +234,11 @@ class COutputGenerator(OutputGenerator):
def appendSection(self, section, text):
"Append a definition to the specified section"
# self.sections[section].append('SECTION: ' + section + '\n')
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)
self.feature_not_empty = True

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python3 -i
#
# Copyright 2013-2021 The Khronos Group Inc.
# Copyright 2013-2022 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python3 -i
#
# Copyright 2013-2021 The Khronos Group Inc.
# Copyright 2013-2022 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0
"""Base class for source/header/doc generators, as well as some utility functions."""
@@ -55,10 +55,13 @@ def regSortCategoryKey(feature):
Sorts by category of the feature name string:
- Core API features (those defined with a `<feature>` tag)
- (sort VKSC after VK)
- ARB/KHR/OES (Khronos extensions)
- other (EXT/vendor extensions)"""
if feature.elem.tag == 'feature':
if feature.name.startswith('VKSC'):
return 0.5
return 0
if (feature.category == 'ARB'
or feature.category == 'KHR'
@@ -580,7 +583,10 @@ class OutputGenerator:
# Work around this by chasing the aliases to get the actual value.
while numVal is None:
alias = self.registry.tree.find("enums/enum[@name='" + strVal + "']")
(numVal, strVal) = self.enumToValue(alias, True, bitwidth, True)
if alias is not None:
(numVal, strVal) = self.enumToValue(alias, True, bitwidth, True)
else:
self.logMsg('error', 'No such alias {} for enum {}'.format(strVal, name))
decl += "static const {} {} = {};\n".format(flagTypeName, name, strVal)
if numVal is not None:
@@ -1063,7 +1069,8 @@ class OutputGenerator:
return False
info = self.registry.typedict.get(structname)
assert(info is not None)
if info is None:
self.logMsg('error', f'isStructAlwaysValid({structname}) - structure not found in typedict')
members = info.getMembers()

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python3
#
# Copyright 2013-2021 The Khronos Group Inc.
# Copyright 2013-2022 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0
@@ -22,7 +22,7 @@ from hostsyncgenerator import HostSynchronizationOutputGenerator
from formatsgenerator import FormatsOutputGenerator
from pygenerator import PyOutputGenerator
from rubygenerator import RubyOutputGenerator
from reflib import logDiag, logWarn, setLogFile
from reflib import logDiag, logWarn, logErr, setLogFile
from reg import Registry
from validitygenerator import ValidityOutputGenerator
from apiconventions import APIConventions
@@ -116,7 +116,7 @@ def makeGenOpts(args):
# The SPDX formatting below works around constraints of the 'reuse' tool
prefixStrings = [
'/*',
'** Copyright 2015-2021 The Khronos Group Inc.',
'** Copyright 2015-2022 The Khronos Group Inc.',
'**',
'** SPDX' + '-License-Identifier: Apache-2.0',
'*/',
@@ -511,6 +511,83 @@ def makeGenOpts(args):
misracppstyle = misracppstyle)
]
# Video header target - combines all video extension dependencies into a
# single header, at present.
genOpts['vk_video.h'] = [
COutputGenerator,
CGeneratorOptions(
conventions = conventions,
filename = 'vk_video.h',
directory = directory,
genpath = None,
apiname = 'vulkan',
profile = None,
versions = None,
emitversions = None,
defaultExtensions = defaultExtensions,
addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat,
prefixText = prefixStrings + vkPrefixStrings,
genFuncPointers = True,
protectFile = protectFile,
protectFeature = False,
protectProto = '#ifndef',
protectProtoStr = 'VK_NO_PROTOTYPES',
apicall = '',
apientry = '',
apientryp = '',
alignFuncParam = 48,
misracstyle = misracstyle,
misracppstyle = misracppstyle)
]
# Video extension 'Std' interfaces, each in its own header files
# These are not Vulkan extensions, or a part of the Vulkan API at all,
# but are treated in a similar fashion for generation purposes.
#
# Each element of the videoStd[] array is an 'extension' name defining
# an iterface, and is also the basis for the generated header file name.
videoStd = [
'vulkan_video_codecs_common',
'vulkan_video_codec_h264std',
'vulkan_video_codec_h264std_decode',
'vulkan_video_codec_h264std_encode',
'vulkan_video_codec_h265std',
'vulkan_video_codec_h265std_decode',
'vulkan_video_codec_h265std_encode',
]
addExtensionRE = makeREstring(videoStd)
for codec in videoStd:
headername = f'{codec}.h'
# Consider all of the codecs 'extensions', but only emit this one
emitExtensionRE = makeREstring([codec])
opts = CGeneratorOptions(
conventions = conventions,
filename = headername,
directory = directory,
genpath = None,
apiname = defaultAPIName,
profile = None,
versions = None,
emitversions = None,
defaultExtensions = None,
addExtensions = addExtensionRE,
removeExtensions = None,
emitExtensions = emitExtensionRE,
prefixText = prefixStrings + vkPrefixStrings,
genFuncPointers = False,
protectFile = protectFile,
protectFeature = False,
alignFuncParam = 48,
)
genOpts[headername] = [ COutputGenerator, opts ]
# Unused - vulkan11.h target.
# It is possible to generate a header with just the Vulkan 1.0 +
# extension interfaces defined, but since the promoted KHR extensions

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python3 -i
#
# Copyright 2013-2021 The Khronos Group Inc.
# Copyright 2013-2022 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0
@@ -104,13 +104,14 @@ def stripNonmatchingAPIs(tree, apiName, actuallyDelete = True):
for child in parent.findall('*'):
api = child.get('api')
if api:
if not apiNameMatch(apiName, api):
if actuallyDelete:
parent.remove(child)
else:
if apiNameMatch(apiName, api):
# Add child to the queue
stack.append(child)
elif not apiNameMatch(apiName, api):
# Child does not match requested api. Remove it.
if actuallyDelete:
parent.remove(child)
class BaseInfo:
@@ -294,8 +295,10 @@ class SpirvInfo(BaseInfo):
class FormatInfo(BaseInfo):
"""Registry information about an API <format>."""
def __init__(self, elem):
def __init__(self, elem, condition):
BaseInfo.__init__(self, elem)
# Need to save the condition here when it is known
self.condition = condition
class Registry:
"""Object representing an API registry, loaded from an XML file."""
@@ -399,26 +402,19 @@ class Registry:
Intended for internal use only.
- elem - `<type>`/`<enums>`/`<enum>`/`<command>`/`<feature>`/`<extension>`/`<spirvextension>`/`<spirvcapability>`/`<format>` Element
- info - corresponding {Type|Group|Enum|Cmd|Feature|Spirv}Info object
- info - corresponding {Type|Group|Enum|Cmd|Feature|Spirv|Format}Info object
- infoName - 'type' / 'group' / 'enum' / 'command' / 'feature' / 'extension' / 'spirvextension' / 'spirvcapability' / 'format'
- dictionary - self.{type|group|enum|cmd|api|ext|format|spirvext|spirvcap}dict
If the Element has an 'api' attribute, the dictionary key is the
tuple (name,api). If not, the key is the name. 'name' is an
attribute of the Element"""
The dictionary key is the element 'name' attribute."""
# self.gen.logMsg('diag', 'Adding ElementInfo.required =',
# info.required, 'name =', elem.get('name'))
api = elem.get('api')
if api:
key = (elem.get('name'), api)
else:
key = elem.get('name')
key = elem.get('name')
if key in dictionary:
if not dictionary[key].compareElem(info, infoName):
self.gen.logMsg('warn', 'Attempt to redefine', key,
'(this should not happen)')
else:
True
else:
dictionary[key] = info
@@ -459,7 +455,7 @@ class Registry:
# overlapping api attributes, or where one element has an api
# attribute and the other does not.
stripNonmatchingAPIs(self.reg, self.genOpts.apiname)
stripNonmatchingAPIs(self.reg, self.genOpts.apiname, actuallyDelete = True)
# Create dictionary of registry types from toplevel <types> tags
# and add 'name' attribute to each <type> tag (where missing)
@@ -547,6 +543,7 @@ class Registry:
# Create dictionaries of API and extension interfaces
# from toplevel <api> and <extension> tags.
self.apidict = {}
format_condition = dict()
for feature in self.reg.findall('feature'):
featureInfo = FeatureInfo(feature)
self.addElementInfo(feature, featureInfo, 'feature', self.apidict)
@@ -583,6 +580,11 @@ class Registry:
else:
self.gen.logMsg('warn', 'NO matching group',
groupName, 'for enum', enum.get('name'), 'found.')
if groupName == "VkFormat":
format_name = enum.get('name')
if enum.get('alias'):
format_name = enum.get('alias')
format_condition[format_name] = featureInfo.name
addEnumInfo = True
elif enum.get('value') or enum.get('bitpos') or enum.get('alias'):
# self.gen.logMsg('diag', 'Adding extension constant "enum"',
@@ -630,6 +632,14 @@ class Registry:
else:
self.gen.logMsg('warn', 'NO matching group',
groupName, 'for enum', enum.get('name'), 'found.')
if groupName == "VkFormat":
format_name = enum.get('name')
if enum.get('alias'):
format_name = enum.get('alias')
if format_name in format_condition:
format_condition[format_name] += "," + featureInfo.name
else:
format_condition[format_name] = featureInfo.name
addEnumInfo = True
elif enum.get('value') or enum.get('bitpos') or enum.get('alias'):
# self.gen.logMsg('diag', 'Adding extension constant "enum"',
@@ -666,7 +676,11 @@ class Registry:
self.addElementInfo(spirv, spirvInfo, 'spirvcapability', self.spirvcapdict)
for format in self.reg.findall('formats/format'):
formatInfo = FormatInfo(format)
condition = None
format_name = format.get('name')
if format_name in format_condition:
condition = format_condition[format_name]
formatInfo = FormatInfo(format, condition)
self.addElementInfo(format, formatInfo, 'format', self.formatsdict)
def dumpReg(self, maxlen=120, filehandle=sys.stdout):
@@ -720,6 +734,7 @@ class Registry:
- required - boolean (to tag features as required or not)
"""
self.gen.logMsg('diag', 'tagging type:', typename, '-> required =', required)
# Get TypeInfo object for <type> tag corresponding to typename
typeinfo = self.lookupElementInfo(typename, self.typedict)
if typeinfo is not None:
@@ -774,20 +789,18 @@ class Registry:
- enumname - name of enum
- required - boolean (to tag features as required or not)"""
self.gen.logMsg('diag', 'tagging enum:', enumname, '-> required =', required)
self.gen.logMsg('diag', 'markEnumRequired: tagging enum:', enumname, '-> required =', required)
enum = self.lookupElementInfo(enumname, self.enumdict)
if enum is not None:
# If the enum is part of a group, and is being removed, then
# look it up in that <group> tag and remove it there, so that it
# is not visible to generators (which traverse the <group> tag
# elements themselves).
# This is not the most robust way of doing this, since a removed
# enum that is later required again will no longer have a group
# element, but it makes the change non-intrusive on generator
# code.
if required is False:
# look it up in that <enums> tag and remove the Element there,
# so that it is not visible to generators (which traverse the
# <enums> tag elements rather than using the dictionaries).
if not required:
groupName = enum.elem.get('extends')
if groupName is not None:
self.gen.logMsg('diag', f'markEnumRequired: Removing extending enum {enum.elem.get("name")}')
# Look up the Info with matching groupName
if groupName in self.groupdict:
gi = self.groupdict[groupName]
@@ -796,23 +809,42 @@ class Registry:
# Remove copy of this enum from the group
gi.elem.remove(gienum)
else:
self.gen.logMsg('warn', 'Cannot remove enum',
self.gen.logMsg('warn', 'markEnumRequired: Cannot remove enum',
enumname, 'not found in group',
groupName)
else:
self.gen.logMsg('warn', 'Cannot remove enum',
self.gen.logMsg('warn', 'markEnumRequired: Cannot remove enum',
enumname, 'from nonexistent group',
groupName)
else:
# This enum is not an extending enum.
# The XML tree must be searched for all <enums> that
# might have it, so we know the parent to delete from.
enumName = enum.elem.get('name')
self.gen.logMsg('diag', f'markEnumRequired: Removing non-extending enum {enumName}')
count = 0
for enums in self.reg.findall('enums'):
for thisEnum in enums.findall('enum'):
if thisEnum.get('name') == enumName:
# Actually remove it
count = count + 1
enums.remove(thisEnum)
if count == 0:
self.gen.logMsg('warn', f'markEnumRequired: {enumName}) not found in any <enums> tag')
enum.required = required
# Tag enum dependencies in 'alias' attribute as required
depname = enum.elem.get('alias')
if depname:
self.gen.logMsg('diag', 'Generating dependent enum',
self.gen.logMsg('diag', 'markEnumRequired: Generating dependent enum',
depname, 'for alias', enumname, 'required =', enum.required)
self.markEnumRequired(depname, required)
else:
self.gen.logMsg('warn', 'enum:', enumname, 'IS NOT DEFINED')
self.gen.logMsg('warn', f'markEnumRequired: {enumname} IS NOT DEFINED')
def markCmdRequired(self, cmdname, required):
"""Mark a command as required or not.
@@ -869,6 +901,7 @@ class Registry:
self.markTypeRequired(typeElem.get('name'), required)
for enumElem in feature.findall('enum'):
self.markEnumRequired(enumElem.get('name'), required)
for cmdElem in feature.findall('command'):
self.markCmdRequired(cmdElem.get('name'), required)
@@ -1009,11 +1042,11 @@ class Registry:
else:
self.gen.logMsg('warn', 'fillFeatureDictionary: NOT filling for {}'.format(typename))
def requireAndRemoveFeatures(self, interface, featurename, api, profile):
"""Process `<require>` and `<remove>` tags for a `<version>` or `<extension>`.
def requireFeatures(self, interface, featurename, api, profile):
"""Process `<require>` tags for a `<version>` or `<extension>`.
- interface - Element for `<version>` or `<extension>`, containing
`<require>` and `<remove>` tags
`<require>` tags
- featurename - name of the feature
- api - string specifying API name being generated
- profile - string specifying API profile being generated"""
@@ -1023,6 +1056,15 @@ class Registry:
if matchAPIProfile(api, profile, feature):
self.markRequired(featurename, feature, True)
def removeFeatures(self, interface, featurename, api, profile):
"""Process `<remove>` tags for a `<version>` or `<extension>`.
- interface - Element for `<version>` or `<extension>`, containing
`<remove>` tags
- featurename - name of the feature
- api - string specifying API name being generated
- profile - string specifying API profile being generated"""
# <remove> marks things that are removed by this version/profile
for feature in interface.findall('remove'):
if matchAPIProfile(api, profile, feature):
@@ -1038,6 +1080,7 @@ class Registry:
if v.get('struct'):
self.typedict[v.get('struct')].additionalValidity.append(copy.deepcopy(v))
def removeAdditionalValidity(self, interface, api, profile):
# Loop over all usage inside all <remove> tags.
for feature in interface.findall('remove'):
if matchAPIProfile(api, profile, feature):
@@ -1165,7 +1208,8 @@ class Registry:
if extname is not None:
# 'supported' attribute was injected when the <enum> element was
# moved into the <enums> group in Registry.parseTree()
if self.genOpts.defaultExtensions == elem.get('supported'):
supported_list = elem.get('supported').split(",")
if self.genOpts.defaultExtensions in supported_list:
required = True
elif re.match(self.genOpts.addExtensions, extname) is not None:
required = True
@@ -1353,7 +1397,7 @@ class Registry:
# Get all matching extensions, in order by their extension number,
# and add to the list of features.
# Start with extensions tagged with 'api' pattern matching the API
# Start with extensions whose 'supported' attributes match the API
# being generated. Add extensions matching the pattern specified in
# regExtensions, then remove extensions matching the pattern
# specified in regRemoveExtensions
@@ -1435,22 +1479,25 @@ class Registry:
self.genOpts.sortProcedure(features)
# print('sortProcedure ->', [f.name for f in features])
# Pass 1: loop over requested API versions and extensions tagging
# Passes 1+2: loop over requested API versions and extensions tagging
# types/commands/features as required (in an <require> block) or no
# longer required (in an <remove> block). It is possible to remove
# a feature in one version and restore it later by requiring it in
# a later version.
# longer required (in an <remove> block). <remove>s are processed
# after all <require>s, so removals win.
# If a profile other than 'None' is being generated, it must
# match the profile attribute (if any) of the <require> and
# <remove> tags.
self.gen.logMsg('diag', 'PASS 1: TAG FEATURES')
for f in features:
self.gen.logMsg('diag', 'PASS 1: Tagging required and removed features for',
f.name)
self.gen.logMsg('diag', 'PASS 1: Tagging required and features for', f.name)
self.fillFeatureDictionary(f.elem, f.name, self.genOpts.apiname, self.genOpts.profile)
self.requireAndRemoveFeatures(f.elem, f.name, self.genOpts.apiname, self.genOpts.profile)
self.requireFeatures(f.elem, f.name, self.genOpts.apiname, self.genOpts.profile)
self.assignAdditionalValidity(f.elem, self.genOpts.apiname, self.genOpts.profile)
for f in features:
self.gen.logMsg('diag', 'PASS 2: Tagging removed features for', f.name)
self.removeFeatures(f.elem, f.name, self.genOpts.apiname, self.genOpts.profile)
self.removeAdditionalValidity(f.elem, self.genOpts.apiname, self.genOpts.profile)
# Now, strip references to APIs that are not required.
# At present such references may occur in:
# Structs in <type category="struct"> 'structextends' attributes
@@ -1466,17 +1513,17 @@ class Registry:
# <enable extension="VK_KHR_shader_draw_parameters"/>
# <enable property="VkPhysicalDeviceVulkan12Properties" member="shaderDenormPreserveFloat16" value="VK_TRUE" requires="VK_VERSION_1_2,VK_KHR_shader_float_controls"/>
# Pass 2: loop over specified API versions and extensions printing
# Pass 3: loop over specified API versions and extensions printing
# declarations for required things which have not already been
# generated.
self.gen.logMsg('diag', 'PASS 2: GENERATE INTERFACES FOR FEATURES')
self.gen.logMsg('diag', 'PASS 3: GENERATE INTERFACES FOR FEATURES')
self.gen.beginFile(self.genOpts)
for f in features:
self.gen.logMsg('diag', 'PASS 2: Generating interface for',
self.gen.logMsg('diag', 'PASS 3: Generating interface for',
f.name)
emit = self.emitFeatures = f.emit
if not emit:
self.gen.logMsg('diag', 'PASS 2: NOT declaring feature',
self.gen.logMsg('diag', 'PASS 3: NOT declaring feature',
f.elem.get('name'), 'because it is not tagged for emission')
# Generate the interface (or just tag its elements as having been
# emitted, if they have not been).

View File

@@ -1,6 +1,6 @@
"""Utility functions not closely tied to other spec_tools types."""
# Copyright 2018-2019 Collabora, Ltd.
# Copyright 2013-2021 The Khronos Group Inc.
# Copyright 2013-2022 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0

File diff suppressed because one or more lines are too long

1111
externals/Vulkan-Headers/registry/video.xml vendored Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python3 -i
#
# Copyright 2013-2021 The Khronos Group Inc.
# Copyright 2013-2022 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0
@@ -22,6 +22,8 @@ CATEGORIES_REQUIRING_VALIDATION = set(('handle', 'enum', 'bitmask'))
# Ideally these would be listed in the spec as exceptions, as OpenXR does.
SPECIAL_WORDS = set((
'16Bit', # VkPhysicalDevice16BitStorageFeatures
'2D', # VkPhysicalDeviceImage2DViewOf3DFeaturesEXT
'3D', # VkPhysicalDeviceImage2DViewOf3DFeaturesEXT
'8Bit', # VkPhysicalDevice8BitStorageFeaturesKHR
'AABB', # VkGeometryAABBNV
'ASTC', # VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT
@@ -173,7 +175,7 @@ class VulkanConventions(ConventionsBase):
instead. N.b. this may need to change on a per-refpage basis if
there are multiple documents involved.
"""
return 'https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html'
return 'https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html'
@property
def xml_api_name(self):