• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python3
2#
3# Copyright 2013-2021 The Khronos Group Inc.
4#
5# SPDX-License-Identifier: Apache-2.0
6
7import argparse
8import pdb
9import re
10import sys
11import time
12import xml.etree.ElementTree as etree
13
14from cgenerator import CGeneratorOptions, COutputGenerator
15from cerealgenerator import CerealGenerator
16from docgenerator import DocGeneratorOptions, DocOutputGenerator
17from extensionmetadocgenerator import (ExtensionMetaDocGeneratorOptions,
18                                       ExtensionMetaDocOutputGenerator)
19from interfacedocgenerator import InterfaceDocGenerator
20from generator import write
21from spirvcapgenerator import SpirvCapabilityOutputGenerator
22from hostsyncgenerator import HostSynchronizationOutputGenerator
23from pygenerator import PyOutputGenerator
24from rubygenerator import RubyOutputGenerator
25from reflib import logDiag, logWarn, setLogFile
26from reg import Registry
27from validitygenerator import ValidityOutputGenerator
28from vkconventions import VulkanConventions
29
30
31# Simple timer functions
32startTime = None
33
34
35def startTimer(timeit):
36    global startTime
37    if timeit:
38        startTime = time.process_time()
39
40
41def endTimer(timeit, msg):
42    global startTime
43    if timeit:
44        endTime = time.process_time()
45        logDiag(msg, endTime - startTime)
46        startTime = None
47
48
49def makeREstring(strings, default=None, strings_are_regex=False):
50    """Turn a list of strings into a regexp string matching exactly those strings."""
51    if strings or default is None:
52        if not strings_are_regex:
53            strings = (re.escape(s) for s in strings)
54        return '^(' + '|'.join(strings) + ')$'
55    return default
56
57
58def makeGenOpts(args):
59    """Returns a directory of [ generator function, generator options ] indexed
60    by specified short names. The generator options incorporate the following
61    parameters:
62
63    args is an parsed argument object; see below for the fields that are used."""
64    global genOpts
65    genOpts = {}
66
67    # Default class of extensions to include, or None
68    defaultExtensions = args.defaultExtensions
69
70    # Additional extensions to include (list of extensions)
71    extensions = args.extension
72
73    # Extensions to remove (list of extensions)
74    removeExtensions = args.removeExtensions
75
76    # Extensions to emit (list of extensions)
77    emitExtensions = args.emitExtensions
78
79    # SPIR-V capabilities / features to emit (list of extensions & capabilities)
80    emitSpirv = args.emitSpirv
81
82    # Features to include (list of features)
83    features = args.feature
84
85    # Whether to disable inclusion protect in headers
86    protect = args.protect
87
88    # Output target directory
89    directory = args.directory
90
91    # Path to generated files, particularly api.py
92    genpath = args.genpath
93
94    # Generate MISRA C-friendly headers
95    misracstyle = args.misracstyle;
96
97    # Generate MISRA C++-friendly headers
98    misracppstyle = args.misracppstyle;
99
100    # Descriptive names for various regexp patterns used to select
101    # versions and extensions
102    allSpirv = allFeatures = allExtensions = r'.*'
103
104    # Turn lists of names/patterns into matching regular expressions
105    addExtensionsPat     = makeREstring(extensions, None)
106    removeExtensionsPat  = makeREstring(removeExtensions, None)
107    emitExtensionsPat    = makeREstring(emitExtensions, allExtensions)
108    emitSpirvPat         = makeREstring(emitSpirv, allSpirv)
109    featuresPat          = makeREstring(features, allFeatures)
110
111    # Copyright text prefixing all headers (list of strings).
112    # The SPDX formatting below works around constraints of the 'reuse' tool
113    prefixStrings = [
114        '/*',
115        '** Copyright 2015-2021 The Khronos Group Inc.',
116        '**',
117        '** SPDX' + '-License-Identifier: Apache-2.0',
118        '*/',
119        ''
120    ]
121
122    # Text specific to Vulkan headers
123    vkPrefixStrings = [
124        '/*',
125        '** This header is generated from the Khronos Vulkan XML API Registry.',
126        '**',
127        '*/',
128        ''
129    ]
130
131    # Defaults for generating re-inclusion protection wrappers (or not)
132    protectFile = protect
133
134    # An API style conventions object
135    conventions = VulkanConventions()
136
137    # API include files for spec and ref pages
138    # Overwrites include subdirectories in spec source tree
139    # The generated include files do not include the calling convention
140    # macros (apientry etc.), unlike the header files.
141    # Because the 1.0 core branch includes ref pages for extensions,
142    # all the extension interfaces need to be generated, even though
143    # none are used by the core spec itself.
144    genOpts['apiinc'] = [
145          DocOutputGenerator,
146          DocGeneratorOptions(
147            conventions       = conventions,
148            filename          = 'timeMarker',
149            directory         = directory,
150            genpath           = genpath,
151            apiname           = 'vulkan',
152            profile           = None,
153            versions          = featuresPat,
154            emitversions      = featuresPat,
155            defaultExtensions = None,
156            addExtensions     = addExtensionsPat,
157            removeExtensions  = removeExtensionsPat,
158            emitExtensions    = emitExtensionsPat,
159            prefixText        = prefixStrings + vkPrefixStrings,
160            apicall           = '',
161            apientry          = '',
162            apientryp         = '*',
163            alignFuncParam    = 48,
164            expandEnumerants  = False)
165        ]
166
167    # Python representation of API information, used by scripts that
168    # don't need to load the full XML.
169    genOpts['api.py'] = [
170          PyOutputGenerator,
171          DocGeneratorOptions(
172            conventions       = conventions,
173            filename          = 'api.py',
174            directory         = directory,
175            genpath           = None,
176            apiname           = 'vulkan',
177            profile           = None,
178            versions          = featuresPat,
179            emitversions      = featuresPat,
180            defaultExtensions = None,
181            addExtensions     = addExtensionsPat,
182            removeExtensions  = removeExtensionsPat,
183            emitExtensions    = emitExtensionsPat,
184            reparentEnums     = False)
185        ]
186
187    # Ruby representation of API information, used by scripts that
188    # don't need to load the full XML.
189    genOpts['api.rb'] = [
190          RubyOutputGenerator,
191          DocGeneratorOptions(
192            conventions       = conventions,
193            filename          = 'api.rb',
194            directory         = directory,
195            genpath           = None,
196            apiname           = 'vulkan',
197            profile           = None,
198            versions          = featuresPat,
199            emitversions      = featuresPat,
200            defaultExtensions = None,
201            addExtensions     = addExtensionsPat,
202            removeExtensions  = removeExtensionsPat,
203            emitExtensions    = emitExtensionsPat,
204            reparentEnums     = False)
205        ]
206
207
208    # API validity files for spec
209    #
210    # requireCommandAliases is set to True because we need validity files
211    # for the command something is promoted to even when the promoted-to
212    # feature is not included. This avoids wordy includes of validity files.
213    genOpts['validinc'] = [
214          ValidityOutputGenerator,
215          DocGeneratorOptions(
216            conventions       = conventions,
217            filename          = 'timeMarker',
218            directory         = directory,
219            genpath           = None,
220            apiname           = 'vulkan',
221            profile           = None,
222            versions          = featuresPat,
223            emitversions      = featuresPat,
224            defaultExtensions = None,
225            addExtensions     = addExtensionsPat,
226            removeExtensions  = removeExtensionsPat,
227            emitExtensions    = emitExtensionsPat,
228            requireCommandAliases = True,
229            )
230        ]
231
232    # Serializer for spec
233    genOpts['cereal'] = [
234            CerealGenerator,
235            CGeneratorOptions(
236                conventions       = conventions,
237                filename          = "CMakeLists.txt",
238                directory         = directory,
239                apiname           = 'vulkan',
240                profile           = None,
241                versions          = featuresPat,
242                emitversions      = featuresPat,
243                defaultExtensions = defaultExtensions,
244                addExtensions     = None,
245                removeExtensions  = removeExtensionsPat,
246                emitExtensions    = emitExtensionsPat,
247                prefixText        = prefixStrings + vkPrefixStrings,
248                genFuncPointers   = True,
249                protectFile       = protectFile,
250                protectFeature    = False,
251                protectProto      = '#ifndef',
252                protectProtoStr   = 'VK_NO_PROTOTYPES',
253                apicall           = 'VKAPI_ATTR ',
254                apientry          = 'VKAPI_CALL ',
255                apientryp         = 'VKAPI_PTR *',
256                alignFuncParam    = 48)
257        ]
258
259    gfxstreamPrefixStrings = [
260        '// Copyright (C) 2022 The Android Open Source Project',
261        '// Copyright (C) 2022 Google Inc.',
262        '//',
263        '// Licensed under the Apache License, Version 2.0 (the "License");',
264        '// you may not use this file except in compliance with the License.',
265        '// You may obtain a copy of the License at',
266        '//',
267        '// http://www.apache.org/licenses/LICENSE-2.0',
268        '//',
269        '// Unless required by applicable law or agreed to in writing, software',
270        '// distributed under the License is distributed on an "AS IS" BASIS,',
271        '// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
272        '// See the License for the specific language governing permissions and',
273        '// limitations under the License.',
274        '//',
275        '// Autogenerated header vulkan_gfxstream.h',
276        '// Please do not modify directly;',
277        '// re-run gfxstream-protocols/scripts/generate-vulkan-sources.sh,',
278        '// or directly from Python by calling the genvk.py script with correct parameters.',
279        '',
280        '#pragma once',
281        '#ifdef VK_GFXSTREAM_STRUCTURE_TYPE_EXT',
282        '#include "vulkan_gfxstream_structure_type.h"',
283        '#endif',
284    ]
285    # gfxstream specific header
286    genOpts['vulkan_gfxstream.h'] = [
287          COutputGenerator,
288          CGeneratorOptions(
289            conventions       = conventions,
290            filename          = 'vulkan_gfxstream.h',
291            directory         = directory,
292            genpath           = None,
293            apiname           = 'vulkan',
294            profile           = None,
295            versions          = featuresPat,
296            emitversions      = None,
297            defaultExtensions = None,
298            addExtensions     = makeREstring(['VK_GOOGLE_gfxstream'], None),
299            removeExtensions  = None,
300            emitExtensions    = makeREstring(['VK_GOOGLE_gfxstream'], None),
301            prefixText        = gfxstreamPrefixStrings,
302            genFuncPointers   = True,
303            # Use #pragma once in the prefixText instead, so that we can put the copyright comments
304            # at the beginning of the file.
305            protectFile       = False,
306            protectFeature    = False,
307            protectProto      = '#ifndef',
308            protectProtoStr   = 'VK_NO_PROTOTYPES',
309            apicall           = 'VKAPI_ATTR ',
310            apientry          = 'VKAPI_CALL ',
311            apientryp         = 'VKAPI_PTR *',
312            alignFuncParam    = 48,
313            misracstyle       = misracstyle,
314            misracppstyle     = misracppstyle)
315        ]
316
317    androidNativeBufferPrefixStrings = [
318        '// Copyright (C) 2022 The Android Open Source Project',
319        '// Copyright (C) 2022 Google Inc.',
320        '//',
321        '// Licensed under the Apache License, Version 2.0 (the "License");',
322        '// you may not use this file except in compliance with the License.',
323        '// You may obtain a copy of the License at',
324        '//',
325        '// http://www.apache.org/licenses/LICENSE-2.0',
326        '//',
327        '// Unless required by applicable law or agreed to in writing, software',
328        '// distributed under the License is distributed on an "AS IS" BASIS,',
329        '// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
330        '// See the License for the specific language governing permissions and',
331        '// limitations under the License.',
332        '//',
333        '// Autogenerated header vk_android_native_buffer.h',
334        '// Please do not modify directly;',
335        '// re-run gfxstream-protocols/scripts/generate-vulkan-sources.sh,',
336        '// or directly from Python by calling the genvk.py script with correct parameters.',
337        '',
338        '#pragma once',
339        '#ifndef VK_ANDROID_native_buffer',
340        '#include "vk_android_native_buffer_structure_type.h"',
341        '#endif /* VK_ANDROID_native_buffer */',
342    ]
343    #  header
344    genOpts['vk_android_native_buffer.h'] = [
345          COutputGenerator,
346          CGeneratorOptions(
347            conventions       = conventions,
348            filename          = 'vk_android_native_buffer.h',
349            directory         = directory,
350            genpath           = None,
351            apiname           = 'vulkan',
352            profile           = None,
353            versions          = featuresPat,
354            emitversions      = None,
355            defaultExtensions = None,
356            addExtensions     = makeREstring(['VK_ANDROID_native_buffer'], None),
357            removeExtensions  = None,
358            emitExtensions    = makeREstring(['VK_ANDROID_native_buffer'], None),
359            prefixText        = androidNativeBufferPrefixStrings,
360            genFuncPointers   = True,
361            # Use #pragma once in the prefixText instead, so that we can put the copyright comments
362            # at the beginning of the file.
363            protectFile       = False,
364            protectFeature    = True,
365            protectProto      = '#ifndef',
366            protectProtoStr   = 'VK_NO_PROTOTYPES',
367            apicall           = 'VKAPI_ATTR ',
368            apientry          = 'VKAPI_CALL ',
369            apientryp         = 'VKAPI_PTR *',
370            alignFuncParam    = 48,
371            misracstyle       = misracstyle,
372            misracppstyle     = misracppstyle)
373        ]
374
375    # API host sync table files for spec
376    genOpts['hostsyncinc'] = [
377          HostSynchronizationOutputGenerator,
378          DocGeneratorOptions(
379            conventions       = conventions,
380            filename          = 'timeMarker',
381            directory         = directory,
382            genpath           = None,
383            apiname           = 'vulkan',
384            profile           = None,
385            versions          = featuresPat,
386            emitversions      = featuresPat,
387            defaultExtensions = None,
388            addExtensions     = addExtensionsPat,
389            removeExtensions  = removeExtensionsPat,
390            emitExtensions    = emitExtensionsPat,
391            reparentEnums     = False)
392        ]
393
394    # Extension metainformation for spec extension appendices
395    # Includes all extensions by default, but only so that the generated
396    # 'promoted_extensions_*' files refer to all extensions that were
397    # promoted to a core version.
398    genOpts['extinc'] = [
399          ExtensionMetaDocOutputGenerator,
400          ExtensionMetaDocGeneratorOptions(
401            conventions       = conventions,
402            filename          = 'timeMarker',
403            directory         = directory,
404            genpath           = None,
405            apiname           = 'vulkan',
406            profile           = None,
407            versions          = featuresPat,
408            emitversions      = None,
409            defaultExtensions = defaultExtensions,
410            addExtensions     = addExtensionsPat,
411            removeExtensions  = None,
412            emitExtensions    = emitExtensionsPat)
413        ]
414
415    # Version and extension interface docs for version/extension appendices
416    # Includes all extensions by default.
417    genOpts['interfaceinc'] = [
418          InterfaceDocGenerator,
419          DocGeneratorOptions(
420            conventions       = conventions,
421            filename          = 'timeMarker',
422            directory         = directory,
423            genpath           = None,
424            apiname           = 'vulkan',
425            profile           = None,
426            versions          = featuresPat,
427            emitversions      = featuresPat,
428            defaultExtensions = None,
429            addExtensions     = addExtensionsPat,
430            removeExtensions  = removeExtensionsPat,
431            emitExtensions    = emitExtensionsPat,
432            reparentEnums     = False)
433        ]
434
435    genOpts['spirvcapinc'] = [
436          SpirvCapabilityOutputGenerator,
437          DocGeneratorOptions(
438            conventions       = conventions,
439            filename          = 'timeMarker',
440            directory         = directory,
441            genpath           = None,
442            apiname           = 'vulkan',
443            profile           = None,
444            versions          = featuresPat,
445            emitversions      = featuresPat,
446            defaultExtensions = None,
447            addExtensions     = addExtensionsPat,
448            removeExtensions  = removeExtensionsPat,
449            emitExtensions    = emitExtensionsPat,
450            emitSpirv         = emitSpirvPat,
451            reparentEnums     = False)
452        ]
453
454    # Platform extensions, in their own header files
455    # Each element of the platforms[] array defines information for
456    # generating a single platform:
457    #   [0] is the generated header file name
458    #   [1] is the set of platform extensions to generate
459    #   [2] is additional extensions whose interfaces should be considered,
460    #   but suppressed in the output, to avoid duplicate definitions of
461    #   dependent types like VkDisplayKHR and VkSurfaceKHR which come from
462    #   non-platform extensions.
463
464    # Track all platform extensions, for exclusion from vulkan_core.h
465    allPlatformExtensions = []
466
467    # Extensions suppressed for all WSI platforms (WSI extensions required
468    # by all platforms)
469    commonSuppressExtensions = [ 'VK_KHR_display', 'VK_KHR_swapchain' ]
470
471    # Extensions required and suppressed for beta "platform". This can
472    # probably eventually be derived from the requires= attributes of
473    # the extension blocks.
474    betaRequireExtensions = [
475        'VK_KHR_portability_subset',
476        'VK_KHR_video_queue',
477        'VK_KHR_video_decode_queue',
478        'VK_KHR_video_encode_queue',
479        'VK_EXT_video_decode_h264',
480        'VK_EXT_video_decode_h265',
481        'VK_EXT_video_encode_h264',
482        'VK_EXT_video_encode_h265',
483    ]
484
485    betaSuppressExtensions = []
486
487    platforms = [
488        [ 'vulkan_android.h',     [ 'VK_KHR_android_surface',
489                                    'VK_ANDROID_external_memory_android_hardware_buffer'
490                                                                  ], commonSuppressExtensions +
491                                                                     [ 'VK_KHR_format_feature_flags2',
492                                                                     ] ],
493        [ 'vulkan_fuchsia.h',     [ 'VK_FUCHSIA_imagepipe_surface',
494                                    'VK_FUCHSIA_external_memory',
495                                    'VK_FUCHSIA_external_semaphore',
496                                    'VK_FUCHSIA_buffer_collection' ], commonSuppressExtensions ],
497        [ 'vulkan_ggp.h',         [ 'VK_GGP_stream_descriptor_surface',
498                                    'VK_GGP_frame_token'          ], commonSuppressExtensions ],
499        [ 'vulkan_ios.h',         [ 'VK_MVK_ios_surface'          ], commonSuppressExtensions ],
500        [ 'vulkan_macos.h',       [ 'VK_MVK_macos_surface'        ], commonSuppressExtensions ],
501        [ 'vulkan_vi.h',          [ 'VK_NN_vi_surface'            ], commonSuppressExtensions ],
502        [ 'vulkan_wayland.h',     [ 'VK_KHR_wayland_surface'      ], commonSuppressExtensions ],
503        [ 'vulkan_win32.h',       [ 'VK_.*_win32(|_.*)', 'VK_EXT_full_screen_exclusive' ],
504                                                                     commonSuppressExtensions +
505                                                                     [ 'VK_KHR_external_semaphore',
506                                                                       'VK_KHR_external_memory_capabilities',
507                                                                       'VK_KHR_external_fence',
508                                                                       'VK_KHR_external_fence_capabilities',
509                                                                       'VK_KHR_get_surface_capabilities2',
510                                                                       'VK_NV_external_memory_capabilities',
511                                                                     ] ],
512        [ 'vulkan_xcb.h',         [ 'VK_KHR_xcb_surface'          ], commonSuppressExtensions ],
513        [ 'vulkan_xlib.h',        [ 'VK_KHR_xlib_surface'         ], commonSuppressExtensions ],
514        [ 'vulkan_directfb.h',    [ 'VK_EXT_directfb_surface'     ], commonSuppressExtensions ],
515        [ 'vulkan_xlib_xrandr.h', [ 'VK_EXT_acquire_xlib_display' ], commonSuppressExtensions ],
516        [ 'vulkan_metal.h',       [ 'VK_EXT_metal_surface'        ], commonSuppressExtensions ],
517        [ 'vulkan_screen.h',      [ 'VK_QNX_screen_surface'       ], commonSuppressExtensions ],
518        [ 'vulkan_beta.h',        betaRequireExtensions,             betaSuppressExtensions ],
519    ]
520
521    for platform in platforms:
522        headername = platform[0]
523
524        allPlatformExtensions += platform[1]
525
526        addPlatformExtensionsRE = makeREstring(
527            platform[1] + platform[2], strings_are_regex=True)
528        emitPlatformExtensionsRE = makeREstring(
529            platform[1], strings_are_regex=True)
530
531        opts = CGeneratorOptions(
532            conventions       = conventions,
533            filename          = headername,
534            directory         = directory,
535            genpath           = None,
536            apiname           = 'vulkan',
537            profile           = None,
538            versions          = featuresPat,
539            emitversions      = None,
540            defaultExtensions = None,
541            addExtensions     = addPlatformExtensionsRE,
542            removeExtensions  = None,
543            emitExtensions    = emitPlatformExtensionsRE,
544            prefixText        = prefixStrings + vkPrefixStrings,
545            genFuncPointers   = True,
546            protectFile       = protectFile,
547            protectFeature    = False,
548            protectProto      = '#ifndef',
549            protectProtoStr   = 'VK_NO_PROTOTYPES',
550            apicall           = 'VKAPI_ATTR ',
551            apientry          = 'VKAPI_CALL ',
552            apientryp         = 'VKAPI_PTR *',
553            alignFuncParam    = 48,
554            misracstyle       = misracstyle,
555            misracppstyle     = misracppstyle)
556
557        genOpts[headername] = [ COutputGenerator, opts ]
558
559    # Header for core API + extensions.
560    # To generate just the core API,
561    # change to 'defaultExtensions = None' below.
562    #
563    # By default this adds all enabled, non-platform extensions.
564    # It removes all platform extensions (from the platform headers options
565    # constructed above) as well as any explicitly specified removals.
566
567    removeExtensionsPat = makeREstring(
568        allPlatformExtensions + removeExtensions, None, strings_are_regex=True)
569
570    genOpts['vulkan_core.h'] = [
571          COutputGenerator,
572          CGeneratorOptions(
573            conventions       = conventions,
574            filename          = 'vulkan_core.h',
575            directory         = directory,
576            genpath           = None,
577            apiname           = 'vulkan',
578            profile           = None,
579            versions          = featuresPat,
580            emitversions      = featuresPat,
581            defaultExtensions = defaultExtensions,
582            addExtensions     = addExtensionsPat,
583            removeExtensions  = removeExtensionsPat,
584            emitExtensions    = emitExtensionsPat,
585            prefixText        = prefixStrings + vkPrefixStrings,
586            genFuncPointers   = True,
587            protectFile       = protectFile,
588            protectFeature    = False,
589            protectProto      = '#ifndef',
590            protectProtoStr   = 'VK_NO_PROTOTYPES',
591            apicall           = 'VKAPI_ATTR ',
592            apientry          = 'VKAPI_CALL ',
593            apientryp         = 'VKAPI_PTR *',
594            alignFuncParam    = 48,
595            misracstyle       = misracstyle,
596            misracppstyle     = misracppstyle)
597        ]
598
599    # Unused - vulkan10.h target.
600    # It is possible to generate a header with just the Vulkan 1.0 +
601    # extension interfaces defined, but since the promoted KHR extensions
602    # are now defined in terms of the 1.1 interfaces, such a header is very
603    # similar to vulkan_core.h.
604    genOpts['vulkan10.h'] = [
605          COutputGenerator,
606          CGeneratorOptions(
607            conventions       = conventions,
608            filename          = 'vulkan10.h',
609            directory         = directory,
610            genpath           = None,
611            apiname           = 'vulkan',
612            profile           = None,
613            versions          = 'VK_VERSION_1_0',
614            emitversions      = 'VK_VERSION_1_0',
615            defaultExtensions = None,
616            addExtensions     = None,
617            removeExtensions  = None,
618            emitExtensions    = None,
619            prefixText        = prefixStrings + vkPrefixStrings,
620            genFuncPointers   = True,
621            protectFile       = protectFile,
622            protectFeature    = False,
623            protectProto      = '#ifndef',
624            protectProtoStr   = 'VK_NO_PROTOTYPES',
625            apicall           = 'VKAPI_ATTR ',
626            apientry          = 'VKAPI_CALL ',
627            apientryp         = 'VKAPI_PTR *',
628            alignFuncParam    = 48,
629            misracstyle       = misracstyle,
630            misracppstyle     = misracppstyle)
631        ]
632
633    # Unused - vulkan11.h target.
634    # It is possible to generate a header with just the Vulkan 1.0 +
635    # extension interfaces defined, but since the promoted KHR extensions
636    # are now defined in terms of the 1.1 interfaces, such a header is very
637    # similar to vulkan_core.h.
638    genOpts['vulkan11.h'] = [
639          COutputGenerator,
640          CGeneratorOptions(
641            conventions       = conventions,
642            filename          = 'vulkan11.h',
643            directory         = directory,
644            genpath           = None,
645            apiname           = 'vulkan',
646            profile           = None,
647            versions          = '^VK_VERSION_1_[01]$',
648            emitversions      = '^VK_VERSION_1_[01]$',
649            defaultExtensions = None,
650            addExtensions     = None,
651            removeExtensions  = None,
652            emitExtensions    = None,
653            prefixText        = prefixStrings + vkPrefixStrings,
654            genFuncPointers   = True,
655            protectFile       = protectFile,
656            protectFeature    = False,
657            protectProto      = '#ifndef',
658            protectProtoStr   = 'VK_NO_PROTOTYPES',
659            apicall           = 'VKAPI_ATTR ',
660            apientry          = 'VKAPI_CALL ',
661            apientryp         = 'VKAPI_PTR *',
662            alignFuncParam    = 48,
663            misracstyle       = misracstyle,
664            misracppstyle     = misracppstyle)
665        ]
666
667    genOpts['alias.h'] = [
668          COutputGenerator,
669          CGeneratorOptions(
670            conventions       = conventions,
671            filename          = 'alias.h',
672            directory         = directory,
673            genpath           = None,
674            apiname           = 'vulkan',
675            profile           = None,
676            versions          = featuresPat,
677            emitversions      = featuresPat,
678            defaultExtensions = defaultExtensions,
679            addExtensions     = None,
680            removeExtensions  = removeExtensionsPat,
681            emitExtensions    = emitExtensionsPat,
682            prefixText        = None,
683            genFuncPointers   = False,
684            protectFile       = False,
685            protectFeature    = False,
686            protectProto      = '',
687            protectProtoStr   = '',
688            apicall           = '',
689            apientry          = '',
690            apientryp         = '',
691            alignFuncParam    = 36)
692        ]
693
694
695def genTarget(args):
696    """Create an API generator and corresponding generator options based on
697    the requested target and command line options.
698
699    This is encapsulated in a function so it can be profiled and/or timed.
700    The args parameter is an parsed argument object containing the following
701    fields that are used:
702
703    - target - target to generate
704    - directory - directory to generate it in
705    - protect - True if re-inclusion wrappers should be created
706    - extensions - list of additional extensions to include in generated interfaces"""
707
708    # Create generator options with parameters specified on command line
709    makeGenOpts(args)
710
711    # pdb.set_trace()
712
713    # Select a generator matching the requested target
714    if args.target in genOpts:
715        createGenerator = genOpts[args.target][0]
716        options = genOpts[args.target][1]
717
718        logDiag('* Building', options.filename)
719        logDiag('* options.versions          =', options.versions)
720        logDiag('* options.emitversions      =', options.emitversions)
721        logDiag('* options.defaultExtensions =', options.defaultExtensions)
722        logDiag('* options.addExtensions     =', options.addExtensions)
723        logDiag('* options.removeExtensions  =', options.removeExtensions)
724        logDiag('* options.emitExtensions    =', options.emitExtensions)
725
726        gen = createGenerator(errFile=errWarn,
727                              warnFile=errWarn,
728                              diagFile=diag)
729        return (gen, options)
730    else:
731        logErr('No generator options for unknown target:', args.target)
732        return None
733
734
735# -feature name
736# -extension name
737# For both, "name" may be a single name, or a space-separated list
738# of names, or a regular expression.
739if __name__ == '__main__':
740    parser = argparse.ArgumentParser()
741
742    parser.add_argument('-defaultExtensions', action='store',
743                        default='vulkan',
744                        help='Specify a single class of extensions to add to targets')
745    parser.add_argument('-extension', action='append',
746                        default=[],
747                        help='Specify an extension or extensions to add to targets')
748    parser.add_argument('-removeExtensions', action='append',
749                        default=[],
750                        help='Specify an extension or extensions to remove from targets')
751    parser.add_argument('-emitExtensions', action='append',
752                        default=[],
753                        help='Specify an extension or extensions to emit in targets')
754    parser.add_argument('-emitSpirv', action='append',
755                        default=[],
756                        help='Specify a SPIR-V extension or capability to emit in targets')
757    parser.add_argument('-feature', action='append',
758                        default=[],
759                        help='Specify a core API feature name or names to add to targets')
760    parser.add_argument('-debug', action='store_true',
761                        help='Enable debugging')
762    parser.add_argument('-dump', action='store_true',
763                        help='Enable dump to stderr')
764    parser.add_argument('-diagfile', action='store',
765                        default=None,
766                        help='Write diagnostics to specified file')
767    parser.add_argument('-errfile', action='store',
768                        default=None,
769                        help='Write errors and warnings to specified file instead of stderr')
770    parser.add_argument('-noprotect', dest='protect', action='store_false',
771                        help='Disable inclusion protection in output headers')
772    parser.add_argument('-profile', action='store_true',
773                        help='Enable profiling')
774    parser.add_argument('-registry', action='store',
775                        default='vk.xml',
776                        help='Use specified registry file instead of vk.xml')
777    parser.add_argument('-time', action='store_true',
778                        help='Enable timing')
779    parser.add_argument('-validate', action='store_true',
780                        help='Validate the registry properties and exit')
781    parser.add_argument('-genpath', action='store', default='gen',
782                        help='Path to generated files')
783    parser.add_argument('-o', action='store', dest='directory',
784                        default='.',
785                        help='Create target and related files in specified directory')
786    parser.add_argument('target', metavar='target', nargs='?',
787                        help='Specify target')
788    parser.add_argument('-quiet', action='store_true', default=True,
789                        help='Suppress script output during normal execution.')
790    parser.add_argument('-verbose', action='store_false', dest='quiet', default=True,
791                        help='Enable script output during normal execution.')
792    parser.add_argument('-misracstyle', dest='misracstyle', action='store_true',
793                        help='generate MISRA C-friendly headers')
794    parser.add_argument('-misracppstyle', dest='misracppstyle', action='store_true',
795                        help='generate MISRA C++-friendly headers')
796
797    args = parser.parse_args()
798
799    # This splits arguments which are space-separated lists
800    args.feature = [name for arg in args.feature for name in arg.split()]
801    args.extension = [name for arg in args.extension for name in arg.split()]
802
803    # create error/warning & diagnostic files
804    if args.errfile:
805        errWarn = open(args.errfile, 'w', encoding='utf-8')
806    else:
807        errWarn = sys.stderr
808
809    if args.diagfile:
810        diag = open(args.diagfile, 'w', encoding='utf-8')
811    else:
812        diag = None
813
814    if args.time:
815        # Log diagnostics and warnings
816        setLogFile(setDiag = True, setWarn = True, filename = '-')
817
818    (gen, options) = (None, None)
819    if not args.validate:
820      # Create the API generator & generator options
821      (gen, options) = genTarget(args)
822
823    # Create the registry object with the specified generator and generator
824    # options. The options are set before XML loading as they may affect it.
825    reg = Registry(gen, options)
826
827    # Parse the specified registry XML into an ElementTree object
828    startTimer(args.time)
829    tree = etree.parse(args.registry)
830    endTimer(args.time, '* Time to make ElementTree =')
831
832    # Load the XML tree into the registry object
833    startTimer(args.time)
834    reg.loadElementTree(tree)
835    endTimer(args.time, '* Time to parse ElementTree =')
836
837    if args.validate:
838        success = reg.validateRegistry()
839        sys.exit(0 if success else 1)
840
841    if args.dump:
842        logDiag('* Dumping registry to regdump.txt')
843        reg.dumpReg(filehandle=open('regdump.txt', 'w', encoding='utf-8'))
844
845    # Finally, use the output generator to create the requested target
846    if args.debug:
847        pdb.run('reg.apiGen()')
848    else:
849        startTimer(args.time)
850        reg.apiGen()
851        endTimer(args.time, '* Time to generate ' + options.filename + ' =')
852
853    if not args.quiet:
854        logDiag('* Generated', options.filename)
855