import argparse, cProfile, pdb, string, sys, time, os
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
def makeREstring(list, default = None):
if len(list) > 0 or default is None:
return '^(' + '|'.join(list) + ')$'
else:
return default
def makeGenOpts(args):
global genOpts
genOpts = {}
apiname = args.api
if args.defaultExtensions is not None:
defaultExtensions = args.defaultExtensions
else:
defaultExtensions = apiname
extensions = args.extension
removeExtensions = args.removeExtensions
emitExtensions = args.emitExtensions
features = args.feature
protect = args.protect
directory = args.directory
genpath = args.genpath
allFeatures = allExtensions = '.*'
noFeatures = noExtensions = None
addExtensionsPat = makeREstring(extensions, None)
removeExtensionsPat = makeREstring(removeExtensions, None)
emitExtensionsPat = makeREstring(emitExtensions, allExtensions)
featuresPat = makeREstring(features, allFeatures)
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',
'**',
'** 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.',
'*/',
''
]
vkPrefixStrings = [
'/*',
'** This header is generated from the Khronos Vulkan XML API Registry.',
'**',
'*/',
''
]
protectFeature = protect
conventions = VulkanConventions()
genOpts['vk_dispatch_table_helper.h'] = [
DispatchTableHelperOutputGenerator,
DispatchTableHelperOutputGeneratorOptions(
conventions = conventions,
filename = 'vk_dispatch_table_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,
apicall = 'VKAPI_ATTR ',
apientry = 'VKAPI_CALL ',
apientryp = 'VKAPI_PTR *',
alignFuncParam = 48,
expandEnumerants = False)
]
genOpts['vk_layer_dispatch_table.h'] = [
LoaderExtensionOutputGenerator,
LoaderExtensionGeneratorOptions(
conventions = conventions,
filename = 'vk_layer_dispatch_table.h',
directory = directory,
genpath = None,
apiname = apiname,
profile = None,
versions = featuresPat,
emitversions = featuresPat,
defaultExtensions = defaultExtensions,
addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat,
prefixText = prefixStrings + vkPrefixStrings,
apicall = 'VKAPI_ATTR ',
apientry = 'VKAPI_CALL ',
apientryp = 'VKAPI_PTR *',
alignFuncParam = 48,
expandEnumerants = False)
]
genOpts['vk_loader_extensions.h'] = [
LoaderExtensionOutputGenerator,
LoaderExtensionGeneratorOptions(
conventions = conventions,
filename = 'vk_loader_extensions.h',
directory = directory,
genpath = None,
apiname = apiname,
profile = None,
versions = featuresPat,
emitversions = featuresPat,
defaultExtensions = defaultExtensions,
addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat,
prefixText = prefixStrings + vkPrefixStrings,
apicall = 'VKAPI_ATTR ',
apientry = 'VKAPI_CALL ',
apientryp = 'VKAPI_PTR *',
alignFuncParam = 48,
expandEnumerants = False)
]
genOpts['vk_loader_extensions.c'] = [
LoaderExtensionOutputGenerator,
LoaderExtensionGeneratorOptions(
conventions = conventions,
filename = 'vk_loader_extensions.c',
directory = directory,
genpath = None,
apiname = apiname,
profile = None,
versions = featuresPat,
emitversions = featuresPat,
defaultExtensions = defaultExtensions,
addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat,
prefixText = prefixStrings + vkPrefixStrings,
apicall = 'VKAPI_ATTR ',
apientry = 'VKAPI_CALL ',
apientryp = 'VKAPI_PTR *',
alignFuncParam = 48,
expandEnumerants = False)
]
genOpts['vk_object_types.h'] = [
HelperFileOutputGenerator,
HelperFileOutputGeneratorOptions(
conventions = conventions,
filename = 'vk_object_types.h',
directory = directory,
genpath = None,
apiname = apiname,
profile = None,
versions = featuresPat,
emitversions = featuresPat,
defaultExtensions = defaultExtensions,
addExtensions = addExtensionsPat,
removeExtensions = removeExtensionsPat,
emitExtensions = emitExtensionsPat,
prefixText = prefixStrings + vkPrefixStrings,
apicall = 'VKAPI_ATTR ',
apientry = 'VKAPI_CALL ',
apientryp = 'VKAPI_PTR *',
alignFuncParam = 48,
expandEnumerants = False,
helper_file_type = 'object_types_header')
]
def genTarget(args):
global genOpts
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
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-api', action='store',
default='vulkan',
choices=['vulkan'],
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('-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.')
parser.add_argument('-scripts', action='store',
help='Find additional scripts in this directory')
args = parser.parse_args()
if not args.scripts:
args.scripts = os.path.dirname(args.registry)
print(args.scripts)
scripts_dir = os.path.dirname(os.path.abspath(__file__))
registry_dir = os.path.join(scripts_dir, args.scripts)
sys.path.insert(0, registry_dir)
from reg import *
from generator import write
from cgenerator import CGeneratorOptions, COutputGenerator
from dispatch_table_helper_generator import DispatchTableHelperOutputGenerator, DispatchTableHelperOutputGeneratorOptions
from helper_file_generator import HelperFileOutputGenerator, HelperFileOutputGeneratorOptions
from loader_extension_generator import LoaderExtensionOutputGenerator, LoaderExtensionGeneratorOptions
import abc; abc.ABC = abc.ABCMeta('ABC', (object,), {})
from vkconventions import VulkanConventions
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()]
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
(gen, options) = genTarget(args)
reg = Registry(gen, options)
startTimer(args.time)
tree = etree.parse(args.registry)
endTimer(args.time, '* Time to make ElementTree =')
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'))
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:
write('* Generated', options.filename, file=sys.stderr)