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