summaryrefslogtreecommitdiff
path: root/external/vulkan/registry/genvk.py
diff options
context:
space:
mode:
Diffstat (limited to 'external/vulkan/registry/genvk.py')
-rw-r--r--external/vulkan/registry/genvk.py363
1 files changed, 221 insertions, 142 deletions
diff --git a/external/vulkan/registry/genvk.py b/external/vulkan/registry/genvk.py
index 7034a3d09..626f0b984 100644
--- a/external/vulkan/registry/genvk.py
+++ b/external/vulkan/registry/genvk.py
@@ -1,58 +1,63 @@
#!/usr/bin/python3
#
-# Copyright (c) 2013-2019 The Khronos Group Inc.
+# Copyright (c) 2013-2020 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.
-
-import argparse, cProfile, pdb, string, sys, time
-from reg import *
-from generator import write
+# 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 extensionmetadocgenerator import (ExtensionMetaDocGeneratorOptions,
+ ExtensionMetaDocOutputGenerator)
+from interfacedocgenerator import InterfaceDocGenerator
+from generator import write
+from hostsyncgenerator import HostSynchronizationOutputGenerator
from pygenerator import PyOutputGenerator
+from reflib import logDiag, logWarn, setLogFile
+from reg import Registry
from validitygenerator import ValidityOutputGenerator
-from hostsyncgenerator import HostSynchronizationOutputGenerator
-from extensionStubSource import ExtensionStubSourceOutputGenerator
+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()
- write(msg, endTime - startTime, file=sys.stderr)
+ logDiag(msg, endTime - startTime)
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 == 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 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 = {}
@@ -77,10 +82,12 @@ def makeGenOpts(args):
# 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
+ allFeatures = allExtensions = r'.*'
# Turn lists of names/patterns into matching regular expressions
addExtensionsPat = makeREstring(extensions, None)
@@ -89,21 +96,12 @@ def makeGenOpts(args):
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 (c) 2015-2019 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',
+ '** Copyright (c) 2015-2020 The Khronos Group Inc.',
'**',
- '** 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.',
+ '** SPDX' + '-License-Identifier: Apache-2.0',
'*/',
''
]
@@ -119,8 +117,9 @@ def makeGenOpts(args):
# Defaults for generating re-inclusion protection wrappers (or not)
protectFile = protect
- protectFeature = protect
- protectProto = protect
+
+ # An API style conventions object
+ conventions = VulkanConventions()
# API include files for spec and ref pages
# Overwrites include subdirectories in spec source tree
@@ -132,8 +131,10 @@ def makeGenOpts(args):
genOpts['apiinc'] = [
DocOutputGenerator,
DocGeneratorOptions(
+ conventions = conventions,
filename = 'timeMarker',
directory = directory,
+ genpath = genpath,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
@@ -150,12 +151,15 @@ def makeGenOpts(args):
expandEnumerants = False)
]
- # API names to validate man/api spec includes & links
- genOpts['vkapi.py'] = [
+ # Python representation of API information, used by scripts that
+ # don't need to load the full XML.
+ genOpts['api.py'] = [
PyOutputGenerator,
DocGeneratorOptions(
- filename = 'vkapi.py',
+ conventions = conventions,
+ filename = 'api.py',
directory = directory,
+ genpath = None,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
@@ -163,15 +167,18 @@ def makeGenOpts(args):
defaultExtensions = None,
addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
- emitExtensions = emitExtensionsPat)
+ 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,
@@ -186,8 +193,10 @@ def makeGenOpts(args):
genOpts['hostsyncinc'] = [
HostSynchronizationOutputGenerator,
DocGeneratorOptions(
+ conventions = conventions,
filename = 'timeMarker',
directory = directory,
+ genpath = None,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
@@ -195,45 +204,51 @@ def makeGenOpts(args):
defaultExtensions = None,
addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
- emitExtensions = emitExtensionsPat)
- ]
-
- # Extension stub source dispatcher
- # This target is no longer maintained and supported.
- # See README.adoc for discussion.
- genOpts['vulkan_ext.c'] = [
- ExtensionStubSourceOutputGenerator,
- CGeneratorOptions(
- filename = 'vulkan_ext.c',
- directory = directory,
- apiname = 'vulkan',
- profile = None,
- versions = featuresPat,
- emitversions = None,
- defaultExtensions = None,
- addExtensions = '.*',
- removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat,
- prefixText = prefixStrings + vkPrefixStrings,
- alignFuncParam = 48)
+ 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 = None,
+ 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)
+ ]
+
# Platform extensions, in their own header files
# Each element of the platforms[] array defines information for
# generating a single platform:
@@ -247,24 +262,42 @@ def makeGenOpts(args):
# Track all platform extensions, for exclusion from vulkan_core.h
allPlatformExtensions = []
- # Extensions suppressed for all platforms.
- # Covers common WSI extension types.
+ # 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_ray_tracing', 'VK_KHR_deferred_host_operations', 'VK_KHR_pipeline_library' ]
+ betaSuppressExtensions = [ 'VK_NV_ray_tracing' ]
+
platforms = [
[ 'vulkan_android.h', [ 'VK_KHR_android_surface',
'VK_ANDROID_external_memory_android_hardware_buffer'
], commonSuppressExtensions ],
[ 'vulkan_fuchsia.h', [ 'VK_FUCHSIA_imagepipe_surface'], 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(|_.*)' ], commonSuppressExtensions + [ 'VK_KHR_external_semaphore', 'VK_KHR_external_memory_capabilities', 'VK_KHR_external_fence', 'VK_KHR_external_fence_capabilities', 'VK_NV_external_memory_capabilities' ] ],
+ [ '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_beta.h', betaRequireExtensions, betaSuppressExtensions ],
]
for platform in platforms:
@@ -272,12 +305,16 @@ def makeGenOpts(args):
allPlatformExtensions += platform[1]
- addPlatformExtensionsRE = makeREstring(platform[1] + platform[2])
- emitPlatformExtensionsRE = makeREstring(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,
@@ -307,19 +344,22 @@ def makeGenOpts(args):
# It removes all platform extensions (from the platform headers options
# constructed above) as well as any explicitly specified removals.
- removeExtensionsPat = makeREstring(allPlatformExtensions + removeExtensions, None)
+ 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 = None,
+ addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat,
prefixText = prefixStrings + vkPrefixStrings,
@@ -342,16 +382,50 @@ def makeGenOpts(args):
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 = defaultExtensions,
+ defaultExtensions = None,
addExtensions = None,
- removeExtensions = removeExtensionsPat,
- emitExtensions = emitExtensionsPat,
+ 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)
+ ]
+
+ # 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,
@@ -367,8 +441,10 @@ def makeGenOpts(args):
genOpts['alias.h'] = [
COutputGenerator,
CGeneratorOptions(
+ conventions = conventions,
filename = 'alias.h',
directory = directory,
+ genpath = None,
apiname = 'vulkan',
profile = None,
versions = featuresPat,
@@ -389,47 +465,44 @@ def makeGenOpts(args):
alignFuncParam = 36)
]
-# 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 an API generator and corresponding generator options based on
+ the requested target and command line options.
- # Create generator options with specified parameters
+ 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)
- if (args.target in genOpts.keys()):
+ # Select a generator matching the requested target
+ if args.target in genOpts:
createGenerator = genOpts[args.target][0]
options = genOpts[args.target][1]
- if not args.quiet:
- write('* Building', options.filename, 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)
+ 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)
- startTimer(args.time)
gen = createGenerator(errFile=errWarn,
warnFile=errWarn,
diagFile=diag)
- reg.setGenerator(gen)
- reg.apiGen(options)
-
- if not args.quiet:
- write('* Generated', options.filename, file=sys.stderr)
- endTimer(args.time, '* Time to generate ' + options.filename + ' =')
+ return (gen, options)
else:
- write('No generator options for unknown target:',
- args.target, file=sys.stderr)
+ logErr('No generator options for unknown target:', args.target)
+ return None
+
# -feature name
# -extension name
@@ -473,7 +546,9 @@ if __name__ == '__main__':
parser.add_argument('-time', action='store_true',
help='Enable timing')
parser.add_argument('-validate', action='store_true',
- help='Enable group validation')
+ 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')
@@ -490,44 +565,48 @@ if __name__ == '__main__':
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()]
- # Load & parse registry
- reg = Registry()
+ # 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 =')
- if args.debug:
- pdb.run('reg.loadElementTree(tree)')
- else:
- startTimer(args.time)
- reg.loadElementTree(tree)
- endTimer(args.time, '* Time to parse 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):
+ 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'))
-
- # create error/warning & diagnostic files
- if (args.errfile):
- errWarn = open(args.errfile, 'w', encoding='utf-8')
- else:
- errWarn = sys.stderr
+ if args.dump:
+ logDiag('* Dumping registry to regdump.txt')
+ reg.dumpReg(filehandle=open('regdump.txt', 'w', encoding='utf-8'))
- if (args.diagfile):
- diag = open(args.diagfile, 'w', encoding='utf-8')
+ # Finally, use the output generator to create the requested target
+ if args.debug:
+ pdb.run('reg.apiGen()')
else:
- diag = None
+ startTimer(args.time)
+ reg.apiGen()
+ endTimer(args.time, '* Time to generate ' + options.filename + ' =')
- if (args.debug):
- pdb.run('genTarget(args)')
- elif (args.profile):
- import cProfile, pstats
- cProfile.run('genTarget(args)', 'profile.txt')
- p = pstats.Stats('profile.txt')
- p.strip_dirs().sort_stats('time').print_stats(50)
- else:
- genTarget(args)
+ if not args.quiet:
+ logDiag('* Generated', options.filename)