add vulkan-headers 1.2.189

This commit is contained in:
alexey.lysiuk 2021-09-08 10:44:44 +03:00
parent 17e9462881
commit d598f9cf3b
42 changed files with 65421 additions and 0 deletions

View file

@ -0,0 +1,420 @@
#!/usr/bin/python3 -i
#
# Copyright 2013-2021 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0
import os
import re
from generator import (GeneratorOptions, 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,
apicall='',
apientry='',
apientryp='',
indentFuncProto=True,
indentFuncPointer=False,
alignFuncParam=0,
genEnumBeginEndRange=False,
genAliasMacro=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
- 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)
- 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.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.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)
# C-specific
#
# Multiple inclusion protection & C++ wrappers.
if 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
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're only
# printed in endFeature().
self.sections = {section: [] for section in self.ALL_SECTIONS}
self.feature_not_empty = False
def endFeature(self):
"Actually write the interface to the output file."
# C-specific
if self.emit:
if self.feature_not_empty:
if self.genOpts.conventions.writeFeature(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()
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)
write('\n'.join(self.sections['command']), end='', file=self.outFile)
if self.genOpts.protectProto:
write('#endif', file=self.outFile)
else:
self.newline()
if self.featureExtraProtect is not None:
write('#endif /*', self.featureExtraProtect, '*/', file=self.outFile)
if self.genOpts.protectFeature:
write('#endif /*', self.featureName, '*/', file=self.outFile)
# Finish processing in superclass
OutputGenerator.endFeature(self)
def appendSection(self, section, text):
"Append a definition to the specified section"
# self.sections[section].append('SECTION: ' + section + '\n')
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:
# 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, don't emit it.
body = noneStr(typeElem.text)
for elem in typeElem:
if elem.tag == 'apientry':
body += self.genOpts.apientry + noneStr(elem.tail)
else:
body += noneStr(elem.text) + noneStr(elem.tail)
if body:
# Add extra newline after multi-line entries.
if '\n' in body[0:-1]:
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 OpenXR 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:
# First time we've asked if a type may alias.
# So, let's 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.
parent_structs = (otherType.elem.get('parentstruct')
for otherType in self.registry.typedict.values())
self.may_alias.update(set(x for x in parent_structs
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)
typeElem = typeinfo.elem
if alias:
body = 'typedef ' + alias + ' ' + typeName + ';\n'
else:
body = ''
(protect_begin, protect_end) = self.genProtectString(typeElem.get('protect'))
if protect_begin:
body += protect_begin
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.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:
(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)."""
OutputGenerator.genEnum(self, enuminfo, name, alias)
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 = ''
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;

View file

@ -0,0 +1,358 @@
#!/usr/bin/python3 -i
#
# Copyright 2013-2021 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
# 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',
'int32_t', 'uint32_t',
'int64_t', 'uint64_t',
'size_t',
'uintptr_t',
'int',
))
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
return None
@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:
"""WG-specific conventions."""
def __init__(self):
self._command_prefix = None
self._type_prefix = None
def formatExtension(self, name):
"""Mark up an extension name as a link the spec."""
return '`apiext:{}`'.format(name)
@property
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:'
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.
Don't edit these defaults, override self.makeProseList().
"""
assert(serial_comma) # didn't implement what we didn't 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
def file_suffix(self):
"""Return suffix of generated Asciidoctor files"""
raise NotImplementedError
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
def api_prefix(self):
"""Return API token prefix.
Typically two uppercase letters followed by an underscore.
Must implement."""
raise NotImplementedError
@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, 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_include_string(self, ext):
"""Return format string for include:: line for an extension appendix
file. ext is an object with the following members:
- name - extension string string
- vendor - vendor portion of name
- barename - remainder of name
Must implement."""
raise NotImplementedError
@property
def refpage_generated_include_path(self):
"""Return path relative to the generated reference pages, to the
generated API include files.
Must implement."""
raise NotImplementedError
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

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,671 @@
#!/usr/bin/python3
#
# Copyright 2013-2021 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0
import argparse
import pdb
import re
import sys
import time
import xml.etree.ElementTree as etree
from cgenerator import CGeneratorOptions, COutputGenerator
from docgenerator import DocGeneratorOptions, DocOutputGenerator
from extensionmetadocgenerator import (ExtensionMetaDocGeneratorOptions,
ExtensionMetaDocOutputGenerator)
from interfacedocgenerator import InterfaceDocGenerator
from generator import write
from spirvcapgenerator import SpirvCapabilityOutputGenerator
from hostsyncgenerator import HostSynchronizationOutputGenerator
from pygenerator import PyOutputGenerator
from reflib import logDiag, logWarn, setLogFile
from reg import Registry
from validitygenerator import ValidityOutputGenerator
from vkconventions import VulkanConventions
# Simple timer functions
startTime = None
def startTimer(timeit):
global startTime
if timeit:
startTime = time.process_time()
def endTimer(timeit, msg):
global startTime
if timeit:
endTime = time.process_time()
logDiag(msg, endTime - startTime)
startTime = None
def makeREstring(strings, default=None, strings_are_regex=False):
"""Turn a list of strings into a regexp string matching exactly those strings."""
if strings or default is None:
if not strings_are_regex:
strings = (re.escape(s) for s in strings)
return '^(' + '|'.join(strings) + ')$'
return default
def makeGenOpts(args):
"""Returns a directory of [ generator function, generator options ] indexed
by specified short names. The generator options incorporate the following
parameters:
args is an parsed argument object; see below for the fields that are used."""
global genOpts
genOpts = {}
# Default class of extensions to include, or None
defaultExtensions = args.defaultExtensions
# Additional extensions to include (list of extensions)
extensions = args.extension
# Extensions to remove (list of extensions)
removeExtensions = args.removeExtensions
# Extensions to emit (list of extensions)
emitExtensions = args.emitExtensions
# SPIR-V capabilities / features to emit (list of extensions & capabilities)
emitSpirv = args.emitSpirv
# Features to include (list of features)
features = args.feature
# Whether to disable inclusion protect in headers
protect = args.protect
# Output target directory
directory = args.directory
# Path to generated files, particularly api.py
genpath = args.genpath
# Generate MISRA C-friendly headers
misracstyle = args.misracstyle;
# Generate MISRA C++-friendly headers
misracppstyle = args.misracppstyle;
# Descriptive names for various regexp patterns used to select
# versions and extensions
allSpirv = allFeatures = allExtensions = r'.*'
# Turn lists of names/patterns into matching regular expressions
addExtensionsPat = makeREstring(extensions, None)
removeExtensionsPat = makeREstring(removeExtensions, None)
emitExtensionsPat = makeREstring(emitExtensions, allExtensions)
emitSpirvPat = makeREstring(emitSpirv, allSpirv)
featuresPat = makeREstring(features, allFeatures)
# Copyright text prefixing all headers (list of strings).
# The SPDX formatting below works around constraints of the 'reuse' tool
prefixStrings = [
'/*',
'** Copyright 2015-2021 The Khronos Group Inc.',
'**',
'** SPDX' + '-License-Identifier: Apache-2.0',
'*/',
''
]
# Text specific to Vulkan headers
vkPrefixStrings = [
'/*',
'** This header is generated from the Khronos Vulkan XML API Registry.',
'**',
'*/',
''
]
# Defaults for generating re-inclusion protection wrappers (or not)
protectFile = protect
# An API style conventions object
conventions = VulkanConventions()
# API include files for spec and ref pages
# Overwrites include subdirectories in spec source tree
# The generated include files do not include the calling convention
# macros (apientry etc.), unlike the header files.
# Because the 1.0 core branch includes ref pages for extensions,
# all the extension interfaces need to be generated, even though
# none are used by the core spec itself.
genOpts['apiinc'] = [
DocOutputGenerator,
DocGeneratorOptions(
conventions = conventions,
filename = 'timeMarker',
directory = directory,
genpath = genpath,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
emitversions = featuresPat,
defaultExtensions = None,
addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat,
prefixText = prefixStrings + vkPrefixStrings,
apicall = '',
apientry = '',
apientryp = '*',
alignFuncParam = 48,
expandEnumerants = False)
]
# Python representation of API information, used by scripts that
# don't need to load the full XML.
genOpts['api.py'] = [
PyOutputGenerator,
DocGeneratorOptions(
conventions = conventions,
filename = 'api.py',
directory = directory,
genpath = None,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
emitversions = featuresPat,
defaultExtensions = None,
addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat,
reparentEnums = False)
]
# API validity files for spec
genOpts['validinc'] = [
ValidityOutputGenerator,
DocGeneratorOptions(
conventions = conventions,
filename = 'timeMarker',
directory = directory,
genpath = None,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
emitversions = featuresPat,
defaultExtensions = None,
addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat)
]
# API host sync table files for spec
genOpts['hostsyncinc'] = [
HostSynchronizationOutputGenerator,
DocGeneratorOptions(
conventions = conventions,
filename = 'timeMarker',
directory = directory,
genpath = None,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
emitversions = featuresPat,
defaultExtensions = None,
addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat,
reparentEnums = False)
]
# Extension metainformation for spec extension appendices
# Includes all extensions by default, but only so that the generated
# 'promoted_extensions_*' files refer to all extensions that were
# promoted to a core version.
genOpts['extinc'] = [
ExtensionMetaDocOutputGenerator,
ExtensionMetaDocGeneratorOptions(
conventions = conventions,
filename = 'timeMarker',
directory = directory,
genpath = None,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
emitversions = None,
defaultExtensions = defaultExtensions,
addExtensions = addExtensionsPat,
removeExtensions = None,
emitExtensions = emitExtensionsPat)
]
# Version and extension interface docs for version/extension appendices
# Includes all extensions by default.
genOpts['interfaceinc'] = [
InterfaceDocGenerator,
DocGeneratorOptions(
conventions = conventions,
filename = 'timeMarker',
directory = directory,
genpath = None,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
emitversions = featuresPat,
defaultExtensions = None,
addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat,
reparentEnums = False)
]
genOpts['spirvcapinc'] = [
SpirvCapabilityOutputGenerator,
DocGeneratorOptions(
conventions = conventions,
filename = 'timeMarker',
directory = directory,
genpath = None,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
emitversions = featuresPat,
defaultExtensions = None,
addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat,
emitSpirv = emitSpirvPat,
reparentEnums = False)
]
# Platform extensions, in their own header files
# Each element of the platforms[] array defines information for
# generating a single platform:
# [0] is the generated header file name
# [1] is the set of platform extensions to generate
# [2] is additional extensions whose interfaces should be considered,
# but suppressed in the output, to avoid duplicate definitions of
# dependent types like VkDisplayKHR and VkSurfaceKHR which come from
# non-platform extensions.
# Track all platform extensions, for exclusion from vulkan_core.h
allPlatformExtensions = []
# Extensions suppressed for all WSI platforms (WSI extensions required
# by all platforms)
commonSuppressExtensions = [ 'VK_KHR_display', 'VK_KHR_swapchain' ]
# Extensions required and suppressed for beta "platform". This can
# probably eventually be derived from the requires= attributes of
# the extension blocks.
betaRequireExtensions = [
'VK_KHR_portability_subset',
'VK_KHR_video_queue',
'VK_KHR_video_decode_queue',
'VK_KHR_video_encode_queue',
'VK_EXT_video_decode_h264',
'VK_EXT_video_decode_h265',
'VK_EXT_video_encode_h264',
]
betaSuppressExtensions = []
platforms = [
[ 'vulkan_android.h', [ 'VK_KHR_android_surface',
'VK_ANDROID_external_memory_android_hardware_buffer'
], commonSuppressExtensions ],
[ 'vulkan_fuchsia.h', [ 'VK_FUCHSIA_imagepipe_surface',
'VK_FUCHSIA_external_memory',
'VK_FUCHSIA_external_semaphore' ], commonSuppressExtensions ],
[ 'vulkan_ggp.h', [ 'VK_GGP_stream_descriptor_surface',
'VK_GGP_frame_token' ], commonSuppressExtensions ],
[ 'vulkan_ios.h', [ 'VK_MVK_ios_surface' ], commonSuppressExtensions ],
[ 'vulkan_macos.h', [ 'VK_MVK_macos_surface' ], commonSuppressExtensions ],
[ 'vulkan_vi.h', [ 'VK_NN_vi_surface' ], commonSuppressExtensions ],
[ 'vulkan_wayland.h', [ 'VK_KHR_wayland_surface' ], commonSuppressExtensions ],
[ 'vulkan_win32.h', [ 'VK_.*_win32(|_.*)', 'VK_EXT_full_screen_exclusive' ],
commonSuppressExtensions +
[ 'VK_KHR_external_semaphore',
'VK_KHR_external_memory_capabilities',
'VK_KHR_external_fence',
'VK_KHR_external_fence_capabilities',
'VK_KHR_get_surface_capabilities2',
'VK_NV_external_memory_capabilities',
] ],
[ 'vulkan_xcb.h', [ 'VK_KHR_xcb_surface' ], commonSuppressExtensions ],
[ 'vulkan_xlib.h', [ 'VK_KHR_xlib_surface' ], commonSuppressExtensions ],
[ 'vulkan_directfb.h', [ 'VK_EXT_directfb_surface' ], commonSuppressExtensions ],
[ 'vulkan_xlib_xrandr.h', [ 'VK_EXT_acquire_xlib_display' ], commonSuppressExtensions ],
[ 'vulkan_metal.h', [ 'VK_EXT_metal_surface' ], commonSuppressExtensions ],
[ 'vulkan_screen.h', [ 'VK_QNX_screen_surface' ], commonSuppressExtensions ],
[ 'vulkan_beta.h', betaRequireExtensions, betaSuppressExtensions ],
]
for platform in platforms:
headername = platform[0]
allPlatformExtensions += platform[1]
addPlatformExtensionsRE = makeREstring(
platform[1] + platform[2], strings_are_regex=True)
emitPlatformExtensionsRE = makeREstring(
platform[1], strings_are_regex=True)
opts = CGeneratorOptions(
conventions = conventions,
filename = headername,
directory = directory,
genpath = None,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
emitversions = None,
defaultExtensions = None,
addExtensions = addPlatformExtensionsRE,
removeExtensions = None,
emitExtensions = emitPlatformExtensionsRE,
prefixText = prefixStrings + vkPrefixStrings,
genFuncPointers = True,
protectFile = protectFile,
protectFeature = False,
protectProto = '#ifndef',
protectProtoStr = 'VK_NO_PROTOTYPES',
apicall = 'VKAPI_ATTR ',
apientry = 'VKAPI_CALL ',
apientryp = 'VKAPI_PTR *',
alignFuncParam = 48,
misracstyle = misracstyle,
misracppstyle = misracppstyle)
genOpts[headername] = [ COutputGenerator, opts ]
# Header for core API + extensions.
# To generate just the core API,
# change to 'defaultExtensions = None' below.
#
# By default this adds all enabled, non-platform extensions.
# It removes all platform extensions (from the platform headers options
# constructed above) as well as any explicitly specified removals.
removeExtensionsPat = makeREstring(
allPlatformExtensions + removeExtensions, None, strings_are_regex=True)
genOpts['vulkan_core.h'] = [
COutputGenerator,
CGeneratorOptions(
conventions = conventions,
filename = 'vulkan_core.h',
directory = directory,
genpath = None,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
emitversions = featuresPat,
defaultExtensions = defaultExtensions,
addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat,
prefixText = prefixStrings + vkPrefixStrings,
genFuncPointers = True,
protectFile = protectFile,
protectFeature = False,
protectProto = '#ifndef',
protectProtoStr = 'VK_NO_PROTOTYPES',
apicall = 'VKAPI_ATTR ',
apientry = 'VKAPI_CALL ',
apientryp = 'VKAPI_PTR *',
alignFuncParam = 48,
misracstyle = misracstyle,
misracppstyle = misracppstyle)
]
# Unused - vulkan10.h target.
# It is possible to generate a header with just the Vulkan 1.0 +
# extension interfaces defined, but since the promoted KHR extensions
# are now defined in terms of the 1.1 interfaces, such a header is very
# similar to vulkan_core.h.
genOpts['vulkan10.h'] = [
COutputGenerator,
CGeneratorOptions(
conventions = conventions,
filename = 'vulkan10.h',
directory = directory,
genpath = None,
apiname = 'vulkan',
profile = None,
versions = 'VK_VERSION_1_0',
emitversions = 'VK_VERSION_1_0',
defaultExtensions = None,
addExtensions = None,
removeExtensions = None,
emitExtensions = None,
prefixText = prefixStrings + vkPrefixStrings,
genFuncPointers = True,
protectFile = protectFile,
protectFeature = False,
protectProto = '#ifndef',
protectProtoStr = 'VK_NO_PROTOTYPES',
apicall = 'VKAPI_ATTR ',
apientry = 'VKAPI_CALL ',
apientryp = 'VKAPI_PTR *',
alignFuncParam = 48,
misracstyle = misracstyle,
misracppstyle = misracppstyle)
]
# Unused - vulkan11.h target.
# It is possible to generate a header with just the Vulkan 1.0 +
# extension interfaces defined, but since the promoted KHR extensions
# are now defined in terms of the 1.1 interfaces, such a header is very
# similar to vulkan_core.h.
genOpts['vulkan11.h'] = [
COutputGenerator,
CGeneratorOptions(
conventions = conventions,
filename = 'vulkan11.h',
directory = directory,
genpath = None,
apiname = 'vulkan',
profile = None,
versions = '^VK_VERSION_1_[01]$',
emitversions = '^VK_VERSION_1_[01]$',
defaultExtensions = None,
addExtensions = None,
removeExtensions = None,
emitExtensions = None,
prefixText = prefixStrings + vkPrefixStrings,
genFuncPointers = True,
protectFile = protectFile,
protectFeature = False,
protectProto = '#ifndef',
protectProtoStr = 'VK_NO_PROTOTYPES',
apicall = 'VKAPI_ATTR ',
apientry = 'VKAPI_CALL ',
apientryp = 'VKAPI_PTR *',
alignFuncParam = 48,
misracstyle = misracstyle,
misracppstyle = misracppstyle)
]
genOpts['alias.h'] = [
COutputGenerator,
CGeneratorOptions(
conventions = conventions,
filename = 'alias.h',
directory = directory,
genpath = None,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
emitversions = featuresPat,
defaultExtensions = defaultExtensions,
addExtensions = None,
removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat,
prefixText = None,
genFuncPointers = False,
protectFile = False,
protectFeature = False,
protectProto = '',
protectProtoStr = '',
apicall = '',
apientry = '',
apientryp = '',
alignFuncParam = 36)
]
def genTarget(args):
"""Create an API generator and corresponding generator options based on
the requested target and command line options.
This is encapsulated in a function so it can be profiled and/or timed.
The args parameter is an parsed argument object containing the following
fields that are used:
- target - target to generate
- directory - directory to generate it in
- protect - True if re-inclusion wrappers should be created
- extensions - list of additional extensions to include in generated interfaces"""
# Create generator options with parameters specified on command line
makeGenOpts(args)
# pdb.set_trace()
# Select a generator matching the requested target
if args.target in genOpts:
createGenerator = genOpts[args.target][0]
options = genOpts[args.target][1]
logDiag('* Building', options.filename)
logDiag('* options.versions =', options.versions)
logDiag('* options.emitversions =', options.emitversions)
logDiag('* options.defaultExtensions =', options.defaultExtensions)
logDiag('* options.addExtensions =', options.addExtensions)
logDiag('* options.removeExtensions =', options.removeExtensions)
logDiag('* options.emitExtensions =', options.emitExtensions)
gen = createGenerator(errFile=errWarn,
warnFile=errWarn,
diagFile=diag)
return (gen, options)
else:
logErr('No generator options for unknown target:', args.target)
return None
# -feature name
# -extension name
# For both, "name" may be a single name, or a space-separated list
# of names, or a regular expression.
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-defaultExtensions', action='store',
default='vulkan',
help='Specify a single class of extensions to add to targets')
parser.add_argument('-extension', action='append',
default=[],
help='Specify an extension or extensions to add to targets')
parser.add_argument('-removeExtensions', action='append',
default=[],
help='Specify an extension or extensions to remove from targets')
parser.add_argument('-emitExtensions', action='append',
default=[],
help='Specify an extension or extensions to emit in targets')
parser.add_argument('-emitSpirv', action='append',
default=[],
help='Specify a SPIR-V extension or capability to emit in targets')
parser.add_argument('-feature', action='append',
default=[],
help='Specify a core API feature name or names to add to targets')
parser.add_argument('-debug', action='store_true',
help='Enable debugging')
parser.add_argument('-dump', action='store_true',
help='Enable dump to stderr')
parser.add_argument('-diagfile', action='store',
default=None,
help='Write diagnostics to specified file')
parser.add_argument('-errfile', action='store',
default=None,
help='Write errors and warnings to specified file instead of stderr')
parser.add_argument('-noprotect', dest='protect', action='store_false',
help='Disable inclusion protection in output headers')
parser.add_argument('-profile', action='store_true',
help='Enable profiling')
parser.add_argument('-registry', action='store',
default='vk.xml',
help='Use specified registry file instead of vk.xml')
parser.add_argument('-time', action='store_true',
help='Enable timing')
parser.add_argument('-validate', action='store_true',
help='Enable XML group validation')
parser.add_argument('-genpath', action='store', default='gen',
help='Path to generated files')
parser.add_argument('-o', action='store', dest='directory',
default='.',
help='Create target and related files in specified directory')
parser.add_argument('target', metavar='target', nargs='?',
help='Specify target')
parser.add_argument('-quiet', action='store_true', default=True,
help='Suppress script output during normal execution.')
parser.add_argument('-verbose', action='store_false', dest='quiet', default=True,
help='Enable script output during normal execution.')
parser.add_argument('-misracstyle', dest='misracstyle', action='store_true',
help='generate MISRA C-friendly headers')
parser.add_argument('-misracppstyle', dest='misracppstyle', action='store_true',
help='generate MISRA C++-friendly headers')
args = parser.parse_args()
# This splits arguments which are space-separated lists
args.feature = [name for arg in args.feature for name in arg.split()]
args.extension = [name for arg in args.extension for name in arg.split()]
# create error/warning & diagnostic files
if args.errfile:
errWarn = open(args.errfile, 'w', encoding='utf-8')
else:
errWarn = sys.stderr
if args.diagfile:
diag = open(args.diagfile, 'w', encoding='utf-8')
else:
diag = None
# Create the API generator & generator options
(gen, options) = genTarget(args)
# Create the registry object with the specified generator and generator
# options. The options are set before XML loading as they may affect it.
reg = Registry(gen, options)
# Parse the specified registry XML into an ElementTree object
startTimer(args.time)
tree = etree.parse(args.registry)
endTimer(args.time, '* Time to make ElementTree =')
# Load the XML tree into the registry object
startTimer(args.time)
reg.loadElementTree(tree)
endTimer(args.time, '* Time to parse ElementTree =')
if args.validate:
reg.validateGroups()
if args.dump:
logDiag('* Dumping registry to regdump.txt')
reg.dumpReg(filehandle=open('regdump.txt', 'w', encoding='utf-8'))
# Finally, use the output generator to create the requested target
if args.debug:
pdb.run('reg.apiGen()')
else:
startTimer(args.time)
reg.apiGen()
endTimer(args.time, '* Time to generate ' + options.filename + ' =')
if not args.quiet:
logDiag('* Generated', options.filename)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,58 @@
"""Utility functions not closely tied to other spec_tools types."""
# Copyright 2018-2019 Collabora, Ltd.
# Copyright 2013-2021 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)

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,273 @@
#!/usr/bin/python3 -i
#
# Copyright 2013-2021 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0
# Working-group-specific style conventions,
# used in generation.
import re
import os
from 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
'8Bit', # VkPhysicalDevice8BitStorageFeaturesKHR
'AABB', # VkGeometryAABBNV
'ASTC', # VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT
'D3D12', # VkD3D12FenceSubmitInfoKHR
'Float16', # VkPhysicalDeviceShaderFloat16Int8FeaturesKHR
'ImagePipe', # VkImagePipeSurfaceCreateInfoFUCHSIA
'Int64', # VkPhysicalDeviceShaderAtomicInt64FeaturesKHR
'Int8', # VkPhysicalDeviceShaderFloat16Int8FeaturesKHR
'MacOS', # VkMacOSSurfaceCreateInfoMVK
'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`'
@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'_VULKAN_([0-9])([0-9])_', r'_VULKAN_\1_\2_' ],
[ r'_DIRECT_FB_', r'_DIRECTFB_' ],
]
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 '.txt'
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 aren't 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://www.khronos.org/registry/vulkan/specs/1.2-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 extra_refpage_headers(self):
"""Return any extra text to add to refpage headers."""
return 'include::{config}/attribs.txt[]'
@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're 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 doesn't 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_include_string(self, ext):
"""Return format string for include:: line for an extension appendix
file. ext is an object with the following members:
- name - extension string string
- vendor - vendor portion of name
- barename - remainder of name"""
return 'include::{{appendices}}/{name}{suffix}[]'.format(
name=ext.name, suffix=self.file_suffix)
@property
def refpage_generated_include_path(self):
"""Return path relative to the generated reference pages, to the
generated API include files."""
return "{generated}"
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