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