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