First Commit
This commit is contained in:
21
externals/vulkan-headers/registry/apiconventions.py
vendored
Normal file
21
externals/vulkan-headers/registry/apiconventions.py
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python3 -i
|
||||
#
|
||||
# Copyright 2021-2024 The Khronos Group Inc.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Generic alias for working group-specific API conventions interface.
|
||||
|
||||
# This import should be changed at the repository / working group level to
|
||||
# specify the correct API's conventions.
|
||||
|
||||
|
||||
import os
|
||||
|
||||
defaultAPI = 'vulkan'
|
||||
|
||||
VulkanAPI = os.getenv('VULKAN_API', default=defaultAPI)
|
||||
|
||||
if VulkanAPI == 'vulkansc':
|
||||
from vkconventions import VulkanSCConventions as APIConventions
|
||||
else:
|
||||
from vkconventions import VulkanConventions as APIConventions
|
||||
518
externals/vulkan-headers/registry/cgenerator.py
vendored
Normal file
518
externals/vulkan-headers/registry/cgenerator.py
vendored
Normal file
@@ -0,0 +1,518 @@
|
||||
#!/usr/bin/env python3 -i
|
||||
#
|
||||
# Copyright 2013-2024 The Khronos Group Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from generator import (GeneratorOptions,
|
||||
MissingGeneratorOptionsConventionsError,
|
||||
MissingGeneratorOptionsError, MissingRegistryError,
|
||||
OutputGenerator, noneStr, regSortFeatures, write)
|
||||
|
||||
class CGeneratorOptions(GeneratorOptions):
|
||||
"""CGeneratorOptions - subclass of GeneratorOptions.
|
||||
|
||||
Adds options used by COutputGenerator objects during C language header
|
||||
generation."""
|
||||
|
||||
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.
|
||||
Additional parameters beyond parent class:
|
||||
|
||||
- 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"""
|
||||
|
||||
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."""
|
||||
|
||||
# This is an ordered list of sections in the header file.
|
||||
TYPE_SECTIONS = ['include', 'define', 'basetype', 'handle', 'enum',
|
||||
'group', 'bitmask', 'funcpointer', 'struct']
|
||||
ALL_SECTIONS = TYPE_SECTIONS + ['commandPointer', 'command']
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
# 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:
|
||||
for s in genOpts.prefixText:
|
||||
write(s, file=self.outFile)
|
||||
|
||||
# C++ extern wrapper - after prefix lines so they can add includes.
|
||||
self.newline()
|
||||
write('#ifdef __cplusplus', file=self.outFile)
|
||||
write('extern "C" {', file=self.outFile)
|
||||
write('#endif', file=self.outFile)
|
||||
self.newline()
|
||||
|
||||
def endFile(self):
|
||||
# C-specific
|
||||
# Finish C++ wrapper and multiple inclusion protection
|
||||
if self.genOpts is None:
|
||||
raise MissingGeneratorOptionsError()
|
||||
self.newline()
|
||||
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)
|
||||
|
||||
def beginFeature(self, interface, emit):
|
||||
# Start processing in superclass
|
||||
OutputGenerator.beginFeature(self, interface, emit)
|
||||
# C-specific
|
||||
# Accumulate includes, defines, types, enums, function pointer typedefs,
|
||||
# end function prototypes separately for this feature. They are only
|
||||
# printed in endFeature().
|
||||
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
|
||||
if self.emit:
|
||||
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.featureName, self.featureExtraProtect, self.genOpts.filename):
|
||||
self.newline()
|
||||
if self.genOpts.protectFeature:
|
||||
write('#ifndef', self.featureName, file=self.outFile)
|
||||
|
||||
# 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)
|
||||
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.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)
|
||||
|
||||
def appendSection(self, section, text):
|
||||
"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)
|
||||
self.feature_not_empty = True
|
||||
|
||||
def genType(self, typeinfo, name, alias):
|
||||
"Generate type."
|
||||
OutputGenerator.genType(self, typeinfo, name, alias)
|
||||
typeElem = typeinfo.elem
|
||||
|
||||
# Vulkan:
|
||||
# Determine the category of the type, and the type section to add
|
||||
# its definition to.
|
||||
# 'funcpointer' is added to the 'struct' section as a workaround for
|
||||
# internal issue #877, since structures and function pointer types
|
||||
# can have cross-dependencies.
|
||||
category = typeElem.get('category')
|
||||
if category == 'funcpointer':
|
||||
section = 'struct'
|
||||
else:
|
||||
section = category
|
||||
|
||||
if category in ('struct', 'union'):
|
||||
# If the type is a struct type, generate it using the
|
||||
# special-purpose generator.
|
||||
self.genStruct(typeinfo, name, alias)
|
||||
else:
|
||||
if self.genOpts is None:
|
||||
raise MissingGeneratorOptionsError()
|
||||
|
||||
body = self.deprecationComment(typeElem)
|
||||
|
||||
# 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>")
|
||||
if body:
|
||||
# Add extra newline after multi-line entries.
|
||||
if '\n' in body[0:-1]:
|
||||
body += '\n'
|
||||
self.appendSection(section, body)
|
||||
|
||||
def genProtectString(self, protect_str):
|
||||
"""Generate protection string.
|
||||
|
||||
Protection strings are the strings defining the OS/Platform/Graphics
|
||||
requirements for a given API command. When generating the
|
||||
language header files, we need to make sure the items specific to a
|
||||
graphics API or OS platform are properly wrapped in #ifs."""
|
||||
protect_if_str = ''
|
||||
protect_end_str = ''
|
||||
if not protect_str:
|
||||
return (protect_if_str, protect_end_str)
|
||||
|
||||
if ',' in protect_str:
|
||||
protect_list = protect_str.split(',')
|
||||
protect_defs = ('defined(%s)' % d for d in protect_list)
|
||||
protect_def_str = ' && '.join(protect_defs)
|
||||
protect_if_str = '#if %s\n' % protect_def_str
|
||||
protect_end_str = '#endif // %s\n' % protect_def_str
|
||||
else:
|
||||
protect_if_str = '#ifdef %s\n' % protect_str
|
||||
protect_end_str = '#endif // %s\n' % protect_str
|
||||
|
||||
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).
|
||||
|
||||
This is a special case of the <type> tag where the contents are
|
||||
interpreted as a set of <member> tags instead of freeform C
|
||||
C type declarations. The <member> tags are just like <param>
|
||||
tags - they are a declaration of a struct or union member.
|
||||
Only simple member declarations are supported (no nested
|
||||
structs etc.)
|
||||
|
||||
If alias is not None, then this struct aliases another; just
|
||||
generate a typedef of that alias."""
|
||||
OutputGenerator.genStruct(self, typeinfo, typeName, alias)
|
||||
|
||||
if self.genOpts is None:
|
||||
raise MissingGeneratorOptionsError()
|
||||
|
||||
typeElem = typeinfo.elem
|
||||
body = self.deprecationComment(typeElem)
|
||||
|
||||
if alias:
|
||||
body += 'typedef ' + alias + ' ' + typeName + ';\n'
|
||||
else:
|
||||
(protect_begin, protect_end) = self.genProtectString(typeElem.get('protect'))
|
||||
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)
|
||||
for member in typeElem.findall('.//member'):
|
||||
body += self.deprecationComment(member, indent = 4)
|
||||
body += self.makeCParamDecl(member, targetLen + 4)
|
||||
body += ';\n'
|
||||
body += '} ' + typeName + ';\n'
|
||||
if protect_end:
|
||||
body += protect_end
|
||||
|
||||
self.appendSection('struct', body)
|
||||
|
||||
def genGroup(self, groupinfo, groupName, alias=None):
|
||||
"""Generate groups (e.g. C "enum" type).
|
||||
|
||||
These are concatenated together with other types.
|
||||
|
||||
If alias is not None, it is the name of another group type
|
||||
which aliases this type; just generate that alias."""
|
||||
OutputGenerator.genGroup(self, groupinfo, groupName, alias)
|
||||
groupElem = groupinfo.elem
|
||||
|
||||
# After either enumerated type or alias paths, add the declaration
|
||||
# to the appropriate section for the group being defined.
|
||||
if groupElem.get('type') == 'bitmask':
|
||||
section = 'bitmask'
|
||||
else:
|
||||
section = 'group'
|
||||
|
||||
if alias:
|
||||
# If the group name is aliased, just emit a typedef declaration
|
||||
# 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).
|
||||
|
||||
<enum> tags may specify their values in several ways, but are usually
|
||||
just integers."""
|
||||
|
||||
OutputGenerator.genEnum(self, enuminfo, name, alias)
|
||||
|
||||
body = self.deprecationComment(enuminfo.elem)
|
||||
body += self.buildConstantCDecl(enuminfo, name, alias)
|
||||
self.appendSection('enum', body)
|
||||
|
||||
def genCmd(self, cmdinfo, name, alias):
|
||||
"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
|
||||
1423
externals/vulkan-headers/registry/generator.py
vendored
Normal file
1423
externals/vulkan-headers/registry/generator.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
404
externals/vulkan-headers/registry/parse_dependency.py
vendored
Normal file
404
externals/vulkan-headers/registry/parse_dependency.py
vendored
Normal file
@@ -0,0 +1,404 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright 2022-2024 The Khronos Group Inc.
|
||||
# Copyright 2003-2019 Paul McGuire
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# apirequirements.py - parse 'depends' expressions in API XML
|
||||
# Supported methods:
|
||||
# dependency - the expression string
|
||||
#
|
||||
# evaluateDependency(dependency, isSupported) evaluates the expression,
|
||||
# returning a boolean result. isSupported takes an extension or version name
|
||||
# string and returns a boolean.
|
||||
#
|
||||
# dependencyLanguage(dependency) returns an English string equivalent
|
||||
# to the expression, suitable for header file comments.
|
||||
#
|
||||
# dependencyNames(dependency) returns a set of the extension and
|
||||
# version names in the expression.
|
||||
#
|
||||
# dependencyMarkup(dependency) returns a string containing asciidoctor
|
||||
# markup for English equivalent to the expression, suitable for extension
|
||||
# appendices.
|
||||
#
|
||||
# All may throw a ParseException if the expression cannot be parsed or is
|
||||
# not completely consumed by parsing.
|
||||
|
||||
# Supported expressions at present:
|
||||
# - extension names
|
||||
# - '+' as AND connector
|
||||
# - ',' as OR connector
|
||||
# - parenthesization for grouping
|
||||
|
||||
# Based on `examples/fourFn.py` from the
|
||||
# https://github.com/pyparsing/pyparsing/ repository.
|
||||
|
||||
from pyparsing import (
|
||||
Literal,
|
||||
Word,
|
||||
Group,
|
||||
Forward,
|
||||
alphas,
|
||||
alphanums,
|
||||
Regex,
|
||||
ParseException,
|
||||
CaselessKeyword,
|
||||
Suppress,
|
||||
delimitedList,
|
||||
infixNotation,
|
||||
)
|
||||
import math
|
||||
import operator
|
||||
import pyparsing as pp
|
||||
import re
|
||||
|
||||
from apiconventions import APIConventions as APIConventions
|
||||
conventions = APIConventions()
|
||||
|
||||
def markupPassthrough(name):
|
||||
"""Pass a name (leaf or operator) through without applying markup"""
|
||||
return name
|
||||
|
||||
def leafMarkupAsciidoc(name):
|
||||
"""Markup a leaf name as an asciidoc link to an API version or extension
|
||||
anchor.
|
||||
|
||||
- name - version or extension name"""
|
||||
|
||||
return conventions.formatVersionOrExtension(name)
|
||||
|
||||
def leafMarkupC(name):
|
||||
"""Markup a leaf name as a C expression, using conventions of the
|
||||
Vulkan Validation Layers
|
||||
|
||||
- name - version or extension name"""
|
||||
|
||||
(apivariant, major, minor) = apiVersionNameMatch(name)
|
||||
|
||||
if apivariant is not None:
|
||||
return name
|
||||
else:
|
||||
return f'ext.{name}'
|
||||
|
||||
opMarkupAsciidocMap = { '+' : 'and', ',' : 'or' }
|
||||
|
||||
def opMarkupAsciidoc(op):
|
||||
"""Markup an operator as an asciidoc spec markup equivalent
|
||||
|
||||
- op - operator ('+' or ',')"""
|
||||
|
||||
return opMarkupAsciidocMap[op]
|
||||
|
||||
opMarkupCMap = { '+' : '&&', ',' : '||' }
|
||||
|
||||
def opMarkupC(op):
|
||||
"""Markup an operator as a C language equivalent
|
||||
|
||||
- op - operator ('+' or ',')"""
|
||||
|
||||
return opMarkupCMap[op]
|
||||
|
||||
|
||||
# Unfortunately global to be used in pyparsing
|
||||
exprStack = []
|
||||
|
||||
def push_first(toks):
|
||||
"""Push a token on the global stack
|
||||
|
||||
- toks - first element is the token to push"""
|
||||
|
||||
exprStack.append(toks[0])
|
||||
|
||||
# An identifier (version or extension name)
|
||||
dependencyIdent = Word(alphanums + '_')
|
||||
|
||||
# Infix expression for depends expressions
|
||||
dependencyExpr = pp.infixNotation(dependencyIdent,
|
||||
[ (pp.oneOf(', +'), 2, pp.opAssoc.LEFT), ])
|
||||
|
||||
# BNF grammar for depends expressions
|
||||
_bnf = None
|
||||
def dependencyBNF():
|
||||
"""
|
||||
boolop :: '+' | ','
|
||||
extname :: Char(alphas)
|
||||
atom :: extname | '(' expr ')'
|
||||
expr :: atom [ boolop atom ]*
|
||||
"""
|
||||
global _bnf
|
||||
if _bnf is None:
|
||||
and_, or_ = map(Literal, '+,')
|
||||
lpar, rpar = map(Suppress, '()')
|
||||
boolop = and_ | or_
|
||||
|
||||
expr = Forward()
|
||||
expr_list = delimitedList(Group(expr))
|
||||
atom = (
|
||||
boolop[...]
|
||||
+ (
|
||||
(dependencyIdent).setParseAction(push_first)
|
||||
| Group(lpar + expr + rpar)
|
||||
)
|
||||
)
|
||||
|
||||
expr <<= atom + (boolop + atom).setParseAction(push_first)[...]
|
||||
_bnf = expr
|
||||
return _bnf
|
||||
|
||||
|
||||
# map operator symbols to corresponding arithmetic operations
|
||||
_opn = {
|
||||
'+': operator.and_,
|
||||
',': operator.or_,
|
||||
}
|
||||
|
||||
def evaluateStack(stack, isSupported):
|
||||
"""Evaluate an expression stack, returning a boolean result.
|
||||
|
||||
- stack - the stack
|
||||
- isSupported - function taking a version or extension name string and
|
||||
returning True or False if that name is supported or not."""
|
||||
|
||||
op, num_args = stack.pop(), 0
|
||||
if isinstance(op, tuple):
|
||||
op, num_args = op
|
||||
|
||||
if op in '+,':
|
||||
# Note: operands are pushed onto the stack in reverse order
|
||||
op2 = evaluateStack(stack, isSupported)
|
||||
op1 = evaluateStack(stack, isSupported)
|
||||
return _opn[op](op1, op2)
|
||||
elif op[0].isalpha():
|
||||
return isSupported(op)
|
||||
else:
|
||||
raise Exception(f'invalid op: {op}')
|
||||
|
||||
def evaluateDependency(dependency, isSupported):
|
||||
"""Evaluate a dependency expression, returning a boolean result.
|
||||
|
||||
- dependency - the expression
|
||||
- isSupported - function taking a version or extension name string and
|
||||
returning True or False if that name is supported or not."""
|
||||
|
||||
global exprStack
|
||||
exprStack = []
|
||||
results = dependencyBNF().parseString(dependency, parseAll=True)
|
||||
val = evaluateStack(exprStack[:], isSupported)
|
||||
return val
|
||||
|
||||
def evalDependencyLanguage(stack, leafMarkup, opMarkup, parenthesize, root):
|
||||
"""Evaluate an expression stack, returning an English equivalent
|
||||
|
||||
- stack - the stack
|
||||
- leafMarkup, opMarkup, parenthesize - same as dependencyLanguage
|
||||
- root - True only if this is the outer (root) expression level"""
|
||||
|
||||
op, num_args = stack.pop(), 0
|
||||
if isinstance(op, tuple):
|
||||
op, num_args = op
|
||||
if op in '+,':
|
||||
# Could parenthesize, not needed yet
|
||||
rhs = evalDependencyLanguage(stack, leafMarkup, opMarkup, parenthesize, root = False)
|
||||
opname = opMarkup(op)
|
||||
lhs = evalDependencyLanguage(stack, leafMarkup, opMarkup, parenthesize, root = False)
|
||||
if parenthesize and not root:
|
||||
return f'({lhs} {opname} {rhs})'
|
||||
else:
|
||||
return f'{lhs} {opname} {rhs}'
|
||||
elif op[0].isalpha():
|
||||
# This is an extension or feature name
|
||||
return leafMarkup(op)
|
||||
else:
|
||||
raise Exception(f'invalid op: {op}')
|
||||
|
||||
def dependencyLanguage(dependency, leafMarkup, opMarkup, parenthesize):
|
||||
"""Return an API dependency expression translated to a form suitable for
|
||||
asciidoctor conditionals or header file comments.
|
||||
|
||||
- dependency - the expression
|
||||
- leafMarkup - function taking an extension / version name and
|
||||
returning an equivalent marked up version
|
||||
- opMarkup - function taking an operator ('+' / ',') name name and
|
||||
returning an equivalent marked up version
|
||||
- parenthesize - True if parentheses should be used in the resulting
|
||||
expression, False otherwise"""
|
||||
|
||||
global exprStack
|
||||
exprStack = []
|
||||
results = dependencyBNF().parseString(dependency, parseAll=True)
|
||||
return evalDependencyLanguage(exprStack, leafMarkup, opMarkup, parenthesize, root = True)
|
||||
|
||||
# aka specmacros = False
|
||||
def dependencyLanguageComment(dependency):
|
||||
"""Return dependency expression translated to a form suitable for
|
||||
comments in headers of emitted C code, as used by the
|
||||
docgenerator."""
|
||||
return dependencyLanguage(dependency, leafMarkup = markupPassthrough, opMarkup = opMarkupAsciidoc, parenthesize = True)
|
||||
|
||||
# aka specmacros = True
|
||||
def dependencyLanguageSpecMacros(dependency):
|
||||
"""Return dependency expression translated to a form suitable for
|
||||
comments in headers of emitted C code, as used by the
|
||||
interfacegenerator."""
|
||||
return dependencyLanguage(dependency, leafMarkup = leafMarkupAsciidoc, opMarkup = opMarkupAsciidoc, parenthesize = False)
|
||||
|
||||
def dependencyLanguageC(dependency):
|
||||
"""Return dependency expression translated to a form suitable for
|
||||
use in C expressions"""
|
||||
return dependencyLanguage(dependency, leafMarkup = leafMarkupC, opMarkup = opMarkupC, parenthesize = True)
|
||||
|
||||
def evalDependencyNames(stack):
|
||||
"""Evaluate an expression stack, returning the set of extension and
|
||||
feature names used in the expression.
|
||||
|
||||
- stack - the stack"""
|
||||
|
||||
op, num_args = stack.pop(), 0
|
||||
if isinstance(op, tuple):
|
||||
op, num_args = op
|
||||
if op in '+,':
|
||||
# Do not evaluate the operation. We only care about the names.
|
||||
return evalDependencyNames(stack) | evalDependencyNames(stack)
|
||||
elif op[0].isalpha():
|
||||
return { op }
|
||||
else:
|
||||
raise Exception(f'invalid op: {op}')
|
||||
|
||||
def dependencyNames(dependency):
|
||||
"""Return a set of the extension and version names in an API dependency
|
||||
expression. Used when determining transitive dependencies for spec
|
||||
generation with specific extensions included.
|
||||
|
||||
- dependency - the expression"""
|
||||
|
||||
global exprStack
|
||||
exprStack = []
|
||||
results = dependencyBNF().parseString(dependency, parseAll=True)
|
||||
# print(f'names(): stack = {exprStack}')
|
||||
return evalDependencyNames(exprStack)
|
||||
|
||||
def markupTraverse(expr, level = 0, root = True):
|
||||
"""Recursively process a dependency in infix form, transforming it into
|
||||
asciidoctor markup with expression nesting indicated by indentation
|
||||
level.
|
||||
|
||||
- expr - expression to process
|
||||
- level - indentation level to render expression at
|
||||
- root - True only on initial call"""
|
||||
|
||||
if level > 0:
|
||||
prefix = '{nbsp}{nbsp}' * level * 2 + ' '
|
||||
else:
|
||||
prefix = ''
|
||||
str = ''
|
||||
|
||||
for elem in expr:
|
||||
if isinstance(elem, pp.ParseResults):
|
||||
if not root:
|
||||
nextlevel = level + 1
|
||||
else:
|
||||
# Do not indent the outer expression
|
||||
nextlevel = level
|
||||
|
||||
str = str + markupTraverse(elem, level = nextlevel, root = False)
|
||||
elif elem in ('+', ','):
|
||||
str = str + f'{prefix}{opMarkupAsciidoc(elem)} +\n'
|
||||
else:
|
||||
str = str + f'{prefix}{leafMarkupAsciidoc(elem)} +\n'
|
||||
|
||||
return str
|
||||
|
||||
def dependencyMarkup(dependency):
|
||||
"""Return asciidoctor markup for a human-readable equivalent of an API
|
||||
dependency expression, suitable for use in extension appendix
|
||||
metadata.
|
||||
|
||||
- dependency - the expression"""
|
||||
|
||||
parsed = dependencyExpr.parseString(dependency)
|
||||
return markupTraverse(parsed)
|
||||
|
||||
if __name__ == "__main__":
|
||||
for str in [ 'VK_VERSION_1_0', 'cl_khr_extension_name', 'XR_VERSION_3_2', 'CL_VERSION_1_0' ]:
|
||||
print(f'{str} -> {conventions.formatVersionOrExtension(str)}')
|
||||
import sys
|
||||
sys.exit(0)
|
||||
|
||||
termdict = {
|
||||
'VK_VERSION_1_1' : True,
|
||||
'false' : False,
|
||||
'true' : True,
|
||||
}
|
||||
termSupported = lambda name: name in termdict and termdict[name]
|
||||
|
||||
def test(dependency, expected):
|
||||
val = False
|
||||
try:
|
||||
val = evaluateDependency(dependency, termSupported)
|
||||
except ParseException as pe:
|
||||
print(dependency, f'failed parse: {dependency}')
|
||||
except Exception as e:
|
||||
print(dependency, f'failed eval: {dependency}')
|
||||
|
||||
if val == expected:
|
||||
True
|
||||
# print(f'{dependency} = {val} (as expected)')
|
||||
else:
|
||||
print(f'{dependency} ERROR: {val} != {expected}')
|
||||
|
||||
# Verify expressions are evaluated left-to-right
|
||||
|
||||
test('false,false+false', False)
|
||||
test('false,false+true', False)
|
||||
test('false,true+false', False)
|
||||
test('false,true+true', True)
|
||||
test('true,false+false', False)
|
||||
test('true,false+true', True)
|
||||
test('true,true+false', False)
|
||||
test('true,true+true', True)
|
||||
|
||||
test('false,(false+false)', False)
|
||||
test('false,(false+true)', False)
|
||||
test('false,(true+false)', False)
|
||||
test('false,(true+true)', True)
|
||||
test('true,(false+false)', True)
|
||||
test('true,(false+true)', True)
|
||||
test('true,(true+false)', True)
|
||||
test('true,(true+true)', True)
|
||||
|
||||
|
||||
test('false+false,false', False)
|
||||
test('false+false,true', True)
|
||||
test('false+true,false', False)
|
||||
test('false+true,true', True)
|
||||
test('true+false,false', False)
|
||||
test('true+false,true', True)
|
||||
test('true+true,false', True)
|
||||
test('true+true,true', True)
|
||||
|
||||
test('false+(false,false)', False)
|
||||
test('false+(false,true)', False)
|
||||
test('false+(true,false)', False)
|
||||
test('false+(true,true)', False)
|
||||
test('true+(false,false)', False)
|
||||
test('true+(false,true)', True)
|
||||
test('true+(true,false)', True)
|
||||
test('true+(true,true)', True)
|
||||
|
||||
# Check formatting
|
||||
for dependency in [
|
||||
#'true',
|
||||
#'true+true+false',
|
||||
'true+false',
|
||||
'true+(true+false),(false,true)',
|
||||
#'true+((true+false),(false,true))',
|
||||
'VK_VERSION_1_0+VK_KHR_display',
|
||||
#'VK_VERSION_1_1+(true,false)',
|
||||
]:
|
||||
print(f'expr = {dependency}\n{dependencyMarkup(dependency)}')
|
||||
print(f' spec language = {dependencyLanguageSpecMacros(dependency)}')
|
||||
print(f' comment language = {dependencyLanguageComment(dependency)}')
|
||||
print(f' C language = {dependencyLanguageC(dependency)}')
|
||||
print(f' names = {dependencyNames(dependency)}')
|
||||
print(f' value = {evaluateDependency(dependency, termSupported)}')
|
||||
390
externals/vulkan-headers/registry/profiles/VP_KHR_roadmap.json
vendored
Normal file
390
externals/vulkan-headers/registry/profiles/VP_KHR_roadmap.json
vendored
Normal file
@@ -0,0 +1,390 @@
|
||||
{
|
||||
"$schema": "https://schema.khronos.org/vulkan/profiles-0.8.2-276.json#",
|
||||
"capabilities": {
|
||||
"vulkan10requirements": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceFeatures": {
|
||||
"robustBufferAccess": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan11requirements": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan11Features": {
|
||||
"multiview": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceVulkan11Properties": {
|
||||
"maxMultiviewViewCount": 6,
|
||||
"maxMultiviewInstanceIndex": 134217727
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan12requirements": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan12Features": {
|
||||
"uniformBufferStandardLayout": true,
|
||||
"subgroupBroadcastDynamicId": true,
|
||||
"imagelessFramebuffer": true,
|
||||
"separateDepthStencilLayouts": true,
|
||||
"hostQueryReset": true,
|
||||
"timelineSemaphore": true,
|
||||
"shaderSubgroupExtendedTypes": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceVulkan12Properties": {
|
||||
"maxTimelineSemaphoreValueDifference": 2147483647
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan13requirements": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan12Features": {
|
||||
"vulkanMemoryModel": true,
|
||||
"vulkanMemoryModelDeviceScope": true,
|
||||
"bufferDeviceAddress": true
|
||||
},
|
||||
"VkPhysicalDeviceVulkan13Features": {
|
||||
"robustImageAccess": true,
|
||||
"shaderTerminateInvocation": true,
|
||||
"shaderZeroInitializeWorkgroupMemory": true,
|
||||
"synchronization2": true,
|
||||
"shaderIntegerDotProduct": true,
|
||||
"maintenance4": true,
|
||||
"pipelineCreationCacheControl": true,
|
||||
"subgroupSizeControl": true,
|
||||
"computeFullSubgroups": true,
|
||||
"shaderDemoteToHelperInvocation": true,
|
||||
"inlineUniformBlock": true,
|
||||
"dynamicRendering": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceVulkan13Properties": {
|
||||
"maxBufferSize": 1073741824,
|
||||
"maxInlineUniformBlockSize": 256,
|
||||
"maxPerStageDescriptorInlineUniformBlocks": 4,
|
||||
"maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks": 4,
|
||||
"maxDescriptorSetInlineUniformBlocks": 4,
|
||||
"maxDescriptorSetUpdateAfterBindInlineUniformBlocks": 4,
|
||||
"maxInlineUniformTotalSize": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan10requirements_roadmap2022": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceFeatures": {
|
||||
"fullDrawIndexUint32": true,
|
||||
"imageCubeArray": true,
|
||||
"independentBlend": true,
|
||||
"sampleRateShading": true,
|
||||
"drawIndirectFirstInstance": true,
|
||||
"depthClamp": true,
|
||||
"depthBiasClamp": true,
|
||||
"samplerAnisotropy": true,
|
||||
"occlusionQueryPrecise": true,
|
||||
"fragmentStoresAndAtomics": true,
|
||||
"shaderStorageImageExtendedFormats": true,
|
||||
"shaderUniformBufferArrayDynamicIndexing": true,
|
||||
"shaderSampledImageArrayDynamicIndexing": true,
|
||||
"shaderStorageBufferArrayDynamicIndexing": true,
|
||||
"shaderStorageImageArrayDynamicIndexing": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceProperties": {
|
||||
"limits": {
|
||||
"maxImageDimension1D": 8192,
|
||||
"maxImageDimension2D": 8192,
|
||||
"maxImageDimensionCube": 8192,
|
||||
"maxImageArrayLayers": 2048,
|
||||
"maxUniformBufferRange": 65536,
|
||||
"bufferImageGranularity": 4096,
|
||||
"maxPerStageDescriptorSamplers": 64,
|
||||
"maxPerStageDescriptorUniformBuffers": 15,
|
||||
"maxPerStageDescriptorStorageBuffers": 30,
|
||||
"maxPerStageDescriptorSampledImages": 200,
|
||||
"maxPerStageDescriptorStorageImages": 16,
|
||||
"maxPerStageResources": 200,
|
||||
"maxDescriptorSetSamplers": 576,
|
||||
"maxDescriptorSetUniformBuffers": 90,
|
||||
"maxDescriptorSetStorageBuffers": 96,
|
||||
"maxDescriptorSetSampledImages": 1800,
|
||||
"maxDescriptorSetStorageImages": 144,
|
||||
"maxFragmentCombinedOutputResources": 16,
|
||||
"maxComputeWorkGroupInvocations": 256,
|
||||
"maxComputeWorkGroupSize": [ 256, 256, 64 ],
|
||||
"subTexelPrecisionBits": 8,
|
||||
"mipmapPrecisionBits": 6,
|
||||
"maxSamplerLodBias": 14,
|
||||
"standardSampleLocations": true,
|
||||
"maxColorAttachments": 7
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan10optionals_roadmap2022": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceFeatures": {
|
||||
"largePoints": true,
|
||||
"wideLines": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceProperties": {
|
||||
"limits": {
|
||||
"pointSizeGranularity": 0.125,
|
||||
"lineWidthGranularity": 0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan11requirements_roadmap2022": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan11Features": {
|
||||
"samplerYcbcrConversion": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceVulkan11Properties": {
|
||||
"subgroupSize": 4,
|
||||
"subgroupSupportedStages": [ "VK_SHADER_STAGE_COMPUTE_BIT", "VK_SHADER_STAGE_FRAGMENT_BIT" ],
|
||||
"subgroupSupportedOperations": [ "VK_SUBGROUP_FEATURE_BASIC_BIT", "VK_SUBGROUP_FEATURE_VOTE_BIT", "VK_SUBGROUP_FEATURE_ARITHMETIC_BIT", "VK_SUBGROUP_FEATURE_BALLOT_BIT", "VK_SUBGROUP_FEATURE_SHUFFLE_BIT", "VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT", "VK_SUBGROUP_FEATURE_QUAD_BIT" ]
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan12requirements_roadmap2022": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan12Features": {
|
||||
"samplerMirrorClampToEdge": true,
|
||||
"descriptorIndexing": true,
|
||||
"shaderUniformTexelBufferArrayDynamicIndexing": true,
|
||||
"shaderStorageTexelBufferArrayDynamicIndexing": true,
|
||||
"shaderUniformBufferArrayNonUniformIndexing": true,
|
||||
"shaderSampledImageArrayNonUniformIndexing": true,
|
||||
"shaderStorageBufferArrayNonUniformIndexing": true,
|
||||
"shaderStorageImageArrayNonUniformIndexing": true,
|
||||
"shaderUniformTexelBufferArrayNonUniformIndexing": true,
|
||||
"shaderStorageTexelBufferArrayNonUniformIndexing": true,
|
||||
"descriptorBindingSampledImageUpdateAfterBind": true,
|
||||
"descriptorBindingStorageImageUpdateAfterBind": true,
|
||||
"descriptorBindingStorageBufferUpdateAfterBind": true,
|
||||
"descriptorBindingUniformTexelBufferUpdateAfterBind": true,
|
||||
"descriptorBindingStorageTexelBufferUpdateAfterBind": true,
|
||||
"descriptorBindingUpdateUnusedWhilePending": true,
|
||||
"descriptorBindingPartiallyBound": true,
|
||||
"descriptorBindingVariableDescriptorCount": true,
|
||||
"runtimeDescriptorArray": true,
|
||||
"scalarBlockLayout": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceVulkan12Properties": {
|
||||
"shaderSignedZeroInfNanPreserveFloat16": true,
|
||||
"shaderSignedZeroInfNanPreserveFloat32": true,
|
||||
"maxPerStageDescriptorUpdateAfterBindSamplers": 500000,
|
||||
"maxPerStageDescriptorUpdateAfterBindUniformBuffers": 12,
|
||||
"maxPerStageDescriptorUpdateAfterBindStorageBuffers": 500000,
|
||||
"maxPerStageDescriptorUpdateAfterBindSampledImages": 500000,
|
||||
"maxPerStageDescriptorUpdateAfterBindStorageImages": 500000,
|
||||
"maxPerStageDescriptorUpdateAfterBindInputAttachments": 7,
|
||||
"maxPerStageUpdateAfterBindResources": 500000,
|
||||
"maxDescriptorSetUpdateAfterBindSamplers": 500000,
|
||||
"maxDescriptorSetUpdateAfterBindUniformBuffers": 72,
|
||||
"maxDescriptorSetUpdateAfterBindUniformBuffersDynamic": 8,
|
||||
"maxDescriptorSetUpdateAfterBindStorageBuffers": 500000,
|
||||
"maxDescriptorSetUpdateAfterBindStorageBuffersDynamic": 4,
|
||||
"maxDescriptorSetUpdateAfterBindSampledImages": 500000,
|
||||
"maxDescriptorSetUpdateAfterBindStorageImages": 500000,
|
||||
"maxDescriptorSetUpdateAfterBindInputAttachments": 7
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan13requirements_roadmap2022": {
|
||||
"extensions": {
|
||||
"VK_KHR_global_priority": 1
|
||||
},
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan13Features": {
|
||||
"descriptorBindingInlineUniformBlockUpdateAfterBind": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan10requirements_roadmap2024": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceFeatures": {
|
||||
"multiDrawIndirect": true,
|
||||
"shaderInt16": true,
|
||||
"shaderImageGatherExtended": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceProperties": {
|
||||
"limits": {
|
||||
"timestampComputeAndGraphics": true,
|
||||
"maxColorAttachments": 8,
|
||||
"maxBoundDescriptorSets": 7
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan11requirements_roadmap2024": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan11Features": {
|
||||
"shaderDrawParameters": true,
|
||||
"storageBuffer16BitAccess": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan12requirements_roadmap2024": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan12Features": {
|
||||
"shaderInt8": true,
|
||||
"shaderFloat16": true,
|
||||
"storageBuffer8BitAccess": true
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceVulkan12Properties": {
|
||||
"shaderRoundingModeRTEFloat16": true,
|
||||
"shaderRoundingModeRTEFloat32": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkan13requirements_roadmap2024": {
|
||||
"features": {
|
||||
"VkPhysicalDeviceVulkan13Features": {
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"VkPhysicalDeviceVulkan13Properties": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"vulkanextensionrequirements_roadmap2024": {
|
||||
"extensions": {
|
||||
"VK_KHR_dynamic_rendering_local_read": 1,
|
||||
"VK_KHR_load_store_op_none": 1,
|
||||
"VK_KHR_shader_quad_control": 1,
|
||||
"VK_KHR_shader_maximal_reconvergence": 1,
|
||||
"VK_KHR_shader_subgroup_uniform_control_flow": 1,
|
||||
"VK_KHR_shader_subgroup_rotate": 1,
|
||||
"VK_KHR_shader_float_controls2": 1,
|
||||
"VK_KHR_shader_expect_assume": 1,
|
||||
"VK_KHR_line_rasterization": 1,
|
||||
"VK_KHR_vertex_attribute_divisor": 1,
|
||||
"VK_KHR_index_type_uint8": 1,
|
||||
"VK_KHR_map_memory2": 1,
|
||||
"VK_KHR_maintenance5": 1,
|
||||
"VK_KHR_push_descriptor": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"VP_KHR_roadmap_2024": {
|
||||
"version": 1,
|
||||
"api-version": "1.3.276",
|
||||
"label": "Khronos Vulkan Roadmap 2024 profile",
|
||||
"description": "This roadmap profile is intended to be supported by newer devices shipping in 2024 across mainstream smartphone, tablet, laptops, console and desktop devices.",
|
||||
"profiles": [
|
||||
"VP_KHR_roadmap_2022"
|
||||
],
|
||||
"capabilities": [
|
||||
"vulkan10requirements_roadmap2024",
|
||||
"vulkan11requirements_roadmap2024",
|
||||
"vulkan12requirements_roadmap2024",
|
||||
"vulkan13requirements_roadmap2024",
|
||||
"vulkanextensionrequirements_roadmap2024"
|
||||
]
|
||||
},
|
||||
"VP_KHR_roadmap_2022": {
|
||||
"version": 1,
|
||||
"api-version": "1.3.204",
|
||||
"label": "Khronos Vulkan Roadmap 2022 profile",
|
||||
"description": "This roadmap profile is intended to be supported by newer devices shipping in 2022 across mainstream smartphone, tablet, laptops, console and desktop devices.",
|
||||
"contributors": {
|
||||
"Tobias Hector": {
|
||||
"company": "AMD",
|
||||
"email": "tobias.hector@amd.com",
|
||||
"contact": true
|
||||
},
|
||||
"Christophe Riccio": {
|
||||
"company": "LunarG",
|
||||
"email": "christophe@lunarg.com",
|
||||
"contact": true
|
||||
}
|
||||
},
|
||||
"history": [
|
||||
{
|
||||
"revision": 9,
|
||||
"date": "2024-01-16",
|
||||
"author": "Tobias Hector",
|
||||
"comment": "Add Roadmap 2024 profile"
|
||||
},
|
||||
{
|
||||
"revision": 8,
|
||||
"date": "2023-11-02",
|
||||
"author": "Christophe Riccio",
|
||||
"comment": "Remove unreferenced capabilities blocks that were written against Vulkan 1.2 for testing before Vulkan 1.3 was released"
|
||||
},
|
||||
{
|
||||
"revision": 7,
|
||||
"date": "2022-11-16",
|
||||
"author": "Christophe Riccio",
|
||||
"comment": "Fix wideLines and largePoints that are optionals"
|
||||
},
|
||||
{
|
||||
"revision": 6,
|
||||
"date": "2022-11-02",
|
||||
"author": "Christophe Riccio",
|
||||
"comment": "Fix roadmap 2022 maxInlineUniformTotalSize limit, 256 instead of 4"
|
||||
},
|
||||
{
|
||||
"revision": 5,
|
||||
"date": "2022-05-02",
|
||||
"author": "Christophe Riccio",
|
||||
"comment": "Add missing dynamicRendering that is a Vulkan 1.3 requirement"
|
||||
},
|
||||
{
|
||||
"revision": 4,
|
||||
"date": "2022-03-08",
|
||||
"author": "Christophe Riccio",
|
||||
"comment": "Refactor requirements per Vulkan API version"
|
||||
},
|
||||
{
|
||||
"revision": 3,
|
||||
"date": "2022-03-08",
|
||||
"author": "Christophe Riccio",
|
||||
"comment": "Fix Vulkan 1.3.204 API version requirement"
|
||||
},
|
||||
{
|
||||
"revision": 2,
|
||||
"date": "2022-01-03",
|
||||
"author": "Christophe Riccio",
|
||||
"comment": "Rebase against Vulkan 1.3.203 revision"
|
||||
},
|
||||
{
|
||||
"revision": 1,
|
||||
"date": "2021-12-08",
|
||||
"author": "Christophe Riccio",
|
||||
"comment": "Initial revision"
|
||||
}
|
||||
],
|
||||
"capabilities": [
|
||||
"vulkan10requirements",
|
||||
"vulkan10requirements_roadmap2022",
|
||||
"vulkan11requirements",
|
||||
"vulkan11requirements_roadmap2022",
|
||||
"vulkan12requirements",
|
||||
"vulkan12requirements_roadmap2022",
|
||||
"vulkan13requirements",
|
||||
"vulkan13requirements_roadmap2022"
|
||||
],
|
||||
"optionals": [
|
||||
"vulkan10optionals_roadmap2022"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
1820
externals/vulkan-headers/registry/reg.py
vendored
Normal file
1820
externals/vulkan-headers/registry/reg.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
563
externals/vulkan-headers/registry/spec_tools/conventions.py
vendored
Normal file
563
externals/vulkan-headers/registry/spec_tools/conventions.py
vendored
Normal file
@@ -0,0 +1,563 @@
|
||||
#!/usr/bin/env python3 -i
|
||||
#
|
||||
# Copyright 2013-2024 The Khronos Group Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Base class for working-group-specific style conventions,
|
||||
# used in generation.
|
||||
|
||||
from enum import Enum
|
||||
import abc
|
||||
import re
|
||||
|
||||
# Type categories that respond "False" to isStructAlwaysValid
|
||||
# basetype is home to typedefs like ..Bool32
|
||||
CATEGORIES_REQUIRING_VALIDATION = set(('handle',
|
||||
'enum',
|
||||
'bitmask',
|
||||
'basetype',
|
||||
None))
|
||||
|
||||
# These are basic C types pulled in via openxr_platform_defines.h
|
||||
TYPES_KNOWN_ALWAYS_VALID = set(('char',
|
||||
'float',
|
||||
'int8_t', 'uint8_t',
|
||||
'int16_t', 'uint16_t',
|
||||
'int32_t', 'uint32_t',
|
||||
'int64_t', 'uint64_t',
|
||||
'size_t',
|
||||
'intptr_t', 'uintptr_t',
|
||||
'int',
|
||||
))
|
||||
|
||||
# Split an extension name into vendor ID and name portions
|
||||
EXT_NAME_DECOMPOSE_RE = re.compile(r'(?P<prefix>[A-Za-z]+)_(?P<vendor>[A-Za-z]+)_(?P<name>[\w_]+)')
|
||||
|
||||
# Match an API version name.
|
||||
# Match object includes API prefix, major, and minor version numbers.
|
||||
# This could be refined further for specific APIs.
|
||||
API_VERSION_NAME_RE = re.compile(r'(?P<apivariant>[A-Za-z]+)_VERSION_(?P<major>[0-9]+)_(?P<minor>[0-9]+)')
|
||||
|
||||
class ProseListFormats(Enum):
|
||||
"""A connective, possibly with a quantifier."""
|
||||
AND = 0
|
||||
EACH_AND = 1
|
||||
OR = 2
|
||||
ANY_OR = 3
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, s):
|
||||
if s == 'or':
|
||||
return cls.OR
|
||||
if s == 'and':
|
||||
return cls.AND
|
||||
raise RuntimeError("Unrecognized string connective: " + s)
|
||||
|
||||
@property
|
||||
def connective(self):
|
||||
if self in (ProseListFormats.OR, ProseListFormats.ANY_OR):
|
||||
return 'or'
|
||||
return 'and'
|
||||
|
||||
def quantifier(self, n):
|
||||
"""Return the desired quantifier for a list of a given length."""
|
||||
if self == ProseListFormats.ANY_OR:
|
||||
if n > 1:
|
||||
return 'any of '
|
||||
elif self == ProseListFormats.EACH_AND:
|
||||
if n > 2:
|
||||
return 'each of '
|
||||
if n == 2:
|
||||
return 'both of '
|
||||
return ''
|
||||
|
||||
|
||||
class ConventionsBase(abc.ABC):
|
||||
"""WG-specific conventions."""
|
||||
|
||||
def __init__(self):
|
||||
self._command_prefix = None
|
||||
self._type_prefix = None
|
||||
|
||||
def formatVersionOrExtension(self, name):
|
||||
"""Mark up an API version or extension name as a link in the spec."""
|
||||
|
||||
# Is this a version name?
|
||||
match = API_VERSION_NAME_RE.match(name)
|
||||
if match is not None:
|
||||
return self.formatVersion(name,
|
||||
match.group('apivariant'),
|
||||
match.group('major'),
|
||||
match.group('minor'))
|
||||
else:
|
||||
# If not, assumed to be an extension name. Might be worth checking.
|
||||
return self.formatExtension(name)
|
||||
|
||||
def formatVersion(self, name, apivariant, major, minor):
|
||||
"""Mark up an API version name as a link in the spec."""
|
||||
return '`<<{}>>`'.format(name)
|
||||
|
||||
def formatExtension(self, name):
|
||||
"""Mark up an extension name as a link in the spec."""
|
||||
return '`<<{}>>`'.format(name)
|
||||
|
||||
def formatSPIRVlink(self, name):
|
||||
"""Mark up a SPIR-V extension name as an external link in the spec.
|
||||
Since these are external links, the formatting probably will be
|
||||
the same for all APIs creating such links, so long as they use
|
||||
the asciidoctor {spirv} attribute for the base path to the SPIR-V
|
||||
extensions."""
|
||||
|
||||
(vendor, _) = self.extension_name_split(name)
|
||||
|
||||
return f'{{spirv}}/{vendor}/{name}.html[{name}]'
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def null(self):
|
||||
"""Preferred spelling of NULL."""
|
||||
raise NotImplementedError
|
||||
|
||||
def makeProseList(self, elements, fmt=ProseListFormats.AND, with_verb=False, *args, **kwargs):
|
||||
"""Make a (comma-separated) list for use in prose.
|
||||
|
||||
Adds a connective (by default, 'and')
|
||||
before the last element if there are more than 1.
|
||||
|
||||
Adds the right one of "is" or "are" to the end if with_verb is true.
|
||||
|
||||
Optionally adds a quantifier (like 'any') before a list of 2 or more,
|
||||
if specified by fmt.
|
||||
|
||||
Override with a different method or different call to
|
||||
_implMakeProseList if you want to add a comma for two elements,
|
||||
or not use a serial comma.
|
||||
"""
|
||||
return self._implMakeProseList(elements, fmt, with_verb, *args, **kwargs)
|
||||
|
||||
@property
|
||||
def struct_macro(self):
|
||||
"""Get the appropriate format macro for a structure.
|
||||
|
||||
May override.
|
||||
"""
|
||||
return 'slink:'
|
||||
|
||||
@property
|
||||
def external_macro(self):
|
||||
"""Get the appropriate format macro for an external type like uint32_t.
|
||||
|
||||
May override.
|
||||
"""
|
||||
return 'code:'
|
||||
|
||||
@property
|
||||
def allows_x_number_suffix(self):
|
||||
"""Whether vendor tags can be suffixed with X and a number to mark experimental extensions."""
|
||||
return False
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def structtype_member_name(self):
|
||||
"""Return name of the structure type member.
|
||||
|
||||
Must implement.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def nextpointer_member_name(self):
|
||||
"""Return name of the structure pointer chain member.
|
||||
|
||||
Must implement.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def xml_api_name(self):
|
||||
"""Return the name used in the default API XML registry for the default API"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@abc.abstractmethod
|
||||
def generate_structure_type_from_name(self, structname):
|
||||
"""Generate a structure type name, like XR_TYPE_CREATE_INSTANCE_INFO.
|
||||
|
||||
Must implement.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def makeStructName(self, name):
|
||||
"""Prepend the appropriate format macro for a structure to a structure type name.
|
||||
|
||||
Uses struct_macro, so just override that if you want to change behavior.
|
||||
"""
|
||||
return self.struct_macro + name
|
||||
|
||||
def makeExternalTypeName(self, name):
|
||||
"""Prepend the appropriate format macro for an external type like uint32_t to a type name.
|
||||
|
||||
Uses external_macro, so just override that if you want to change behavior.
|
||||
"""
|
||||
return self.external_macro + name
|
||||
|
||||
def _implMakeProseList(self, elements, fmt, with_verb, comma_for_two_elts=False, serial_comma=True):
|
||||
"""Internal-use implementation to make a (comma-separated) list for use in prose.
|
||||
|
||||
Adds a connective (by default, 'and')
|
||||
before the last element if there are more than 1,
|
||||
and only includes commas if there are more than 2
|
||||
(if comma_for_two_elts is False).
|
||||
|
||||
Adds the right one of "is" or "are" to the end if with_verb is true.
|
||||
|
||||
Optionally adds a quantifier (like 'any') before a list of 2 or more,
|
||||
if specified by fmt.
|
||||
|
||||
Do not edit these defaults, override self.makeProseList().
|
||||
"""
|
||||
assert serial_comma # did not implement what we did not need
|
||||
if isinstance(fmt, str):
|
||||
fmt = ProseListFormats.from_string(fmt)
|
||||
|
||||
my_elts = list(elements)
|
||||
if len(my_elts) > 1:
|
||||
my_elts[-1] = '{} {}'.format(fmt.connective, my_elts[-1])
|
||||
|
||||
if not comma_for_two_elts and len(my_elts) <= 2:
|
||||
prose = ' '.join(my_elts)
|
||||
else:
|
||||
prose = ', '.join(my_elts)
|
||||
|
||||
quantifier = fmt.quantifier(len(my_elts))
|
||||
|
||||
parts = [quantifier, prose]
|
||||
|
||||
if with_verb:
|
||||
if len(my_elts) > 1:
|
||||
parts.append(' are')
|
||||
else:
|
||||
parts.append(' is')
|
||||
return ''.join(parts)
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def file_suffix(self):
|
||||
"""Return suffix of generated Asciidoctor files"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abc.abstractmethod
|
||||
def api_name(self, spectype=None):
|
||||
"""Return API or specification name for citations in ref pages.
|
||||
|
||||
spectype is the spec this refpage is for.
|
||||
'api' (the default value) is the main API Specification.
|
||||
If an unrecognized spectype is given, returns None.
|
||||
|
||||
Must implement."""
|
||||
raise NotImplementedError
|
||||
|
||||
def should_insert_may_alias_macro(self, genOpts):
|
||||
"""Return true if we should insert a "may alias" macro in this file.
|
||||
|
||||
Only used by OpenXR right now."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def command_prefix(self):
|
||||
"""Return the expected prefix of commands/functions.
|
||||
|
||||
Implemented in terms of api_prefix."""
|
||||
if not self._command_prefix:
|
||||
self._command_prefix = self.api_prefix[:].replace('_', '').lower()
|
||||
return self._command_prefix
|
||||
|
||||
@property
|
||||
def type_prefix(self):
|
||||
"""Return the expected prefix of type names.
|
||||
|
||||
Implemented in terms of command_prefix (and in turn, api_prefix)."""
|
||||
if not self._type_prefix:
|
||||
self._type_prefix = ''.join(
|
||||
(self.command_prefix[0:1].upper(), self.command_prefix[1:]))
|
||||
return self._type_prefix
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def api_prefix(self):
|
||||
"""Return API token prefix.
|
||||
|
||||
Typically two uppercase letters followed by an underscore.
|
||||
|
||||
Must implement."""
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
def extension_name_prefix(self):
|
||||
"""Return extension name prefix.
|
||||
|
||||
Typically two uppercase letters followed by an underscore.
|
||||
|
||||
Assumed to be the same as api_prefix, but some APIs use different
|
||||
case conventions."""
|
||||
|
||||
return self.api_prefix
|
||||
|
||||
def extension_short_description(self, elem):
|
||||
"""Return a short description of an extension for use in refpages.
|
||||
|
||||
elem is an ElementTree for the <extension> tag in the XML.
|
||||
The default behavior is to use the 'type' field of this tag, but not
|
||||
all APIs support this field."""
|
||||
|
||||
ext_type = elem.get('type')
|
||||
|
||||
if ext_type is not None:
|
||||
return f'{ext_type} extension'
|
||||
else:
|
||||
return ''
|
||||
|
||||
@property
|
||||
def write_contacts(self):
|
||||
"""Return whether contact list should be written to extension appendices"""
|
||||
return False
|
||||
|
||||
@property
|
||||
def write_extension_type(self):
|
||||
"""Return whether extension type should be written to extension appendices"""
|
||||
return True
|
||||
|
||||
@property
|
||||
def write_extension_number(self):
|
||||
"""Return whether extension number should be written to extension appendices"""
|
||||
return True
|
||||
|
||||
@property
|
||||
def write_extension_revision(self):
|
||||
"""Return whether extension revision number should be written to extension appendices"""
|
||||
return True
|
||||
|
||||
@property
|
||||
def write_refpage_include(self):
|
||||
"""Return whether refpage include should be written to extension appendices"""
|
||||
return True
|
||||
|
||||
@property
|
||||
def api_version_prefix(self):
|
||||
"""Return API core version token prefix.
|
||||
|
||||
Implemented in terms of api_prefix.
|
||||
|
||||
May override."""
|
||||
return self.api_prefix + 'VERSION_'
|
||||
|
||||
@property
|
||||
def KHR_prefix(self):
|
||||
"""Return extension name prefix for KHR extensions.
|
||||
|
||||
Implemented in terms of api_prefix.
|
||||
|
||||
May override."""
|
||||
return self.api_prefix + 'KHR_'
|
||||
|
||||
@property
|
||||
def EXT_prefix(self):
|
||||
"""Return extension name prefix for EXT extensions.
|
||||
|
||||
Implemented in terms of api_prefix.
|
||||
|
||||
May override."""
|
||||
return self.api_prefix + 'EXT_'
|
||||
|
||||
def writeFeature(self, featureName, featureExtraProtect, filename):
|
||||
"""Return True if OutputGenerator.endFeature should write this feature.
|
||||
|
||||
Defaults to always True.
|
||||
Used in COutputGenerator.
|
||||
|
||||
May override."""
|
||||
return True
|
||||
|
||||
def requires_error_validation(self, return_type):
|
||||
"""Return True if the return_type element is an API result code
|
||||
requiring error validation.
|
||||
|
||||
Defaults to always False.
|
||||
|
||||
May override."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def required_errors(self):
|
||||
"""Return a list of required error codes for validation.
|
||||
|
||||
Defaults to an empty list.
|
||||
|
||||
May override."""
|
||||
return []
|
||||
|
||||
def is_voidpointer_alias(self, tag, text, tail):
|
||||
"""Return True if the declaration components (tag,text,tail) of an
|
||||
element represents a void * type.
|
||||
|
||||
Defaults to a reasonable implementation.
|
||||
|
||||
May override."""
|
||||
return tag == 'type' and text == 'void' and tail.startswith('*')
|
||||
|
||||
def make_voidpointer_alias(self, tail):
|
||||
"""Reformat a void * declaration to include the API alias macro.
|
||||
|
||||
Defaults to a no-op.
|
||||
|
||||
Must override if you actually want to use this feature in your project."""
|
||||
return tail
|
||||
|
||||
def category_requires_validation(self, category):
|
||||
"""Return True if the given type 'category' always requires validation.
|
||||
|
||||
Defaults to a reasonable implementation.
|
||||
|
||||
May override."""
|
||||
return category in CATEGORIES_REQUIRING_VALIDATION
|
||||
|
||||
def type_always_valid(self, typename):
|
||||
"""Return True if the given type name is always valid (never requires validation).
|
||||
|
||||
This is for things like integers.
|
||||
|
||||
Defaults to a reasonable implementation.
|
||||
|
||||
May override."""
|
||||
return typename in TYPES_KNOWN_ALWAYS_VALID
|
||||
|
||||
@property
|
||||
def should_skip_checking_codes(self):
|
||||
"""Return True if more than the basic validation of return codes should
|
||||
be skipped for a command."""
|
||||
|
||||
return False
|
||||
|
||||
@property
|
||||
def generate_index_terms(self):
|
||||
"""Return True if asiidoctor index terms should be generated as part
|
||||
of an API interface from the docgenerator."""
|
||||
|
||||
return False
|
||||
|
||||
@property
|
||||
def generate_enum_table(self):
|
||||
"""Return True if asciidoctor tables describing enumerants in a
|
||||
group should be generated as part of group generation."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def generate_max_enum_in_docs(self):
|
||||
"""Return True if MAX_ENUM tokens should be generated in
|
||||
documentation includes."""
|
||||
return False
|
||||
|
||||
def extension_name_split(self, name):
|
||||
"""Split an extension name, returning (vendor, rest of name).
|
||||
The API prefix of the name is ignored."""
|
||||
|
||||
match = EXT_NAME_DECOMPOSE_RE.match(name)
|
||||
vendor = match.group('vendor')
|
||||
bare_name = match.group('name')
|
||||
|
||||
return (vendor, bare_name)
|
||||
|
||||
@abc.abstractmethod
|
||||
def extension_file_path(self, name):
|
||||
"""Return file path to an extension appendix relative to a directory
|
||||
containing all such appendices.
|
||||
- name - extension name
|
||||
|
||||
Must implement."""
|
||||
raise NotImplementedError
|
||||
|
||||
def extension_include_string(self, name):
|
||||
"""Return format string for include:: line for an extension appendix
|
||||
file.
|
||||
- name - extension name"""
|
||||
|
||||
return 'include::{{appendices}}/{}[]'.format(
|
||||
self.extension_file_path(name))
|
||||
|
||||
@property
|
||||
def provisional_extension_warning(self):
|
||||
"""Return True if a warning should be included in extension
|
||||
appendices for provisional extensions."""
|
||||
return True
|
||||
|
||||
@property
|
||||
def generated_include_path(self):
|
||||
"""Return path relative to the generated reference pages, to the
|
||||
generated API include files."""
|
||||
|
||||
return '{generated}'
|
||||
|
||||
@property
|
||||
def include_extension_appendix_in_refpage(self):
|
||||
"""Return True if generating extension refpages by embedding
|
||||
extension appendix content (default), False otherwise
|
||||
(OpenXR)."""
|
||||
|
||||
return True
|
||||
|
||||
def valid_flag_bit(self, bitpos):
|
||||
"""Return True if bitpos is an allowed numeric bit position for
|
||||
an API flag.
|
||||
|
||||
Behavior depends on the data type used for flags (which may be 32
|
||||
or 64 bits), and may depend on assumptions about compiler
|
||||
handling of sign bits in enumerated types, as well."""
|
||||
return True
|
||||
|
||||
@property
|
||||
def duplicate_aliased_structs(self):
|
||||
"""
|
||||
Should aliased structs have the original struct definition listed in the
|
||||
generated docs snippet?
|
||||
"""
|
||||
return False
|
||||
|
||||
@property
|
||||
def protectProtoComment(self):
|
||||
"""Return True if generated #endif should have a comment matching
|
||||
the protection symbol used in the opening #ifdef/#ifndef."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def extra_refpage_headers(self):
|
||||
"""Return any extra headers (preceding the title) for generated
|
||||
reference pages."""
|
||||
return ''
|
||||
|
||||
@property
|
||||
def extra_refpage_body(self):
|
||||
"""Return any extra text (following the title) for generated
|
||||
reference pages."""
|
||||
return ''
|
||||
|
||||
def is_api_version_name(self, name):
|
||||
"""Return True if name is an API version name."""
|
||||
|
||||
return API_VERSION_NAME_RE.match(name) is not None
|
||||
|
||||
@property
|
||||
def docgen_language(self):
|
||||
"""Return the language to be used in docgenerator [source]
|
||||
blocks."""
|
||||
|
||||
return 'c++'
|
||||
|
||||
@property
|
||||
def docgen_source_options(self):
|
||||
"""Return block options to be used in docgenerator [source] blocks,
|
||||
which are appended to the 'source' block type.
|
||||
Can be empty."""
|
||||
|
||||
return '%unbreakable'
|
||||
58
externals/vulkan-headers/registry/spec_tools/util.py
vendored
Normal file
58
externals/vulkan-headers/registry/spec_tools/util.py
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
"""Utility functions not closely tied to other spec_tools types."""
|
||||
# Copyright (c) 2018-2019 Collabora, Ltd.
|
||||
# Copyright 2013-2024 The Khronos Group Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
|
||||
def getElemName(elem, default=None):
|
||||
"""Get the name associated with an element, either a name child or name attribute."""
|
||||
name_elem = elem.find('name')
|
||||
if name_elem is not None:
|
||||
return name_elem.text
|
||||
# Fallback if there is no child.
|
||||
return elem.get('name', default)
|
||||
|
||||
|
||||
def getElemType(elem, default=None):
|
||||
"""Get the type associated with an element, either a type child or type attribute."""
|
||||
type_elem = elem.find('type')
|
||||
if type_elem is not None:
|
||||
return type_elem.text
|
||||
# Fallback if there is no child.
|
||||
return elem.get('type', default)
|
||||
|
||||
|
||||
def findFirstWithPredicate(collection, pred):
|
||||
"""Return the first element that satisfies the predicate, or None if none exist.
|
||||
|
||||
NOTE: Some places where this is used might be better served by changing to a dictionary.
|
||||
"""
|
||||
for elt in collection:
|
||||
if pred(elt):
|
||||
return elt
|
||||
return None
|
||||
|
||||
|
||||
def findNamedElem(elems, name):
|
||||
"""Traverse a collection of elements with 'name' nodes or attributes, looking for and returning one with the right name.
|
||||
|
||||
NOTE: Many places where this is used might be better served by changing to a dictionary.
|
||||
"""
|
||||
return findFirstWithPredicate(elems, lambda elem: getElemName(elem) == name)
|
||||
|
||||
|
||||
def findTypedElem(elems, typename):
|
||||
"""Traverse a collection of elements with 'type' nodes or attributes, looking for and returning one with the right typename.
|
||||
|
||||
NOTE: Many places where this is used might be better served by changing to a dictionary.
|
||||
"""
|
||||
return findFirstWithPredicate(elems, lambda elem: getElemType(elem) == typename)
|
||||
|
||||
|
||||
def findNamedObject(collection, name):
|
||||
"""Traverse a collection of elements with 'name' attributes, looking for and returning one with the right name.
|
||||
|
||||
NOTE: Many places where this is used might be better served by changing to a dictionary.
|
||||
"""
|
||||
return findFirstWithPredicate(collection, lambda elt: elt.name == name)
|
||||
42
externals/vulkan-headers/registry/stripAPI.py
vendored
Normal file
42
externals/vulkan-headers/registry/stripAPI.py
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2023-2024 The Khronos Group Inc.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import argparse
|
||||
import xml.etree.ElementTree as etree
|
||||
from reg import stripNonmatchingAPIs
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(prog='stripAPI',
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description='''\
|
||||
Filters out elements with non-matching explicit 'api' attributes from API XML.
|
||||
To remove Vulkan SC-only elements from the combined API XML:
|
||||
python3 scripts/stripAPI.py -input xml/vk.xml -output vulkan-only.xml -keepAPI vulkan
|
||||
To remove Vulkan-only elements:
|
||||
python3 scripts/stripAPI.py -input xml/vk.xml -output vulkansc-only.xml -keepAPI vulkansc
|
||||
If you are parsing the XML yourself but using the xml.etree package, the
|
||||
equivalent runtime code is:
|
||||
import reg
|
||||
reg.stripNonmatchingAPIs(tree.getroot(), keepAPI, actuallyDelete=True)
|
||||
where 'tree' is an ElementTree created from the XML file using
|
||||
etree.parse(filename)''')
|
||||
|
||||
parser.add_argument('-input', action='store',
|
||||
required=True,
|
||||
help='Specify input registry XML')
|
||||
parser.add_argument('-output', action='store',
|
||||
required=True,
|
||||
help='Specify output registry XML')
|
||||
parser.add_argument('-keepAPI', action='store',
|
||||
default=None,
|
||||
help='Specify API name whose \'api\' tags are kept')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
tree = etree.parse(args.input)
|
||||
if args.keepAPI is not None:
|
||||
stripNonmatchingAPIs(tree.getroot(), args.keepAPI, actuallyDelete = True)
|
||||
tree.write(args.output)
|
||||
|
||||
101830
externals/vulkan-headers/registry/validusage.json
vendored
Normal file
101830
externals/vulkan-headers/registry/validusage.json
vendored
Normal file
File diff suppressed because one or more lines are too long
1703
externals/vulkan-headers/registry/video.xml
vendored
Normal file
1703
externals/vulkan-headers/registry/video.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
27229
externals/vulkan-headers/registry/vk.xml
vendored
Normal file
27229
externals/vulkan-headers/registry/vk.xml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
311
externals/vulkan-headers/registry/vkconventions.py
vendored
Normal file
311
externals/vulkan-headers/registry/vkconventions.py
vendored
Normal file
@@ -0,0 +1,311 @@
|
||||
#!/usr/bin/env python3 -i
|
||||
#
|
||||
# Copyright 2013-2024 The Khronos Group Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Working-group-specific style conventions,
|
||||
# used in generation.
|
||||
|
||||
import re
|
||||
import os
|
||||
|
||||
from spec_tools.conventions import ConventionsBase
|
||||
|
||||
# Modified from default implementation - see category_requires_validation() below
|
||||
CATEGORIES_REQUIRING_VALIDATION = set(('handle', 'enum', 'bitmask'))
|
||||
|
||||
# Tokenize into "words" for structure types, approximately per spec "Implicit Valid Usage" section 2.7.2
|
||||
# This first set is for things we recognize explicitly as words,
|
||||
# as exceptions to the general regex.
|
||||
# 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
|
||||
'D3D12', # VkD3D12FenceSubmitInfoKHR
|
||||
'Float16', # VkPhysicalDeviceShaderFloat16Int8FeaturesKHR
|
||||
'ImagePipe', # VkImagePipeSurfaceCreateInfoFUCHSIA
|
||||
'Int64', # VkPhysicalDeviceShaderAtomicInt64FeaturesKHR
|
||||
'Int8', # VkPhysicalDeviceShaderFloat16Int8FeaturesKHR
|
||||
'MacOS', # VkMacOSSurfaceCreateInfoMVK
|
||||
'RGBA10X6', # VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT
|
||||
'Uint8', # VkPhysicalDeviceIndexTypeUint8FeaturesEXT
|
||||
'Win32', # VkWin32SurfaceCreateInfoKHR
|
||||
))
|
||||
# A regex to match any of the SPECIAL_WORDS
|
||||
EXCEPTION_PATTERN = r'(?P<exception>{})'.format(
|
||||
'|'.join('(%s)' % re.escape(w) for w in SPECIAL_WORDS))
|
||||
MAIN_RE = re.compile(
|
||||
# the negative lookahead is to prevent the all-caps pattern from being too greedy.
|
||||
r'({}|([0-9]+)|([A-Z][a-z]+)|([A-Z][A-Z]*(?![a-z])))'.format(EXCEPTION_PATTERN))
|
||||
|
||||
|
||||
class VulkanConventions(ConventionsBase):
|
||||
@property
|
||||
def null(self):
|
||||
"""Preferred spelling of NULL."""
|
||||
return '`NULL`'
|
||||
|
||||
def formatVersion(self, name, apivariant, major, minor):
|
||||
"""Mark up an API version name as a link in the spec."""
|
||||
version = f'{major}.{minor}'
|
||||
if apivariant == 'VKSC':
|
||||
# Vulkan SC has a different anchor pattern for version appendices
|
||||
if version == '1.0':
|
||||
return 'Vulkan SC 1.0'
|
||||
else:
|
||||
return f'<<versions-sc-{version}, Vulkan SC Version {version}>>'
|
||||
else:
|
||||
return f'<<versions-{version}, Vulkan Version {version}>>'
|
||||
|
||||
def formatExtension(self, name):
|
||||
"""Mark up an extension name as a link in the spec."""
|
||||
return f'apiext:{name}'
|
||||
|
||||
@property
|
||||
def struct_macro(self):
|
||||
"""Get the appropriate format macro for a structure.
|
||||
|
||||
Primarily affects generated valid usage statements.
|
||||
"""
|
||||
|
||||
return 'slink:'
|
||||
|
||||
@property
|
||||
def constFlagBits(self):
|
||||
"""Returns True if static const flag bits should be generated, False if an enumerated type should be generated."""
|
||||
return False
|
||||
|
||||
@property
|
||||
def structtype_member_name(self):
|
||||
"""Return name of the structure type member"""
|
||||
return 'sType'
|
||||
|
||||
@property
|
||||
def nextpointer_member_name(self):
|
||||
"""Return name of the structure pointer chain member"""
|
||||
return 'pNext'
|
||||
|
||||
@property
|
||||
def valid_pointer_prefix(self):
|
||||
"""Return prefix to pointers which must themselves be valid"""
|
||||
return 'valid'
|
||||
|
||||
def is_structure_type_member(self, paramtype, paramname):
|
||||
"""Determine if member type and name match the structure type member."""
|
||||
return paramtype == 'VkStructureType' and paramname == self.structtype_member_name
|
||||
|
||||
def is_nextpointer_member(self, paramtype, paramname):
|
||||
"""Determine if member type and name match the next pointer chain member."""
|
||||
return paramtype == 'void' and paramname == self.nextpointer_member_name
|
||||
|
||||
def generate_structure_type_from_name(self, structname):
|
||||
"""Generate a structure type name, like VK_STRUCTURE_TYPE_CREATE_INSTANCE_INFO"""
|
||||
|
||||
structure_type_parts = []
|
||||
# Tokenize into "words"
|
||||
for elem in MAIN_RE.findall(structname):
|
||||
word = elem[0]
|
||||
if word == 'Vk':
|
||||
structure_type_parts.append('VK_STRUCTURE_TYPE')
|
||||
else:
|
||||
structure_type_parts.append(word.upper())
|
||||
name = '_'.join(structure_type_parts)
|
||||
|
||||
# The simple-minded rules need modification for some structure names
|
||||
subpats = [
|
||||
[ r'_H_(26[45])_', r'_H\1_' ],
|
||||
[ r'_AV_1_', r'_AV1_' ],
|
||||
[ r'_VULKAN_([0-9])([0-9])_', r'_VULKAN_\1_\2_' ],
|
||||
[ r'_VULKAN_SC_([0-9])([0-9])_',r'_VULKAN_SC_\1_\2_' ],
|
||||
[ r'_DIRECT_FB_', r'_DIRECTFB_' ],
|
||||
[ r'_VULKAN_SC_10', r'_VULKAN_SC_1_0' ],
|
||||
|
||||
]
|
||||
|
||||
for subpat in subpats:
|
||||
name = re.sub(subpat[0], subpat[1], name)
|
||||
return name
|
||||
|
||||
@property
|
||||
def warning_comment(self):
|
||||
"""Return warning comment to be placed in header of generated Asciidoctor files"""
|
||||
return '// WARNING: DO NOT MODIFY! This file is automatically generated from the vk.xml registry'
|
||||
|
||||
@property
|
||||
def file_suffix(self):
|
||||
"""Return suffix of generated Asciidoctor files"""
|
||||
return '.adoc'
|
||||
|
||||
def api_name(self, spectype='api'):
|
||||
"""Return API or specification name for citations in ref pages.ref
|
||||
pages should link to for
|
||||
|
||||
spectype is the spec this refpage is for: 'api' is the Vulkan API
|
||||
Specification. Defaults to 'api'. If an unrecognized spectype is
|
||||
given, returns None.
|
||||
"""
|
||||
if spectype == 'api' or spectype is None:
|
||||
return 'Vulkan'
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def api_prefix(self):
|
||||
"""Return API token prefix"""
|
||||
return 'VK_'
|
||||
|
||||
@property
|
||||
def write_contacts(self):
|
||||
"""Return whether contact list should be written to extension appendices"""
|
||||
return True
|
||||
|
||||
@property
|
||||
def write_refpage_include(self):
|
||||
"""Return whether refpage include should be written to extension appendices"""
|
||||
return True
|
||||
|
||||
@property
|
||||
def member_used_for_unique_vuid(self):
|
||||
"""Return the member name used in the VUID-...-...-unique ID."""
|
||||
return self.structtype_member_name
|
||||
|
||||
def is_externsync_command(self, protoname):
|
||||
"""Returns True if the protoname element is an API command requiring
|
||||
external synchronization
|
||||
"""
|
||||
return protoname is not None and 'vkCmd' in protoname
|
||||
|
||||
def is_api_name(self, name):
|
||||
"""Returns True if name is in the reserved API namespace.
|
||||
For Vulkan, these are names with a case-insensitive 'vk' prefix, or
|
||||
a 'PFN_vk' function pointer type prefix.
|
||||
"""
|
||||
return name[0:2].lower() == 'vk' or name[0:6] == 'PFN_vk'
|
||||
|
||||
def specURL(self, spectype='api'):
|
||||
"""Return public registry URL which ref pages should link to for the
|
||||
current all-extensions HTML specification, so xrefs in the
|
||||
asciidoc source that are not to ref pages can link into it
|
||||
instead. N.b. this may need to change on a per-refpage basis if
|
||||
there are multiple documents involved.
|
||||
"""
|
||||
return 'https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html'
|
||||
|
||||
@property
|
||||
def xml_api_name(self):
|
||||
"""Return the name used in the default API XML registry for the default API"""
|
||||
return 'vulkan'
|
||||
|
||||
@property
|
||||
def registry_path(self):
|
||||
"""Return relpath to the default API XML registry in this project."""
|
||||
return 'xml/vk.xml'
|
||||
|
||||
@property
|
||||
def specification_path(self):
|
||||
"""Return relpath to the Asciidoctor specification sources in this project."""
|
||||
return '{generated}/meta'
|
||||
|
||||
@property
|
||||
def special_use_section_anchor(self):
|
||||
"""Return asciidoctor anchor name in the API Specification of the
|
||||
section describing extension special uses in detail."""
|
||||
return 'extendingvulkan-compatibility-specialuse'
|
||||
|
||||
@property
|
||||
def extension_index_prefixes(self):
|
||||
"""Return a list of extension prefixes used to group extension refpages."""
|
||||
return ['VK_KHR', 'VK_EXT', 'VK']
|
||||
|
||||
@property
|
||||
def unified_flag_refpages(self):
|
||||
"""Return True if Flags/FlagBits refpages are unified, False if
|
||||
they are separate.
|
||||
"""
|
||||
return False
|
||||
|
||||
@property
|
||||
def spec_reflow_path(self):
|
||||
"""Return the path to the spec source folder to reflow"""
|
||||
return os.getcwd()
|
||||
|
||||
@property
|
||||
def spec_no_reflow_dirs(self):
|
||||
"""Return a set of directories not to automatically descend into
|
||||
when reflowing spec text
|
||||
"""
|
||||
return ('scripts', 'style')
|
||||
|
||||
@property
|
||||
def zero(self):
|
||||
return '`0`'
|
||||
|
||||
def category_requires_validation(self, category):
|
||||
"""Return True if the given type 'category' always requires validation.
|
||||
|
||||
Overridden because Vulkan does not require "valid" text for basetype
|
||||
in the spec right now."""
|
||||
return category in CATEGORIES_REQUIRING_VALIDATION
|
||||
|
||||
@property
|
||||
def should_skip_checking_codes(self):
|
||||
"""Return True if more than the basic validation of return codes should
|
||||
be skipped for a command.
|
||||
|
||||
Vulkan mostly relies on the validation layers rather than API
|
||||
builtin error checking, so these checks are not appropriate.
|
||||
|
||||
For example, passing in a VkFormat parameter will not potentially
|
||||
generate a VK_ERROR_FORMAT_NOT_SUPPORTED code."""
|
||||
|
||||
return True
|
||||
|
||||
def extension_file_path(self, name):
|
||||
"""Return file path to an extension appendix relative to a directory
|
||||
containing all such appendices.
|
||||
- name - extension name"""
|
||||
|
||||
return f'{name}{self.file_suffix}'
|
||||
|
||||
def valid_flag_bit(self, bitpos):
|
||||
"""Return True if bitpos is an allowed numeric bit position for
|
||||
an API flag bit.
|
||||
|
||||
Vulkan uses 32 bit Vk*Flags types, and assumes C compilers may
|
||||
cause Vk*FlagBits values with bit 31 set to result in a 64 bit
|
||||
enumerated type, so disallows such flags."""
|
||||
return bitpos >= 0 and bitpos < 31
|
||||
|
||||
@property
|
||||
def extra_refpage_headers(self):
|
||||
"""Return any extra text to add to refpage headers."""
|
||||
return 'include::{config}/attribs.adoc[]'
|
||||
|
||||
@property
|
||||
def extra_refpage_body(self):
|
||||
"""Return any extra text (following the title) for generated
|
||||
reference pages."""
|
||||
return 'include::{generated}/specattribs.adoc[]'
|
||||
|
||||
|
||||
class VulkanSCConventions(VulkanConventions):
|
||||
|
||||
def specURL(self, spectype='api'):
|
||||
"""Return public registry URL which ref pages should link to for the
|
||||
current all-extensions HTML specification, so xrefs in the
|
||||
asciidoc source that are not to ref pages can link into it
|
||||
instead. N.b. this may need to change on a per-refpage basis if
|
||||
there are multiple documents involved.
|
||||
"""
|
||||
return 'https://registry.khronos.org/vulkansc/specs/1.0-extensions/html/vkspec.html'
|
||||
|
||||
@property
|
||||
def xml_api_name(self):
|
||||
"""Return the name used in the default API XML registry for the default API"""
|
||||
return 'vulkansc'
|
||||
|
||||
Reference in New Issue
Block a user