diff options
| author | Lizzy Fleckenstein <lizzy@vlhl.dev> | 2026-03-31 01:30:36 +0200 |
|---|---|---|
| committer | Lizzy Fleckenstein <lizzy@vlhl.dev> | 2026-03-31 01:30:36 +0200 |
| commit | 8e2ff15dbd3fe70fe2b52397b1eaba3fe2d7a5e8 (patch) | |
| tree | 925fa596210d1a1f01e00e0743a643f4552e7a7a /tools/Vulkan-Tools/scripts/kvt_genvk.py | |
| parent | 1f17b4df127bd280e50d93a46ae93df704adc2b0 (diff) | |
| parent | 90bf5bc4fd8bea0d300f6564af256a51a34124b8 (diff) | |
| download | usermoji-8e2ff15dbd3fe70fe2b52397b1eaba3fe2d7a5e8.tar.xz | |
add tools/Vulkan-Tools
Diffstat (limited to 'tools/Vulkan-Tools/scripts/kvt_genvk.py')
| -rw-r--r-- | tools/Vulkan-Tools/scripts/kvt_genvk.py | 416 |
1 files changed, 416 insertions, 0 deletions
diff --git a/tools/Vulkan-Tools/scripts/kvt_genvk.py b/tools/Vulkan-Tools/scripts/kvt_genvk.py new file mode 100644 index 00000000..868cc3fb --- /dev/null +++ b/tools/Vulkan-Tools/scripts/kvt_genvk.py @@ -0,0 +1,416 @@ +#!/usr/bin/python3 +# +# Copyright (c) 2013-2025 The Khronos Group Inc. +# Copyright (c) 2023-2025 RasterGrid Kft. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import pdb +import sys +import time +import os + +# 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() + write(msg, endTime - startTime, file=sys.stderr) + startTime = None + +# Turn a list of strings into a regexp string matching exactly those strings + + +def makeREstring(list, default=None): + if len(list) > 0 or default is None: + return '^(' + '|'.join(list) + ')$' + else: + return default + +# 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. + + +def makeGenOpts(args): + global genOpts + genOpts = {} + + # API to generate sources for + apiname = args.api + + # Default class of extensions to include, or None + if args.defaultExtensions is not None: + defaultExtensions = args.defaultExtensions + else: + defaultExtensions = apiname + + # 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 + + # 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 + + # Descriptive names for various regexp patterns used to select + # versions and extensions + allFeatures = allExtensions = '.*' + noFeatures = noExtensions = None + + # Turn lists of names/patterns into matching regular expressions + addExtensionsPat = makeREstring(extensions, None) + removeExtensionsPat = makeREstring(removeExtensions, None) + emitExtensionsPat = makeREstring(emitExtensions, allExtensions) + featuresPat = makeREstring(features, allFeatures) + + # Copyright text prefixing all headers (list of strings). + prefixStrings = [ + '/*', + '** Copyright (c) 2015-2025 The Khronos Group Inc.', + '**', + '** Licensed under the Apache License, Version 2.0 (the "License");', + '** you may not use this file except in compliance with the License.', + '** You may obtain a copy of the License at', + '**', + '** http://www.apache.org/licenses/LICENSE-2.0', + '**', + '** Unless required by applicable law or agreed to in writing, software', + '** distributed under the License is distributed on an "AS IS" BASIS,', + '** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.', + '** See the License for the specific language governing permissions and', + '** limitations under the License.', + '*/', + '' + ] + + # 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) + protectFeature = protect + + # An API style conventions object + conventions = VulkanConventions() + + # Helper file generator options for typemap_helper.h + genOpts['vk_typemap_helper.h'] = [ + HelperFileOutputGenerator, + HelperFileOutputGeneratorOptions( + conventions=conventions, + filename='vk_typemap_helper.h', + directory=directory, + genpath=None, + apiname=apiname, + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions=defaultExtensions, + addExtensions=addExtensionsPat, + removeExtensions=removeExtensionsPat, + emitExtensions=emitExtensionsPat, + prefixText=prefixStrings + vkPrefixStrings, + protectFeature=False, + apicall='VKAPI_ATTR ', + apientry='VKAPI_CALL ', + apientryp='VKAPI_PTR *', + alignFuncParam=48, + expandEnumerants=False, + helper_file_type='typemap_helper_header') + ] + + # Options for mock ICD header + genOpts['function_declarations.h'] = [ + MockICDOutputGenerator, + MockICDGeneratorOptions( + conventions=conventions, + filename='function_declarations.h', + directory=directory, + genpath=None, + apiname=apiname, + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions=defaultExtensions, + addExtensions=addExtensionsPat, + removeExtensions=removeExtensionsPat, + emitExtensions=emitExtensionsPat, + prefixText=prefixStrings + vkPrefixStrings, + protectFeature=False, + apicall='VKAPI_ATTR ', + apientry='VKAPI_CALL ', + apientryp='VKAPI_PTR *', + alignFuncParam=48, + expandEnumerants=False, + helper_file_type='mock_icd_function_declaration_implementation') + ] + + # Options for mock ICD cpp + genOpts['function_definitions.h'] = [ + MockICDOutputGenerator, + MockICDGeneratorOptions( + conventions=conventions, + filename='function_definitions.h', + directory=directory, + genpath=None, + apiname=apiname, + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions=defaultExtensions, + addExtensions=addExtensionsPat, + removeExtensions=removeExtensionsPat, + emitExtensions=emitExtensionsPat, + prefixText=prefixStrings + vkPrefixStrings, + protectFeature=False, + apicall='VKAPI_ATTR ', + apientry='VKAPI_CALL ', + apientryp='VKAPI_PTR *', + alignFuncParam=48, + expandEnumerants=False, + helper_file_type='mock_icd_function_definition_implementation') + ] + + # Options for vulkaninfo.hpp + genOpts['vulkaninfo.hpp'] = [ + VulkanInfoGenerator, + VulkanInfoGeneratorOptions( + conventions=conventions, + filename='vulkaninfo.hpp', + directory=directory, + genpath=None, + apiname=apiname, + profile=None, + versions=featuresPat, + emitversions=featuresPat, + defaultExtensions=defaultExtensions, + addExtensions=addExtensionsPat, + removeExtensions=removeExtensionsPat, + emitExtensions=emitExtensionsPat, + prefixText=prefixStrings + vkPrefixStrings, + protectFeature=False, + apicall='VKAPI_ATTR ', + apientry='VKAPI_CALL ', + apientryp='VKAPI_PTR *', + alignFuncParam=48, + expandEnumerants=False, + registryFile=args.registry) + ] + + +# Generate a target based on the options in the matching genOpts{} object. +# 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 +def genTarget(args): + global genOpts + + # Create generator options with specified parameters + makeGenOpts(args) + + if (args.target in genOpts.keys()): + createGenerator = genOpts[args.target][0] + options = genOpts[args.target][1] + + if not args.quiet: + write('* Building', options.filename, file=sys.stderr) + write('* options.apiname =', options.apiname, file=sys.stderr) + write('* options.versions =', options.versions, file=sys.stderr) + write('* options.emitversions =', options.emitversions, file=sys.stderr) + write('* options.defaultExtensions =', options.defaultExtensions, file=sys.stderr) + write('* options.addExtensions =', options.addExtensions, file=sys.stderr) + write('* options.removeExtensions =', options.removeExtensions, file=sys.stderr) + write('* options.emitExtensions =', options.emitExtensions, file=sys.stderr) + + gen = createGenerator(errFile=errWarn, + warnFile=errWarn, + diagFile=diag) + if not args.quiet: + write('* Generated', options.filename, file=sys.stderr) + return (gen, options) + else: + write('No generator options for unknown target:', + args.target, file=sys.stderr) + 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('-api', action='store', + default='vulkan', + choices=['vulkan', 'vulkansc'], + help='Specify API name to generate') + parser.add_argument('-defaultExtensions', action='store', + default=None, + help='Specify a single class of extensions to add to targets') + parser.add_argument('-directory', action='store', default='.', + help='Specify where the built file is place') + 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('-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.') + + # This argument tells us where to load the script from the Vulkan-Headers registry + parser.add_argument('-scripts', action='store', + help='Find additional scripts in this directory') + + args = parser.parse_args() + + # default scripts path to be same as registry + if not args.scripts: + args.scripts = os.path.dirname(args.registry) + + scripts_directory_path = os.path.dirname(os.path.abspath(__file__)) + registry_headers_path = os.path.join(scripts_directory_path, args.scripts) + sys.path.insert(0, registry_headers_path) + + from reg import * + from generator import write + from cgenerator import CGeneratorOptions, COutputGenerator + + # Generator Modifications + from generators.mock_icd_generator import MockICDGeneratorOptions, MockICDOutputGenerator + from generators.vulkan_tools_helper_file_generator import HelperFileOutputGenerator, HelperFileOutputGeneratorOptions + from generators.vulkaninfo_generator import VulkanInfoGenerator, VulkanInfoGeneratorOptions + # Temporary workaround for vkconventions python2 compatibility + import abc + abc.ABC = abc.ABCMeta('ABC', (object,), {}) + from vkconventions import VulkanConventions + + # 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): + write('* Dumping registry to regdump.txt', file=sys.stderr) + 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 + ' =') + genTarget(args) |
