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