1#!/usr/bin/python3
2#
3# Copyright (c) 2013-2019 The Khronos Group Inc.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import argparse, cProfile, pdb, string, sys, time, os
18
19# Simple timer functions
20startTime = None
21
22def startTimer(timeit):
23    global startTime
24    if timeit:
25        startTime = time.process_time()
26
27def endTimer(timeit, msg):
28    global startTime
29    if timeit:
30        endTime = time.process_time()
31        write(msg, endTime - startTime, file=sys.stderr)
32        startTime = None
33
34# Turn a list of strings into a regexp string matching exactly those strings
35def makeREstring(list, default = None):
36    if len(list) > 0 or default is None:
37        return '^(' + '|'.join(list) + ')$'
38    else:
39        return default
40
41# Returns a directory of [ generator function, generator options ] indexed
42# by specified short names. The generator options incorporate the following
43# parameters:
44#
45# args is an parsed argument object; see below for the fields that are used.
46def makeGenOpts(args):
47    global genOpts
48    genOpts = {}
49
50    # Default class of extensions to include, or None
51    defaultExtensions = args.defaultExtensions
52
53    # Additional extensions to include (list of extensions)
54    extensions = args.extension
55
56    # Extensions to remove (list of extensions)
57    removeExtensions = args.removeExtensions
58
59    # Extensions to emit (list of extensions)
60    emitExtensions = args.emitExtensions
61
62    # Features to include (list of features)
63    features = args.feature
64
65    # Whether to disable inclusion protect in headers
66    protect = args.protect
67
68    # Output target directory
69    directory = args.directory
70
71    # Descriptive names for various regexp patterns used to select
72    # versions and extensions
73    allFeatures     = allExtensions = '.*'
74    noFeatures      = noExtensions = None
75
76    # Turn lists of names/patterns into matching regular expressions
77    addExtensionsPat     = makeREstring(extensions, None)
78    removeExtensionsPat  = makeREstring(removeExtensions, None)
79    emitExtensionsPat    = makeREstring(emitExtensions, allExtensions)
80    featuresPat          = makeREstring(features, allFeatures)
81
82    # Copyright text prefixing all headers (list of strings).
83    prefixStrings = [
84        '/*',
85        '** Copyright (c) 2015-2019 The Khronos Group Inc.',
86        '**',
87        '** Licensed under the Apache License, Version 2.0 (the "License");',
88        '** you may not use this file except in compliance with the License.',
89        '** You may obtain a copy of the License at',
90        '**',
91        '**     http://www.apache.org/licenses/LICENSE-2.0',
92        '**',
93        '** Unless required by applicable law or agreed to in writing, software',
94        '** distributed under the License is distributed on an "AS IS" BASIS,',
95        '** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
96        '** See the License for the specific language governing permissions and',
97        '** limitations under the License.',
98        '*/',
99        ''
100    ]
101
102    # Text specific to Vulkan headers
103    vkPrefixStrings = [
104        '/*',
105        '** This header is generated from the Khronos Vulkan XML API Registry.',
106        '**',
107        '*/',
108        ''
109    ]
110
111    # Defaults for generating re-inclusion protection wrappers (or not)
112    protectFeature = protect
113
114    # An API style convention object
115    conventions = VulkanConventions()
116
117    # ValidationLayer Generators
118    # Options for thread safety header code-generation
119    genOpts['thread_safety.h'] = [
120          ThreadOutputGenerator,
121          ThreadGeneratorOptions(
122            conventions       = conventions,
123            filename          = 'thread_safety.h',
124            directory         = directory,
125            apiname           = 'vulkan',
126            profile           = None,
127            versions          = featuresPat,
128            emitversions      = featuresPat,
129            defaultExtensions = 'vulkan',
130            addExtensions     = addExtensionsPat,
131            removeExtensions  = removeExtensionsPat,
132            emitExtensions    = emitExtensionsPat,
133            prefixText        = prefixStrings + vkPrefixStrings,
134            protectFeature    = False,
135            apicall           = 'VKAPI_ATTR ',
136            apientry          = 'VKAPI_CALL ',
137            apientryp         = 'VKAPI_PTR *',
138            alignFuncParam    = 48,
139            expandEnumerants = False)
140        ]
141
142    # Options for thread safety source code-generation
143    genOpts['thread_safety.cpp'] = [
144          ThreadOutputGenerator,
145          ThreadGeneratorOptions(
146            conventions       = conventions,
147            filename          = 'thread_safety.cpp',
148            directory         = directory,
149            apiname           = 'vulkan',
150            profile           = None,
151            versions          = featuresPat,
152            emitversions      = featuresPat,
153            defaultExtensions = 'vulkan',
154            addExtensions     = addExtensionsPat,
155            removeExtensions  = removeExtensionsPat,
156            emitExtensions    = emitExtensionsPat,
157            prefixText        = prefixStrings + vkPrefixStrings,
158            protectFeature    = False,
159            apicall           = 'VKAPI_ATTR ',
160            apientry          = 'VKAPI_CALL ',
161            apientryp         = 'VKAPI_PTR *',
162            alignFuncParam    = 48,
163            expandEnumerants = False)
164        ]
165
166    # Options for stateless validation source file
167    genOpts['parameter_validation.cpp'] = [
168          ParameterValidationOutputGenerator,
169          ParameterValidationGeneratorOptions(
170            conventions       = conventions,
171            filename          = 'parameter_validation.cpp',
172            directory         = directory,
173            apiname           = 'vulkan',
174            profile           = None,
175            versions          = featuresPat,
176            emitversions      = featuresPat,
177            defaultExtensions = 'vulkan',
178            addExtensions     = addExtensionsPat,
179            removeExtensions  = removeExtensionsPat,
180            emitExtensions    = emitExtensionsPat,
181            prefixText        = prefixStrings + vkPrefixStrings,
182            apicall           = 'VKAPI_ATTR ',
183            apientry          = 'VKAPI_CALL ',
184            apientryp         = 'VKAPI_PTR *',
185            alignFuncParam    = 48,
186            expandEnumerants  = False,
187            valid_usage_path  = args.scripts)
188          ]
189
190    # Options for stateless validation source file
191    genOpts['parameter_validation.h'] = [
192          ParameterValidationOutputGenerator,
193          ParameterValidationGeneratorOptions(
194            conventions       = conventions,
195            filename          = 'parameter_validation.h',
196            directory         = directory,
197            apiname           = 'vulkan',
198            profile           = None,
199            versions          = featuresPat,
200            emitversions      = featuresPat,
201            defaultExtensions = 'vulkan',
202            addExtensions     = addExtensionsPat,
203            removeExtensions  = removeExtensionsPat,
204            emitExtensions    = emitExtensionsPat,
205            prefixText        = prefixStrings + vkPrefixStrings,
206            apicall           = 'VKAPI_ATTR ',
207            apientry          = 'VKAPI_CALL ',
208            apientryp         = 'VKAPI_PTR *',
209            alignFuncParam    = 48,
210            expandEnumerants  = False,
211            valid_usage_path  = args.scripts)
212          ]
213
214    # Options for object_tracker code-generated validation routines
215    genOpts['object_tracker.cpp'] = [
216          ObjectTrackerOutputGenerator,
217          ObjectTrackerGeneratorOptions(
218            conventions       = conventions,
219            filename          = 'object_tracker.cpp',
220            directory         = directory,
221            apiname           = 'vulkan',
222            profile           = None,
223            versions          = featuresPat,
224            emitversions      = featuresPat,
225            defaultExtensions = 'vulkan',
226            addExtensions     = addExtensionsPat,
227            removeExtensions  = removeExtensionsPat,
228            emitExtensions    = emitExtensionsPat,
229            prefixText        = prefixStrings + vkPrefixStrings,
230            protectFeature    = False,
231            apicall           = 'VKAPI_ATTR ',
232            apientry          = 'VKAPI_CALL ',
233            apientryp         = 'VKAPI_PTR *',
234            alignFuncParam    = 48,
235            expandEnumerants  = False,
236            valid_usage_path  = args.scripts)
237        ]
238
239    # Options for object_tracker code-generated prototypes
240    genOpts['object_tracker.h'] = [
241          ObjectTrackerOutputGenerator,
242          ObjectTrackerGeneratorOptions(
243            conventions       = conventions,
244            filename          = 'object_tracker.h',
245            directory         = directory,
246            apiname           = 'vulkan',
247            profile           = None,
248            versions          = featuresPat,
249            emitversions      = featuresPat,
250            defaultExtensions = 'vulkan',
251            addExtensions     = addExtensionsPat,
252            removeExtensions  = removeExtensionsPat,
253            emitExtensions    = emitExtensionsPat,
254            prefixText        = prefixStrings + vkPrefixStrings,
255            protectFeature    = False,
256            apicall           = 'VKAPI_ATTR ',
257            apientry          = 'VKAPI_CALL ',
258            apientryp         = 'VKAPI_PTR *',
259            alignFuncParam    = 48,
260            expandEnumerants  = False,
261            valid_usage_path  = args.scripts)
262        ]
263
264    # Options for dispatch table helper generator
265    genOpts['vk_dispatch_table_helper.h'] = [
266          DispatchTableHelperOutputGenerator,
267          DispatchTableHelperOutputGeneratorOptions(
268            conventions       = conventions,
269            filename          = 'vk_dispatch_table_helper.h',
270            directory         = directory,
271            apiname           = 'vulkan',
272            profile           = None,
273            versions          = featuresPat,
274            emitversions      = featuresPat,
275            defaultExtensions = 'vulkan',
276            addExtensions     = addExtensionsPat,
277            removeExtensions  = removeExtensionsPat,
278            emitExtensions    = emitExtensionsPat,
279            prefixText        = prefixStrings + vkPrefixStrings,
280            apicall           = 'VKAPI_ATTR ',
281            apientry          = 'VKAPI_CALL ',
282            apientryp         = 'VKAPI_PTR *',
283            alignFuncParam    = 48,
284            expandEnumerants = False)
285        ]
286
287    # Options for Layer dispatch table generator
288    genOpts['vk_layer_dispatch_table.h'] = [
289          LayerDispatchTableOutputGenerator,
290          LayerDispatchTableGeneratorOptions(
291            conventions       = conventions,
292            filename          = 'vk_layer_dispatch_table.h',
293            directory         = directory,
294            apiname           = 'vulkan',
295            profile           = None,
296            versions          = featuresPat,
297            emitversions      = featuresPat,
298            defaultExtensions = 'vulkan',
299            addExtensions     = addExtensionsPat,
300            removeExtensions  = removeExtensionsPat,
301            emitExtensions    = emitExtensionsPat,
302            prefixText        = prefixStrings + vkPrefixStrings,
303            apicall           = 'VKAPI_ATTR ',
304            apientry          = 'VKAPI_CALL ',
305            apientryp         = 'VKAPI_PTR *',
306            alignFuncParam    = 48,
307            expandEnumerants = False)
308        ]
309
310    # Helper file generator options for vk_enum_string_helper.h
311    genOpts['vk_enum_string_helper.h'] = [
312          HelperFileOutputGenerator,
313          HelperFileOutputGeneratorOptions(
314            conventions       = conventions,
315            filename          = 'vk_enum_string_helper.h',
316            directory         = directory,
317            apiname           = 'vulkan',
318            profile           = None,
319            versions          = featuresPat,
320            emitversions      = featuresPat,
321            defaultExtensions = 'vulkan',
322            addExtensions     = addExtensionsPat,
323            removeExtensions  = removeExtensionsPat,
324            emitExtensions    = emitExtensionsPat,
325            prefixText        = prefixStrings + vkPrefixStrings,
326            apicall           = 'VKAPI_ATTR ',
327            apientry          = 'VKAPI_CALL ',
328            apientryp         = 'VKAPI_PTR *',
329            alignFuncParam    = 48,
330            expandEnumerants  = False,
331            helper_file_type  = 'enum_string_header')
332        ]
333
334    # Helper file generator options for vk_safe_struct.h
335    genOpts['vk_safe_struct.h'] = [
336          HelperFileOutputGenerator,
337          HelperFileOutputGeneratorOptions(
338            conventions       = conventions,
339            filename          = 'vk_safe_struct.h',
340            directory         = directory,
341            apiname           = 'vulkan',
342            profile           = None,
343            versions          = featuresPat,
344            emitversions      = featuresPat,
345            defaultExtensions = 'vulkan',
346            addExtensions     = addExtensionsPat,
347            removeExtensions  = removeExtensionsPat,
348            emitExtensions    = emitExtensionsPat,
349            prefixText        = prefixStrings + vkPrefixStrings,
350            apicall           = 'VKAPI_ATTR ',
351            apientry          = 'VKAPI_CALL ',
352            apientryp         = 'VKAPI_PTR *',
353            alignFuncParam    = 48,
354            expandEnumerants  = False,
355            helper_file_type  = 'safe_struct_header')
356        ]
357
358    # Helper file generator options for vk_safe_struct.cpp
359    genOpts['vk_safe_struct.cpp'] = [
360          HelperFileOutputGenerator,
361          HelperFileOutputGeneratorOptions(
362            conventions       = conventions,
363            filename          = 'vk_safe_struct.cpp',
364            directory         = directory,
365            apiname           = 'vulkan',
366            profile           = None,
367            versions          = featuresPat,
368            emitversions      = featuresPat,
369            defaultExtensions = 'vulkan',
370            addExtensions     = addExtensionsPat,
371            removeExtensions  = removeExtensionsPat,
372            emitExtensions    = emitExtensionsPat,
373            prefixText        = prefixStrings + vkPrefixStrings,
374            apicall           = 'VKAPI_ATTR ',
375            apientry          = 'VKAPI_CALL ',
376            apientryp         = 'VKAPI_PTR *',
377            alignFuncParam    = 48,
378            expandEnumerants  = False,
379            helper_file_type  = 'safe_struct_source')
380        ]
381
382    # Helper file generator options for vk_object_types.h
383    genOpts['vk_object_types.h'] = [
384          HelperFileOutputGenerator,
385          HelperFileOutputGeneratorOptions(
386            conventions       = conventions,
387            filename          = 'vk_object_types.h',
388            directory         = directory,
389            apiname           = 'vulkan',
390            profile           = None,
391            versions          = featuresPat,
392            emitversions      = featuresPat,
393            defaultExtensions = 'vulkan',
394            addExtensions     = addExtensionsPat,
395            removeExtensions  = removeExtensionsPat,
396            emitExtensions    = emitExtensionsPat,
397            prefixText        = prefixStrings + vkPrefixStrings,
398            apicall           = 'VKAPI_ATTR ',
399            apientry          = 'VKAPI_CALL ',
400            apientryp         = 'VKAPI_PTR *',
401            alignFuncParam    = 48,
402            expandEnumerants  = False,
403            helper_file_type  = 'object_types_header')
404        ]
405
406    # Helper file generator options for extension_helper.h
407    genOpts['vk_extension_helper.h'] = [
408          HelperFileOutputGenerator,
409          HelperFileOutputGeneratorOptions(
410            conventions       = conventions,
411            filename          = 'vk_extension_helper.h',
412            directory         = directory,
413            apiname           = 'vulkan',
414            profile           = None,
415            versions          = featuresPat,
416            emitversions      = featuresPat,
417            defaultExtensions = 'vulkan',
418            addExtensions     = addExtensionsPat,
419            removeExtensions  = removeExtensionsPat,
420            emitExtensions    = emitExtensionsPat,
421            prefixText        = prefixStrings + vkPrefixStrings,
422            apicall           = 'VKAPI_ATTR ',
423            apientry          = 'VKAPI_CALL ',
424            apientryp         = 'VKAPI_PTR *',
425            alignFuncParam    = 48,
426            expandEnumerants  = False,
427            helper_file_type  = 'extension_helper_header')
428        ]
429
430    # Helper file generator options for typemap_helper.h
431    genOpts['vk_typemap_helper.h'] = [
432          HelperFileOutputGenerator,
433          HelperFileOutputGeneratorOptions(
434            conventions       = conventions,
435            filename          = 'vk_typemap_helper.h',
436            directory         = directory,
437            apiname           = 'vulkan',
438            profile           = None,
439            versions          = featuresPat,
440            emitversions      = featuresPat,
441            defaultExtensions = 'vulkan',
442            addExtensions     = addExtensionsPat,
443            removeExtensions  = removeExtensionsPat,
444            emitExtensions    = emitExtensionsPat,
445            prefixText        = prefixStrings + vkPrefixStrings,
446            protectFeature    = False,
447            apicall           = 'VKAPI_ATTR ',
448            apientry          = 'VKAPI_CALL ',
449            apientryp         = 'VKAPI_PTR *',
450            alignFuncParam    = 48,
451            expandEnumerants  = False,
452            helper_file_type  = 'typemap_helper_header')
453        ]
454
455    # Layer chassis related generation structs
456    # Options for layer chassis header
457    genOpts['chassis.h'] = [
458          LayerChassisOutputGenerator,
459          LayerChassisGeneratorOptions(
460            conventions       = conventions,
461            filename          = 'chassis.h',
462            directory         = directory,
463            apiname           = 'vulkan',
464            profile           = None,
465            versions          = featuresPat,
466            emitversions      = featuresPat,
467            defaultExtensions = 'vulkan',
468            addExtensions     = addExtensionsPat,
469            removeExtensions  = removeExtensionsPat,
470            emitExtensions    = emitExtensionsPat,
471            prefixText        = prefixStrings + vkPrefixStrings,
472            apicall           = 'VKAPI_ATTR ',
473            apientry          = 'VKAPI_CALL ',
474            apientryp         = 'VKAPI_PTR *',
475            alignFuncParam    = 48,
476            helper_file_type  = 'layer_chassis_header',
477            expandEnumerants = False)
478        ]
479
480    # Options for layer chassis source file
481    genOpts['chassis.cpp'] = [
482          LayerChassisOutputGenerator,
483          LayerChassisGeneratorOptions(
484            conventions       = conventions,
485            filename          = 'chassis.cpp',
486            directory         = directory,
487            apiname           = 'vulkan',
488            profile           = None,
489            versions          = featuresPat,
490            emitversions      = featuresPat,
491            defaultExtensions = 'vulkan',
492            addExtensions     = addExtensionsPat,
493            removeExtensions  = removeExtensionsPat,
494            emitExtensions    = emitExtensionsPat,
495            prefixText        = prefixStrings + vkPrefixStrings,
496            apicall           = 'VKAPI_ATTR ',
497            apientry          = 'VKAPI_CALL ',
498            apientryp         = 'VKAPI_PTR *',
499            alignFuncParam    = 48,
500            helper_file_type  = 'layer_chassis_source',
501            expandEnumerants = False)
502        ]
503
504    # Options for layer chassis dispatch source file
505    genOpts['layer_chassis_dispatch.cpp'] = [
506          LayerChassisDispatchOutputGenerator,
507          LayerChassisDispatchGeneratorOptions(
508            conventions       = conventions,
509            filename          = 'layer_chassis_dispatch.cpp',
510            directory         = directory,
511            apiname           = 'vulkan',
512            profile           = None,
513            versions          = featuresPat,
514            emitversions      = featuresPat,
515            defaultExtensions = 'vulkan',
516            addExtensions     = addExtensionsPat,
517            removeExtensions  = removeExtensionsPat,
518            emitExtensions    = emitExtensionsPat,
519            prefixText        = prefixStrings + vkPrefixStrings,
520            protectFeature    = False,
521            apicall           = 'VKAPI_ATTR ',
522            apientry          = 'VKAPI_CALL ',
523            apientryp         = 'VKAPI_PTR *',
524            alignFuncParam    = 48,
525            expandEnumerants = False)
526        ]
527
528    # Options for layer chassis dispatch header file
529    genOpts['layer_chassis_dispatch.h'] = [
530          LayerChassisDispatchOutputGenerator,
531          LayerChassisDispatchGeneratorOptions(
532            conventions       = conventions,
533            filename          = 'layer_chassis_dispatch.h',
534            directory         = directory,
535            apiname           = 'vulkan',
536            profile           = None,
537            versions          = featuresPat,
538            emitversions      = featuresPat,
539            defaultExtensions = 'vulkan',
540            addExtensions     = addExtensionsPat,
541            removeExtensions  = removeExtensionsPat,
542            emitExtensions    = emitExtensionsPat,
543            prefixText        = prefixStrings + vkPrefixStrings,
544            protectFeature    = False,
545            apicall           = 'VKAPI_ATTR ',
546            apientry          = 'VKAPI_CALL ',
547            apientryp         = 'VKAPI_PTR *',
548            alignFuncParam    = 48,
549            expandEnumerants = False)
550        ]
551
552
553# Generate a target based on the options in the matching genOpts{} object.
554# This is encapsulated in a function so it can be profiled and/or timed.
555# The args parameter is an parsed argument object containing the following
556# fields that are used:
557#   target - target to generate
558#   directory - directory to generate it in
559#   protect - True if re-inclusion wrappers should be created
560#   extensions - list of additional extensions to include in generated
561#   interfaces
562def genTarget(args):
563    global genOpts
564
565    # Create generator options with specified parameters
566    makeGenOpts(args)
567
568    if (args.target in genOpts.keys()):
569        createGenerator = genOpts[args.target][0]
570        options = genOpts[args.target][1]
571
572        if not args.quiet:
573            write('* Building', options.filename, file=sys.stderr)
574            write('* options.versions          =', options.versions, file=sys.stderr)
575            write('* options.emitversions      =', options.emitversions, file=sys.stderr)
576            write('* options.defaultExtensions =', options.defaultExtensions, file=sys.stderr)
577            write('* options.addExtensions     =', options.addExtensions, file=sys.stderr)
578            write('* options.removeExtensions  =', options.removeExtensions, file=sys.stderr)
579            write('* options.emitExtensions    =', options.emitExtensions, file=sys.stderr)
580
581        startTimer(args.time)
582        gen = createGenerator(errFile=errWarn,
583                              warnFile=errWarn,
584                              diagFile=diag)
585        reg.setGenerator(gen)
586        reg.apiGen(options)
587
588        if not args.quiet:
589            write('* Generated', options.filename, file=sys.stderr)
590        endTimer(args.time, '* Time to generate ' + options.filename + ' =')
591    else:
592        write('No generator options for unknown target:',
593              args.target, file=sys.stderr)
594
595# -feature name
596# -extension name
597# For both, "name" may be a single name, or a space-separated list
598# of names, or a regular expression.
599if __name__ == '__main__':
600    parser = argparse.ArgumentParser()
601
602    parser.add_argument('-defaultExtensions', action='store',
603                        default='vulkan',
604                        help='Specify a single class of extensions to add to targets')
605    parser.add_argument('-extension', action='append',
606                        default=[],
607                        help='Specify an extension or extensions to add to targets')
608    parser.add_argument('-removeExtensions', action='append',
609                        default=[],
610                        help='Specify an extension or extensions to remove from targets')
611    parser.add_argument('-emitExtensions', action='append',
612                        default=[],
613                        help='Specify an extension or extensions to emit in targets')
614    parser.add_argument('-feature', action='append',
615                        default=[],
616                        help='Specify a core API feature name or names to add to targets')
617    parser.add_argument('-debug', action='store_true',
618                        help='Enable debugging')
619    parser.add_argument('-dump', action='store_true',
620                        help='Enable dump to stderr')
621    parser.add_argument('-diagfile', action='store',
622                        default=None,
623                        help='Write diagnostics to specified file')
624    parser.add_argument('-errfile', action='store',
625                        default=None,
626                        help='Write errors and warnings to specified file instead of stderr')
627    parser.add_argument('-noprotect', dest='protect', action='store_false',
628                        help='Disable inclusion protection in output headers')
629    parser.add_argument('-profile', action='store_true',
630                        help='Enable profiling')
631    parser.add_argument('-registry', action='store',
632                        default='vk.xml',
633                        help='Use specified registry file instead of vk.xml')
634    parser.add_argument('-time', action='store_true',
635                        help='Enable timing')
636    parser.add_argument('-validate', action='store_true',
637                        help='Enable group validation')
638    parser.add_argument('-o', action='store', dest='directory',
639                        default='.',
640                        help='Create target and related files in specified directory')
641    parser.add_argument('target', metavar='target', nargs='?',
642                        help='Specify target')
643    parser.add_argument('-quiet', action='store_true', default=True,
644                        help='Suppress script output during normal execution.')
645    parser.add_argument('-verbose', action='store_false', dest='quiet', default=True,
646                        help='Enable script output during normal execution.')
647
648    # This argument tells us where to load the script from the Vulkan-Headers registry
649    parser.add_argument('-scripts', action='store',
650                        help='Find additional scripts in this directory')
651
652    args = parser.parse_args()
653
654    # default scripts path to be same as registry
655    if not args.scripts:
656        args.scripts = os.path.dirname(args.registry)
657
658    scripts_directory_path = os.path.dirname(os.path.abspath(__file__))
659    registry_headers_path = os.path.join(scripts_directory_path, args.scripts)
660    sys.path.insert(0, registry_headers_path)
661
662    from reg import *
663    from generator import write
664    from cgenerator import CGeneratorOptions, COutputGenerator
665
666    # ValidationLayer Generator Modifications
667    from thread_safety_generator import  ThreadGeneratorOptions, ThreadOutputGenerator
668    from parameter_validation_generator import ParameterValidationGeneratorOptions, ParameterValidationOutputGenerator
669    from object_tracker_generator import ObjectTrackerGeneratorOptions, ObjectTrackerOutputGenerator
670    from dispatch_table_helper_generator import DispatchTableHelperOutputGenerator, DispatchTableHelperOutputGeneratorOptions
671    from helper_file_generator import HelperFileOutputGenerator, HelperFileOutputGeneratorOptions
672    from layer_dispatch_table_generator import LayerDispatchTableOutputGenerator, LayerDispatchTableGeneratorOptions
673    from layer_chassis_generator import LayerChassisOutputGenerator, LayerChassisGeneratorOptions
674    from layer_chassis_dispatch_generator import LayerChassisDispatchOutputGenerator, LayerChassisDispatchGeneratorOptions
675    # Temporary workaround for vkconventions python2 compatibility
676    import abc; abc.ABC = abc.ABCMeta('ABC', (object,), {})
677    from vkconventions import VulkanConventions
678
679    # This splits arguments which are space-separated lists
680    args.feature = [name for arg in args.feature for name in arg.split()]
681    args.extension = [name for arg in args.extension for name in arg.split()]
682
683    # Load & parse registry
684    reg = Registry()
685
686    startTimer(args.time)
687    tree = etree.parse(args.registry)
688    endTimer(args.time, '* Time to make ElementTree =')
689
690    if args.debug:
691        pdb.run('reg.loadElementTree(tree)')
692    else:
693        startTimer(args.time)
694        reg.loadElementTree(tree)
695        endTimer(args.time, '* Time to parse ElementTree =')
696
697    if (args.validate):
698        reg.validateGroups()
699
700    if (args.dump):
701        write('* Dumping registry to regdump.txt', file=sys.stderr)
702        reg.dumpReg(filehandle = open('regdump.txt', 'w', encoding='utf-8'))
703
704    # create error/warning & diagnostic files
705    if (args.errfile):
706        errWarn = open(args.errfile, 'w', encoding='utf-8')
707    else:
708        errWarn = sys.stderr
709
710    if (args.diagfile):
711        diag = open(args.diagfile, 'w', encoding='utf-8')
712    else:
713        diag = None
714
715    if (args.debug):
716        pdb.run('genTarget(args)')
717    elif (args.profile):
718        import cProfile, pstats
719        cProfile.run('genTarget(args)', 'profile.txt')
720        p = pstats.Stats('profile.txt')
721        p.strip_dirs().sort_stats('time').print_stats(50)
722    else:
723        genTarget(args)
724