1# coding=utf-8 2# 3# Copyright © 2015, 2017 Intel Corporation 4# 5# Permission is hereby granted, free of charge, to any person obtaining a 6# copy of this software and associated documentation files (the "Software"), 7# to deal in the Software without restriction, including without limitation 8# the rights to use, copy, modify, merge, publish, distribute, sublicense, 9# and/or sell copies of the Software, and to permit persons to whom the 10# Software is furnished to do so, subject to the following conditions: 11# 12# The above copyright notice and this permission notice (including the next 13# paragraph) shall be included in all copies or substantial portions of the 14# Software. 15# 16# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22# IN THE SOFTWARE. 23# 24 25import argparse 26import math 27import os 28import xml.etree.cElementTree as et 29 30from collections import OrderedDict, namedtuple 31from mako.template import Template 32 33from v3dv_extensions import VkVersion, MAX_API_VERSION, EXTENSIONS 34 35# We currently don't use layers in v3dv, but keeping the ability for anv 36# anyways, so we can use it for device groups. 37 38LAYERS = [ 39 'v3dv' 40] 41 42TEMPLATE_H = Template("""\ 43/* This file generated from ${filename}, don't edit directly. */ 44 45struct v3dv_instance_dispatch_table { 46 union { 47 void *entrypoints[${len(instance_entrypoints)}]; 48 struct { 49 % for e in instance_entrypoints: 50 % if e.guard is not None: 51#ifdef ${e.guard} 52 PFN_${e.name} ${e.name}; 53#else 54 void *${e.name}; 55# endif 56 % else: 57 PFN_${e.name} ${e.name}; 58 % endif 59 % endfor 60 }; 61 }; 62}; 63 64struct v3dv_physical_device_dispatch_table { 65 union { 66 void *entrypoints[${len(physical_device_entrypoints)}]; 67 struct { 68 % for e in physical_device_entrypoints: 69 % if e.guard is not None: 70#ifdef ${e.guard} 71 PFN_${e.name} ${e.name}; 72#else 73 void *${e.name}; 74# endif 75 % else: 76 PFN_${e.name} ${e.name}; 77 % endif 78 % endfor 79 }; 80 }; 81}; 82 83struct v3dv_device_dispatch_table { 84 union { 85 void *entrypoints[${len(device_entrypoints)}]; 86 struct { 87 % for e in device_entrypoints: 88 % if e.guard is not None: 89#ifdef ${e.guard} 90 PFN_${e.name} ${e.name}; 91#else 92 void *${e.name}; 93# endif 94 % else: 95 PFN_${e.name} ${e.name}; 96 % endif 97 % endfor 98 }; 99 }; 100}; 101 102extern const struct v3dv_instance_dispatch_table v3dv_instance_dispatch_table; 103%for layer in LAYERS: 104extern const struct v3dv_physical_device_dispatch_table ${layer}_physical_device_dispatch_table; 105%endfor 106%for layer in LAYERS: 107extern const struct v3dv_device_dispatch_table ${layer}_device_dispatch_table; 108%endfor 109 110% for e in instance_entrypoints: 111 % if e.alias: 112 <% continue %> 113 % endif 114 % if e.guard is not None: 115#ifdef ${e.guard} 116 % endif 117 ${e.return_type} ${e.prefixed_name('v3dv')}(${e.decl_params()}); 118 % if e.guard is not None: 119#endif // ${e.guard} 120 % endif 121% endfor 122 123% for e in physical_device_entrypoints: 124 % if e.alias: 125 <% continue %> 126 % endif 127 % if e.guard is not None: 128#ifdef ${e.guard} 129 % endif 130 % for layer in LAYERS: 131 ${e.return_type} ${e.prefixed_name(layer)}(${e.decl_params()}); 132 % endfor 133 % if e.guard is not None: 134#endif // ${e.guard} 135 % endif 136% endfor 137 138% for e in device_entrypoints: 139 % if e.alias: 140 <% continue %> 141 % endif 142 % if e.guard is not None: 143#ifdef ${e.guard} 144 % endif 145 % for layer in LAYERS: 146 ${e.return_type} ${e.prefixed_name(layer)}(${e.decl_params()}); 147 % endfor 148 % if e.guard is not None: 149#endif // ${e.guard} 150 % endif 151% endfor 152""", output_encoding='utf-8') 153 154TEMPLATE_C = Template(u"""\ 155/* 156 * Copyright © 2015 Intel Corporation 157 * 158 * Permission is hereby granted, free of charge, to any person obtaining a 159 * copy of this software and associated documentation files (the "Software"), 160 * to deal in the Software without restriction, including without limitation 161 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 162 * and/or sell copies of the Software, and to permit persons to whom the 163 * Software is furnished to do so, subject to the following conditions: 164 * 165 * The above copyright notice and this permission notice (including the next 166 * paragraph) shall be included in all copies or substantial portions of the 167 * Software. 168 * 169 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 170 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 171 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 172 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 173 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 174 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 175 * IN THE SOFTWARE. 176 */ 177 178/* This file generated from ${filename}, don't edit directly. */ 179 180#include "v3dv_private.h" 181 182#include "util/macros.h" 183 184struct string_map_entry { 185 uint32_t name; 186 uint32_t hash; 187 uint32_t num; 188}; 189 190/* We use a big string constant to avoid lots of reloctions from the entry 191 * point table to lots of little strings. The entries in the entry point table 192 * store the index into this big string. 193 */ 194 195<%def name="strmap(strmap, prefix)"> 196static const char ${prefix}_strings[] = 197% for s in strmap.sorted_strings: 198 "${s.string}\\0" 199% endfor 200; 201 202static const struct string_map_entry ${prefix}_string_map_entries[] = { 203% for s in strmap.sorted_strings: 204 { ${s.offset}, ${'{:0=#8x}'.format(s.hash)}, ${s.num} }, /* ${s.string} */ 205% endfor 206}; 207 208/* Hash table stats: 209 * size ${len(strmap.sorted_strings)} entries 210 * collisions entries: 211% for i in range(10): 212 * ${i}${'+' if i == 9 else ' '} ${strmap.collisions[i]} 213% endfor 214 */ 215 216#define none 0xffff 217static const uint16_t ${prefix}_string_map[${strmap.hash_size}] = { 218% for e in strmap.mapping: 219 ${ '{:0=#6x}'.format(e) if e >= 0 else 'none' }, 220% endfor 221}; 222 223static int 224${prefix}_string_map_lookup(const char *str) 225{ 226 static const uint32_t prime_factor = ${strmap.prime_factor}; 227 static const uint32_t prime_step = ${strmap.prime_step}; 228 const struct string_map_entry *e; 229 uint32_t hash, h; 230 uint16_t i; 231 const char *p; 232 233 hash = 0; 234 for (p = str; *p; p++) 235 hash = hash * prime_factor + *p; 236 237 h = hash; 238 while (1) { 239 i = ${prefix}_string_map[h & ${strmap.hash_mask}]; 240 if (i == none) 241 return -1; 242 e = &${prefix}_string_map_entries[i]; 243 if (e->hash == hash && strcmp(str, ${prefix}_strings + e->name) == 0) 244 return e->num; 245 h += prime_step; 246 } 247 248 return -1; 249} 250 251static const char * 252${prefix}_entry_name(int num) 253{ 254 for (int i = 0; i < ARRAY_SIZE(${prefix}_string_map_entries); i++) { 255 if (${prefix}_string_map_entries[i].num == num) 256 return &${prefix}_strings[${prefix}_string_map_entries[i].name]; 257 } 258 return NULL; 259} 260</%def> 261 262${strmap(instance_strmap, 'instance')} 263${strmap(physical_device_strmap, 'physical_device')} 264${strmap(device_strmap, 'device')} 265 266/* Weak aliases for all potential implementations. These will resolve to 267 * NULL if they're not defined, which lets the resolve_entrypoint() function 268 * either pick the correct entry point. 269 */ 270 271% for e in instance_entrypoints: 272 % if e.alias: 273 <% continue %> 274 % endif 275 % if e.guard is not None: 276#ifdef ${e.guard} 277 % endif 278 ${e.return_type} ${e.prefixed_name('v3dv')}(${e.decl_params()}) __attribute__ ((weak)); 279 % if e.guard is not None: 280#endif // ${e.guard} 281 % endif 282% endfor 283 284const struct v3dv_instance_dispatch_table v3dv_instance_dispatch_table = { 285% for e in instance_entrypoints: 286 % if e.guard is not None: 287#ifdef ${e.guard} 288 % endif 289 .${e.name} = ${e.prefixed_name('v3dv')}, 290 % if e.guard is not None: 291#endif // ${e.guard} 292 % endif 293% endfor 294}; 295 296% for layer in LAYERS: 297 % for e in physical_device_entrypoints: 298 % if e.alias: 299 <% continue %> 300 % endif 301 % if e.guard is not None: 302#ifdef ${e.guard} 303 % endif 304 % if layer == 'v3dv': 305 ${e.return_type} __attribute__ ((weak)) 306 ${e.prefixed_name('v3dv')}(${e.decl_params()}) 307 { 308 % if e.params[0].type == 'VkPhysicalDevice': 309 V3DV_FROM_HANDLE(v3dv_physical_device, v3dv_physical_device, ${e.params[0].name}); 310 return v3dv_physical_device->dispatch.${e.name}(${e.call_params()}); 311 % else: 312 assert(!"Unhandled device child trampoline case: ${e.params[0].type}"); 313 % endif 314 } 315 % else: 316 ${e.return_type} ${e.prefixed_name(layer)}(${e.decl_params()}) __attribute__ ((weak)); 317 % endif 318 % if e.guard is not None: 319#endif // ${e.guard} 320 % endif 321 % endfor 322 323 const struct v3dv_physical_device_dispatch_table ${layer}_physical_device_dispatch_table = { 324 % for e in physical_device_entrypoints: 325 % if e.guard is not None: 326#ifdef ${e.guard} 327 % endif 328 .${e.name} = ${e.prefixed_name(layer)}, 329 % if e.guard is not None: 330#endif // ${e.guard} 331 % endif 332 % endfor 333 }; 334% endfor 335 336 337% for layer in LAYERS: 338 % for e in device_entrypoints: 339 % if e.alias: 340 <% continue %> 341 % endif 342 % if e.guard is not None: 343#ifdef ${e.guard} 344 % endif 345 % if layer == 'v3dv': 346 ${e.return_type} __attribute__ ((weak)) 347 ${e.prefixed_name('v3dv')}(${e.decl_params()}) 348 { 349 % if e.params[0].type == 'VkDevice': 350 V3DV_FROM_HANDLE(v3dv_device, v3dv_device, ${e.params[0].name}); 351 return v3dv_device->dispatch.${e.name}(${e.call_params()}); 352 % elif e.params[0].type == 'VkCommandBuffer': 353 V3DV_FROM_HANDLE(v3dv_cmd_buffer, v3dv_cmd_buffer, ${e.params[0].name}); 354 return v3dv_cmd_buffer->device->dispatch.${e.name}(${e.call_params()}); 355 % elif e.params[0].type == 'VkQueue': 356 V3DV_FROM_HANDLE(v3dv_queue, v3dv_queue, ${e.params[0].name}); 357 return v3dv_queue->device->dispatch.${e.name}(${e.call_params()}); 358 % else: 359 assert(!"Unhandled device child trampoline case: ${e.params[0].type}"); 360 % endif 361 } 362 % else: 363 ${e.return_type} ${e.prefixed_name(layer)}(${e.decl_params()}) __attribute__ ((weak)); 364 % endif 365 % if e.guard is not None: 366#endif // ${e.guard} 367 % endif 368 % endfor 369 370 const struct v3dv_device_dispatch_table ${layer}_device_dispatch_table = { 371 % for e in device_entrypoints: 372 % if e.guard is not None: 373#ifdef ${e.guard} 374 % endif 375 .${e.name} = ${e.prefixed_name(layer)}, 376 % if e.guard is not None: 377#endif // ${e.guard} 378 % endif 379 % endfor 380 }; 381% endfor 382 383 384/** Return true if the core version or extension in which the given entrypoint 385 * is defined is enabled. 386 * 387 * If device is NULL, all device extensions are considered enabled. 388 */ 389bool 390v3dv_instance_entrypoint_is_enabled(int index, uint32_t core_version, 391 const struct v3dv_instance_extension_table *instance) 392{ 393 switch (index) { 394% for e in instance_entrypoints: 395 case ${e.num}: 396 /* ${e.name} */ 397 % if e.core_version: 398 return ${e.core_version.c_vk_version()} <= core_version; 399 % elif e.extensions: 400 % for ext in e.extensions: 401 % if ext.type == 'instance': 402 if (instance->${ext.name[3:]}) return true; 403 % else: 404 /* All device extensions are considered enabled at the instance level */ 405 return true; 406 % endif 407 % endfor 408 return false; 409 % else: 410 return true; 411 % endif 412% endfor 413 default: 414 return false; 415 } 416} 417 418/** Return true if the core version or extension in which the given entrypoint 419 * is defined is enabled. 420 * 421 * If device is NULL, all device extensions are considered enabled. 422 */ 423bool 424v3dv_physical_device_entrypoint_is_enabled(int index, uint32_t core_version, 425 const struct v3dv_instance_extension_table *instance) 426{ 427 switch (index) { 428% for e in physical_device_entrypoints: 429 case ${e.num}: 430 /* ${e.name} */ 431 % if e.core_version: 432 return ${e.core_version.c_vk_version()} <= core_version; 433 % elif e.extensions: 434 % for ext in e.extensions: 435 % if ext.type == 'instance': 436 if (instance->${ext.name[3:]}) return true; 437 % else: 438 /* All device extensions are considered enabled at the instance level */ 439 return true; 440 % endif 441 % endfor 442 return false; 443 % else: 444 return true; 445 % endif 446% endfor 447 default: 448 return false; 449 } 450} 451 452/** Return true if the core version or extension in which the given entrypoint 453 * is defined is enabled. 454 * 455 * If device is NULL, all device extensions are considered enabled. 456 */ 457bool 458v3dv_device_entrypoint_is_enabled(int index, uint32_t core_version, 459 const struct v3dv_instance_extension_table *instance, 460 const struct v3dv_device_extension_table *device) 461{ 462 switch (index) { 463% for e in device_entrypoints: 464 case ${e.num}: 465 /* ${e.name} */ 466 % if e.core_version: 467 return ${e.core_version.c_vk_version()} <= core_version; 468 % elif e.extensions: 469 % for ext in e.extensions: 470 % if ext.type == 'instance': 471 <% assert False %> 472 % else: 473 if (!device || device->${ext.name[3:]}) return true; 474 % endif 475 % endfor 476 return false; 477 % else: 478 return true; 479 % endif 480% endfor 481 default: 482 return false; 483 } 484} 485 486int 487v3dv_get_instance_entrypoint_index(const char *name) 488{ 489 return instance_string_map_lookup(name); 490} 491 492int 493v3dv_get_physical_device_entrypoint_index(const char *name) 494{ 495 return physical_device_string_map_lookup(name); 496} 497 498int 499v3dv_get_device_entrypoint_index(const char *name) 500{ 501 return device_string_map_lookup(name); 502} 503 504const char * 505v3dv_get_instance_entry_name(int index) 506{ 507 return instance_entry_name(index); 508} 509 510const char * 511v3dv_get_physical_device_entry_name(int index) 512{ 513 return physical_device_entry_name(index); 514} 515 516const char * 517v3dv_get_device_entry_name(int index) 518{ 519 return device_entry_name(index); 520} 521 522void * 523v3dv_lookup_entrypoint(const struct v3d_device_info *devinfo, const char *name) 524{ 525 int idx = v3dv_get_instance_entrypoint_index(name); 526 if (idx >= 0) 527 return v3dv_instance_dispatch_table.entrypoints[idx]; 528 529 idx = v3dv_get_physical_device_entrypoint_index(name); 530 if (idx >= 0) 531 return v3dv_physical_device_dispatch_table.entrypoints[idx]; 532 533 idx = v3dv_get_device_entrypoint_index(name); 534 if (idx >= 0) 535 return v3dv_device_dispatch_table.entrypoints[idx]; 536 537 return NULL; 538}""", output_encoding='utf-8') 539 540U32_MASK = 2**32 - 1 541 542PRIME_FACTOR = 5024183 543PRIME_STEP = 19 544 545class StringIntMapEntry(object): 546 def __init__(self, string, num): 547 self.string = string 548 self.num = num 549 550 # Calculate the same hash value that we will calculate in C. 551 h = 0 552 for c in string: 553 h = ((h * PRIME_FACTOR) + ord(c)) & U32_MASK 554 self.hash = h 555 556 self.offset = None 557 558def round_to_pow2(x): 559 return 2**int(math.ceil(math.log(x, 2))) 560 561class StringIntMap(object): 562 def __init__(self): 563 self.baked = False 564 self.strings = dict() 565 566 def add_string(self, string, num): 567 assert not self.baked 568 assert string not in self.strings 569 assert 0 <= num < 2**31 570 self.strings[string] = StringIntMapEntry(string, num) 571 572 def bake(self): 573 self.sorted_strings = \ 574 sorted(self.strings.values(), key=lambda x: x.string) 575 offset = 0 576 for entry in self.sorted_strings: 577 entry.offset = offset 578 offset += len(entry.string) + 1 579 580 # Save off some values that we'll need in C 581 self.hash_size = round_to_pow2(len(self.strings) * 1.25) 582 self.hash_mask = self.hash_size - 1 583 self.prime_factor = PRIME_FACTOR 584 self.prime_step = PRIME_STEP 585 586 self.mapping = [-1] * self.hash_size 587 self.collisions = [0] * 10 588 for idx, s in enumerate(self.sorted_strings): 589 level = 0 590 h = s.hash 591 while self.mapping[h & self.hash_mask] >= 0: 592 h = h + PRIME_STEP 593 level = level + 1 594 self.collisions[min(level, 9)] += 1 595 self.mapping[h & self.hash_mask] = idx 596 597EntrypointParam = namedtuple('EntrypointParam', 'type name decl') 598 599class EntrypointBase(object): 600 def __init__(self, name): 601 self.name = name 602 self.alias = None 603 self.guard = None 604 self.enabled = False 605 self.num = None 606 # Extensions which require this entrypoint 607 self.core_version = None 608 self.extensions = [] 609 610class Entrypoint(EntrypointBase): 611 def __init__(self, name, return_type, params, guard=None): 612 super(Entrypoint, self).__init__(name) 613 self.return_type = return_type 614 self.params = params 615 self.guard = guard 616 617 def is_physical_device_entrypoint(self): 618 return self.params[0].type in ('VkPhysicalDevice', ) 619 620 def is_device_entrypoint(self): 621 return self.params[0].type in ('VkDevice', 'VkCommandBuffer', 'VkQueue') 622 623 def prefixed_name(self, prefix): 624 assert self.name.startswith('vk') 625 return prefix + '_' + self.name[2:] 626 627 def decl_params(self): 628 return ', '.join(p.decl for p in self.params) 629 630 def call_params(self): 631 return ', '.join(p.name for p in self.params) 632 633class EntrypointAlias(EntrypointBase): 634 def __init__(self, name, entrypoint): 635 super(EntrypointAlias, self).__init__(name) 636 self.alias = entrypoint 637 638 def is_physical_device_entrypoint(self): 639 return self.alias.is_physical_device_entrypoint() 640 641 def is_device_entrypoint(self): 642 return self.alias.is_device_entrypoint() 643 644 def prefixed_name(self, prefix): 645 return self.alias.prefixed_name(prefix) 646 647def get_entrypoints(doc, entrypoints_to_defines): 648 """Extract the entry points from the registry.""" 649 entrypoints = OrderedDict() 650 651 for command in doc.findall('./commands/command'): 652 if 'alias' in command.attrib: 653 alias = command.attrib['name'] 654 target = command.attrib['alias'] 655 entrypoints[alias] = EntrypointAlias(alias, entrypoints[target]) 656 else: 657 name = command.find('./proto/name').text 658 ret_type = command.find('./proto/type').text 659 params = [EntrypointParam( 660 type=p.find('./type').text, 661 name=p.find('./name').text, 662 decl=''.join(p.itertext()) 663 ) for p in command.findall('./param')] 664 guard = entrypoints_to_defines.get(name) 665 # They really need to be unique 666 assert name not in entrypoints 667 entrypoints[name] = Entrypoint(name, ret_type, params, guard) 668 669 for feature in doc.findall('./feature'): 670 assert feature.attrib['api'] == 'vulkan' 671 version = VkVersion(feature.attrib['number']) 672 if version > MAX_API_VERSION: 673 continue 674 675 for command in feature.findall('./require/command'): 676 e = entrypoints[command.attrib['name']] 677 e.enabled = True 678 assert e.core_version is None 679 e.core_version = version 680 681 supported_exts = dict((ext.name, ext) for ext in EXTENSIONS) 682 for extension in doc.findall('.extensions/extension'): 683 ext_name = extension.attrib['name'] 684 if ext_name not in supported_exts: 685 continue 686 687 ext = supported_exts[ext_name] 688 ext.type = extension.attrib['type'] 689 690 for command in extension.findall('./require/command'): 691 e = entrypoints[command.attrib['name']] 692 e.enabled = True 693 assert e.core_version is None 694 e.extensions.append(ext) 695 696 return [e for e in entrypoints.values() if e.enabled] 697 698 699def get_entrypoints_defines(doc): 700 """Maps entry points to extension defines.""" 701 entrypoints_to_defines = {} 702 703 platform_define = {} 704 for platform in doc.findall('./platforms/platform'): 705 name = platform.attrib['name'] 706 define = platform.attrib['protect'] 707 platform_define[name] = define 708 709 for extension in doc.findall('./extensions/extension[@platform]'): 710 platform = extension.attrib['platform'] 711 define = platform_define[platform] 712 713 for entrypoint in extension.findall('./require/command'): 714 fullname = entrypoint.attrib['name'] 715 entrypoints_to_defines[fullname] = define 716 717 return entrypoints_to_defines 718 719 720def main(): 721 parser = argparse.ArgumentParser() 722 parser.add_argument('--outdir', help='Where to write the files.', 723 required=True) 724 parser.add_argument('--xml', 725 help='Vulkan API XML file.', 726 required=True, 727 action='append', 728 dest='xml_files') 729 args = parser.parse_args() 730 731 entrypoints = [] 732 733 for filename in args.xml_files: 734 doc = et.parse(filename) 735 entrypoints += get_entrypoints(doc, get_entrypoints_defines(doc)) 736 737 device_entrypoints = [] 738 physical_device_entrypoints = [] 739 instance_entrypoints = [] 740 for e in entrypoints: 741 if e.is_device_entrypoint(): 742 device_entrypoints.append(e) 743 elif e.is_physical_device_entrypoint(): 744 physical_device_entrypoints.append(e) 745 else: 746 instance_entrypoints.append(e) 747 748 device_strmap = StringIntMap() 749 for num, e in enumerate(device_entrypoints): 750 device_strmap.add_string(e.name, num) 751 e.num = num 752 device_strmap.bake() 753 754 physical_device_strmap = StringIntMap() 755 for num, e in enumerate(physical_device_entrypoints): 756 physical_device_strmap.add_string(e.name, num) 757 e.num = num 758 physical_device_strmap.bake() 759 760 instance_strmap = StringIntMap() 761 for num, e in enumerate(instance_entrypoints): 762 instance_strmap.add_string(e.name, num) 763 e.num = num 764 instance_strmap.bake() 765 766 # For outputting entrypoints.h we generate a v3dv_EntryPoint() prototype 767 # per entry point. 768 try: 769 with open(os.path.join(args.outdir, 'v3dv_entrypoints.h'), 'wb') as f: 770 f.write(TEMPLATE_H.render(instance_entrypoints=instance_entrypoints, 771 physical_device_entrypoints=physical_device_entrypoints, 772 device_entrypoints=device_entrypoints, 773 LAYERS=LAYERS, 774 filename=os.path.basename(__file__))) 775 with open(os.path.join(args.outdir, 'v3dv_entrypoints.c'), 'wb') as f: 776 f.write(TEMPLATE_C.render(instance_entrypoints=instance_entrypoints, 777 physical_device_entrypoints=physical_device_entrypoints, 778 device_entrypoints=device_entrypoints, 779 LAYERS=LAYERS, 780 instance_strmap=instance_strmap, 781 physical_device_strmap=physical_device_strmap, 782 device_strmap=device_strmap, 783 filename=os.path.basename(__file__))) 784 except Exception: 785 # In the event there's an error, this imports some helpers from mako 786 # to print a useful stack trace and prints it, then exits with 787 # status 1, if python is run with debug; otherwise it just raises 788 # the exception 789 if __debug__: 790 import sys 791 from mako import exceptions 792 sys.stderr.write(exceptions.text_error_template().render() + '\n') 793 sys.exit(1) 794 raise 795 796 797if __name__ == '__main__': 798 main() 799