intel/fs: Fix MOV_INDIRECT and BROADCAST of Q types on Gen11+
[mesa.git] / src / intel / vulkan / anv_entrypoints_gen.py
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
25 import argparse
26 import math
27 import os
28 import xml.etree.ElementTree as et
29
30 from collections import OrderedDict, namedtuple
31 from mako.template import Template
32
33 from 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
40 LAYERS = [
41 'anv',
42 'gen7',
43 'gen75',
44 'gen8',
45 'gen9',
46 'gen10',
47 'gen11',
48 'gen12',
49 ]
50
51 TEMPLATE_H = Template("""\
52 /* This file generated from ${filename}, don't edit directly. */
53
54 struct 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
73 struct 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
92 struct 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
111 extern const struct anv_instance_dispatch_table anv_instance_dispatch_table;
112 %for layer in LAYERS:
113 extern const struct anv_physical_device_dispatch_table ${layer}_physical_device_dispatch_table;
114 %endfor
115 %for layer in LAYERS:
116 extern 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
163 TEMPLATE_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
193 struct 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)">
205 static const char ${prefix}_strings[] =
206 % for s in strmap.sorted_strings:
207 "${s.string}\\0"
208 % endfor
209 ;
210
211 static 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
226 static 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
232 static 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
260 static 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
293 const 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
318 const 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 */
383 bool
384 anv_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 */
417 bool
418 anv_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 */
451 bool
452 anv_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
480 int
481 anv_get_instance_entrypoint_index(const char *name)
482 {
483 return instance_string_map_lookup(name);
484 }
485
486 int
487 anv_get_physical_device_entrypoint_index(const char *name)
488 {
489 return physical_device_string_map_lookup(name);
490 }
491
492 int
493 anv_get_device_entrypoint_index(const char *name)
494 {
495 return device_string_map_lookup(name);
496 }
497
498 const char *
499 anv_get_instance_entry_name(int index)
500 {
501 return instance_entry_name(index);
502 }
503
504 const char *
505 anv_get_physical_device_entry_name(int index)
506 {
507 return physical_device_entry_name(index);
508 }
509
510 const char *
511 anv_get_device_entry_name(int index)
512 {
513 return device_entry_name(index);
514 }
515
516 void * __attribute__ ((noinline))
517 anv_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
552 void *
553 anv_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
570 U32_MASK = 2**32 - 1
571
572 PRIME_FACTOR = 5024183
573 PRIME_STEP = 19
574
575 class 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
588 def round_to_pow2(x):
589 return 2**int(math.ceil(math.log(x, 2)))
590
591 class 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
627 EntrypointParam = namedtuple('EntrypointParam', 'type name decl')
628
629 class 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
644 class 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
663 class 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
693 def 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
745 def 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
766 def 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
855 if __name__ == '__main__':
856 main()