Update for Vulkan-Docs 1.4.319

This commit is contained in:
Jon Leech 2025-06-20 13:17:34 +01:00 committed by Jon Leech
parent b39ab380a4
commit 10739e8e00
38 changed files with 184363 additions and 135674 deletions

View file

@ -9,7 +9,7 @@ import os
import tempfile
from vulkan_object import (VulkanObject,
Extension, Version, Deprecate, Handle, Param, Queues, CommandScope, Command,
EnumField, Enum, Flag, Bitmask, Flags, Member, Struct,
EnumField, Enum, Flag, Bitmask, ExternSync, Flags, Member, Struct,
FormatComponent, FormatPlane, Format,
SyncSupport, SyncEquivalent, SyncStage, SyncAccess, SyncPipelineStage, SyncPipeline,
SpirvEnables, Spirv)
@ -35,6 +35,30 @@ def intIfGet(elem, name):
def boolGet(elem, name) -> bool:
return elem.get(name) is not None and elem.get(name) == "true"
def externSyncGet(elem):
value = elem.get('externsync')
if value is None:
return (ExternSync.NONE, None)
if value == 'true':
return (ExternSync.ALWAYS, None)
if value == 'maybe':
return (ExternSync.MAYBE, None)
# There are no cases where multiple members of the param are marked as
# externsync. Supporting that with maybe: requires more than
# ExternSync.SUBTYPE_MAYBE (which is only one bit of information), which is
# not currently done as there are no users.
#
# If this assert is hit, please consider simplifying the design such that
# externsync can move to the struct itself and so external synchronization
# requirements do not depend on the context.
assert ',' not in value
if value.startswith('maybe:'):
return (ExternSync.SUBTYPE_MAYBE, value.removeprefix('maybe:'))
return (ExternSync.SUBTYPE, value)
def getQueues(elem) -> Queues:
queues = 0
queues_list = splitIfGet(elem, 'queues')
@ -139,6 +163,10 @@ class BaseGenerator(OutputGenerator):
self.currentExtension = None
self.currentVersion = None
# We need to flag extensions that we ignore because they are disabled or not
# supported in the target API(s)
self.unsupportedExtension = False
# Will map alias to promoted name
# ex. ['VK_FILTER_CUBIC_IMG' : 'VK_FILTER_CUBIC_EXT']
# When generating any code, there is no reason so use the old name
@ -437,6 +465,17 @@ class BaseGenerator(OutputGenerator):
name = interface.get('name')
if interface.tag == 'extension':
# Generator scripts built on BaseGenerator do not handle the `supported` attribute of extensions
# therefore historically the `generate_source.py` in individual ecosystem components hacked the
# registry by removing non-applicable or disabled extensions from the loaded XML already before
# reg.py parsed it. That broke the general behavior of reg.py for certain use cases so we now
# filter extensions here instead (after parsing) in order to no longer need the filtering hack
# in downstream `generate_source.py` scripts.
enabledApiList = [ globalApiName ] + ([] if mergedApiNames is None else mergedApiNames.split(','))
if (sup := interface.get('supported')) is not None and all(api not in sup.split(',') for api in enabledApiList):
self.unsupportedExtension = True
return
instance = interface.get('type') == 'instance'
device = not instance
depends = interface.get('depends')
@ -468,12 +507,17 @@ class BaseGenerator(OutputGenerator):
OutputGenerator.endFeature(self)
self.currentExtension = None
self.currentVersion = None
self.unsupportedExtension = False
#
# All <command> from XML
def genCmd(self, cmdinfo, name, alias):
OutputGenerator.genCmd(self, cmdinfo, name, alias)
# Do not include APIs from unsupported extensions
if self.unsupportedExtension:
return
params = []
for param in cmdinfo.elem.findall('param'):
paramName = param.find('name').text
@ -505,12 +549,8 @@ class BaseGenerator(OutputGenerator):
optional = optionalValues is not None and optionalValues[0].lower() == "true"
optionalPointer = optionalValues is not None and len(optionalValues) > 1 and optionalValues[1].lower() == "true"
# externsync will be 'true' or expression
# if expression, it should be same as 'true'
externSync = boolGet(param, 'externsync')
externSyncPointer = None if externSync else splitIfGet(param, 'externsync')
if not externSync and externSyncPointer is not None:
externSync = True
# externsync will be 'true', 'maybe', '<expression>' or 'maybe:<expression>'
(externSync, externSyncPointer) = externSyncGet(param)
params.append(Param(paramName, paramAlias, paramType, paramFullType, paramNoautovalidity,
paramConst, length, nullTerminated, pointer, fixedSizeArray,
@ -566,6 +606,10 @@ class BaseGenerator(OutputGenerator):
# List the enum for the commands
# TODO - Seems empty groups like `VkDeviceDeviceMemoryReportCreateInfoEXT` do not show up in here
def genGroup(self, groupinfo, groupName, alias):
# Do not include APIs from unsupported extensions
if self.unsupportedExtension:
return
# There can be case where the Enum/Bitmask is in a protect, but the individual
# fields also have their own protect
groupProtect = self.currentExtension.protect if hasattr(self.currentExtension, 'protect') and self.currentExtension.protect is not None else None
@ -580,6 +624,15 @@ class BaseGenerator(OutputGenerator):
for elem in enumElem.findall('enum'):
fieldName = elem.get('name')
# Do not include non-required enum constants
# reg.py emits the enum constants of the entire type, even constants that are part of unsupported
# extensions or those that are removed by <remove> elements in a given API. reg.py correctly tracks
# down these and also alias dependencies and marks the enum constants that are actually required
# with the 'required' attribute. Therefore we also have to verify that here to make sure we only
# include enum constants that are actually required in the target API(s).
if elem.get('required') is None:
continue
if elem.get('alias') is not None:
self.enumFieldAliasMap[fieldName] = elem.get('alias')
continue
@ -604,6 +657,15 @@ class BaseGenerator(OutputGenerator):
for elem in enumElem.findall('enum'):
flagName = elem.get('name')
# Do not include non-required enum constants
# reg.py emits the enum constants of the entire type, even constants that are part of unsupported
# extensions or those that are removed by <remove> elements in a given API. reg.py correctly tracks
# down these and also alias dependencies and marks the enum constants that are actually required
# with the 'required' attribute. Therefore we also have to verify that here to make sure we only
# include enum constants that are actually required in the target API(s).
if elem.get('required') is None:
continue
if elem.get('alias') is not None:
self.flagAliasMap[flagName] = elem.get('alias')
continue
@ -628,6 +690,11 @@ class BaseGenerator(OutputGenerator):
def genType(self, typeInfo, typeName, alias):
OutputGenerator.genType(self, typeInfo, typeName, alias)
# Do not include APIs from unsupported extensions
if self.unsupportedExtension:
return
typeElem = typeInfo.elem
protect = self.currentExtension.protect if hasattr(self.currentExtension, 'protect') and self.currentExtension.protect is not None else None
extension = [self.currentExtension] if self.currentExtension is not None else []
@ -656,10 +723,13 @@ class BaseGenerator(OutputGenerator):
name = textIfFind(member, 'name')
type = textIfFind(member, 'type')
sType = member.get('values') if member.get('values') is not None else sType
externSync = boolGet(member, 'externsync')
noautovalidity = boolGet(member, 'noautovalidity')
limittype = member.get('limittype')
(externSync, externSyncPointer) = externSyncGet(member)
# No cases currently where a subtype of a struct is marked as externally synchronized.
assert externSyncPointer is None
nullTerminated = False
length = member.get('altlen') if member.get('altlen') is not None else member.get('len')
if length: