radv: update entrypoints generation from ANV
[mesa.git] / src / amd / vulkan / radv_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.cElementTree as et
30
31 from collections import OrderedDict, namedtuple
32 from mako.template import Template
33
34 from radv_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 radv, but keeping the ability for anv
42 # anyways, so we can use it for device groups.
43 LAYERS = [
44 'radv'
45 ]
46
47 TEMPLATE_H = Template("""\
48 /* This file generated from ${filename}, don't edit directly. */
49
50 struct radv_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 radv_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 radv_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 radv_instance_dispatch_table radv_instance_dispatch_table;
108 %for layer in LAYERS:
109 extern const struct radv_physical_device_dispatch_table ${layer}_physical_device_dispatch_table;
110 %endfor
111 %for layer in LAYERS:
112 extern const struct radv_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('radv')}(${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 "radv_private.h"
186
187 #include "util/macros.h"
188
189 struct string_map_entry {
190 uint32_t name;
191 uint32_t hash;
192 uint32_t num;
193 };
194
195 /* We use a big string constant to avoid lots of reloctions from the entry
196 * point table to lots of little strings. The entries in the entry point table
197 * store the index into this big string.
198 */
199
200 <%def name="strmap(strmap, prefix)">
201 static const char ${prefix}_strings[] =
202 % for s in strmap.sorted_strings:
203 "${s.string}\\0"
204 % endfor
205 ;
206
207 static const struct string_map_entry ${prefix}_string_map_entries[] = {
208 % for s in strmap.sorted_strings:
209 { ${s.offset}, ${'{:0=#8x}'.format(s.hash)}, ${s.num} }, /* ${s.string} */
210 % endfor
211 };
212
213 /* Hash table stats:
214 * size ${len(strmap.sorted_strings)} entries
215 * collisions entries:
216 % for i in range(10):
217 * ${i}${'+' if i == 9 else ' '} ${strmap.collisions[i]}
218 % endfor
219 */
220
221 #define none 0xffff
222 static const uint16_t ${prefix}_string_map[${strmap.hash_size}] = {
223 % for e in strmap.mapping:
224 ${ '{:0=#6x}'.format(e) if e >= 0 else 'none' },
225 % endfor
226 };
227
228 static int
229 ${prefix}_string_map_lookup(const char *str)
230 {
231 static const uint32_t prime_factor = ${strmap.prime_factor};
232 static const uint32_t prime_step = ${strmap.prime_step};
233 const struct string_map_entry *e;
234 uint32_t hash, h;
235 uint16_t i;
236 const char *p;
237
238 hash = 0;
239 for (p = str; *p; p++)
240 hash = hash * prime_factor + *p;
241
242 h = hash;
243 while (1) {
244 i = ${prefix}_string_map[h & ${strmap.hash_mask}];
245 if (i == none)
246 return -1;
247 e = &${prefix}_string_map_entries[i];
248 if (e->hash == hash && strcmp(str, ${prefix}_strings + e->name) == 0)
249 return e->num;
250 h += prime_step;
251 }
252
253 return -1;
254 }
255
256 static const char *
257 ${prefix}_entry_name(int num)
258 {
259 for (int i = 0; i < ARRAY_SIZE(${prefix}_string_map_entries); i++) {
260 if (${prefix}_string_map_entries[i].num == num)
261 return &${prefix}_strings[${prefix}_string_map_entries[i].name];
262 }
263 return NULL;
264 }
265 </%def>
266
267 ${strmap(instance_strmap, 'instance')}
268 ${strmap(physical_device_strmap, 'physical_device')}
269 ${strmap(device_strmap, 'device')}
270
271 /* Weak aliases for all potential implementations. These will resolve to
272 * NULL if they're not defined, which lets the resolve_entrypoint() function
273 * either pick the correct entry point.
274 */
275
276 % for e in instance_entrypoints:
277 % if e.alias and e.alias.enabled:
278 <% continue %>
279 % endif
280 % if e.guard is not None:
281 #ifdef ${e.guard}
282 % endif
283 ${e.return_type} ${e.prefixed_name('radv')}(${e.decl_params()}) __attribute__ ((weak));
284 % if e.guard is not None:
285 #endif // ${e.guard}
286 % endif
287 % endfor
288
289 const struct radv_instance_dispatch_table radv_instance_dispatch_table = {
290 % for e in instance_entrypoints:
291 % if e.guard is not None:
292 #ifdef ${e.guard}
293 % endif
294 .${e.name} = ${e.prefixed_name('radv')},
295 % if e.guard is not None:
296 #endif // ${e.guard}
297 % endif
298 % endfor
299 };
300
301 % for e in physical_device_entrypoints:
302 % if e.alias and e.alias.enabled:
303 <% continue %>
304 % endif
305 % if e.guard is not None:
306 #ifdef ${e.guard}
307 % endif
308 ${e.return_type} ${e.prefixed_name('radv')}(${e.decl_params()}) __attribute__ ((weak));
309 % if e.guard is not None:
310 #endif // ${e.guard}
311 % endif
312 % endfor
313
314 const struct radv_physical_device_dispatch_table radv_physical_device_dispatch_table = {
315 % for e in physical_device_entrypoints:
316 % if e.guard is not None:
317 #ifdef ${e.guard}
318 % endif
319 .${e.name} = ${e.prefixed_name('radv')},
320 % if e.guard is not None:
321 #endif // ${e.guard}
322 % endif
323 % endfor
324 };
325
326
327 % for layer in LAYERS:
328 % for e in device_entrypoints:
329 % if e.alias and e.alias.enabled:
330 <% continue %>
331 % endif
332 % if e.guard is not None:
333 #ifdef ${e.guard}
334 % endif
335 % if layer == 'radv':
336 ${e.return_type} __attribute__ ((weak))
337 ${e.prefixed_name('radv')}(${e.decl_params()})
338 {
339 % if e.params[0].type == 'VkDevice':
340 RADV_FROM_HANDLE(radv_device, radv_device, ${e.params[0].name});
341 return radv_device->dispatch.${e.name}(${e.call_params()});
342 % elif e.params[0].type == 'VkCommandBuffer':
343 RADV_FROM_HANDLE(radv_cmd_buffer, radv_cmd_buffer, ${e.params[0].name});
344 return radv_cmd_buffer->device->dispatch.${e.name}(${e.call_params()});
345 % elif e.params[0].type == 'VkQueue':
346 RADV_FROM_HANDLE(radv_queue, radv_queue, ${e.params[0].name});
347 return radv_queue->device->dispatch.${e.name}(${e.call_params()});
348 % else:
349 assert(!"Unhandled device child trampoline case: ${e.params[0].type}");
350 % endif
351 }
352 % else:
353 ${e.return_type} ${e.prefixed_name(layer)}(${e.decl_params()}) __attribute__ ((weak));
354 % endif
355 % if e.guard is not None:
356 #endif // ${e.guard}
357 % endif
358 % endfor
359
360 const struct radv_device_dispatch_table ${layer}_device_dispatch_table = {
361 % for e in device_entrypoints:
362 % if e.guard is not None:
363 #ifdef ${e.guard}
364 % endif
365 .${e.name} = ${e.prefixed_name(layer)},
366 % if e.guard is not None:
367 #endif // ${e.guard}
368 % endif
369 % endfor
370 };
371 % endfor
372
373
374 /** Return true if the core version or extension in which the given entrypoint
375 * is defined is enabled.
376 *
377 * If device is NULL, all device extensions are considered enabled.
378 */
379 bool
380 radv_instance_entrypoint_is_enabled(int index, uint32_t core_version,
381 const struct radv_instance_extension_table *instance)
382 {
383 switch (index) {
384 % for e in instance_entrypoints:
385 case ${e.num}:
386 /* ${e.name} */
387 % if e.core_version:
388 return ${e.core_version.c_vk_version()} <= core_version;
389 % elif e.extensions:
390 % for ext in e.extensions:
391 % if ext.type == 'instance':
392 if (instance->${ext.name[3:]}) return true;
393 % else:
394 /* All device extensions are considered enabled at the instance level */
395 return true;
396 % endif
397 % endfor
398 return false;
399 % else:
400 return true;
401 % endif
402 % endfor
403 default:
404 return false;
405 }
406 }
407
408 /** Return true if the core version or extension in which the given entrypoint
409 * is defined is enabled.
410 *
411 * If device is NULL, all device extensions are considered enabled.
412 */
413 bool
414 radv_physical_device_entrypoint_is_enabled(int index, uint32_t core_version,
415 const struct radv_instance_extension_table *instance)
416 {
417 switch (index) {
418 % for e in physical_device_entrypoints:
419 case ${e.num}:
420 /* ${e.name} */
421 % if e.core_version:
422 return ${e.core_version.c_vk_version()} <= core_version;
423 % elif e.extensions:
424 % for ext in e.extensions:
425 % if ext.type == 'instance':
426 if (instance->${ext.name[3:]}) return true;
427 % else:
428 /* All device extensions are considered enabled at the instance level */
429 return true;
430 % endif
431 % endfor
432 return false;
433 % else:
434 return true;
435 % endif
436 % endfor
437 default:
438 return false;
439 }
440 }
441
442 /** Return true if the core version or extension in which the given entrypoint
443 * is defined is enabled.
444 *
445 * If device is NULL, all device extensions are considered enabled.
446 */
447 bool
448 radv_device_entrypoint_is_enabled(int index, uint32_t core_version,
449 const struct radv_instance_extension_table *instance,
450 const struct radv_device_extension_table *device)
451 {
452 switch (index) {
453 % for e in device_entrypoints:
454 case ${e.num}:
455 /* ${e.name} */
456 % if e.core_version:
457 return ${e.core_version.c_vk_version()} <= core_version;
458 % elif e.extensions:
459 % for ext in e.extensions:
460 % if ext.type == 'instance':
461 <% assert False %>
462 % else:
463 if (!device || device->${ext.name[3:]}) return true;
464 % endif
465 % endfor
466 return false;
467 % else:
468 return true;
469 % endif
470 % endfor
471 default:
472 return false;
473 }
474 }
475
476 int
477 radv_get_instance_entrypoint_index(const char *name)
478 {
479 return instance_string_map_lookup(name);
480 }
481
482 int
483 radv_get_physical_device_entrypoint_index(const char *name)
484 {
485 return physical_device_string_map_lookup(name);
486 }
487
488 int
489 radv_get_device_entrypoint_index(const char *name)
490 {
491 return device_string_map_lookup(name);
492 }
493
494 const char *
495 radv_get_instance_entry_name(int index)
496 {
497 return instance_entry_name(index);
498 }
499
500 const char *
501 radv_get_physical_device_entry_name(int index)
502 {
503 return physical_device_entry_name(index);
504 }
505
506 const char *
507 radv_get_device_entry_name(int index)
508 {
509 return device_entry_name(index);
510 }
511
512 static void * __attribute__ ((noinline))
513 radv_resolve_device_entrypoint(uint32_t index)
514 {
515 return radv_device_dispatch_table.entrypoints[index];
516 }
517
518 void *
519 radv_lookup_entrypoint(const char *name)
520 {
521 int idx = radv_get_instance_entrypoint_index(name);
522 if (idx >= 0)
523 return radv_instance_dispatch_table.entrypoints[idx];
524
525 idx = radv_get_physical_device_entrypoint_index(name);
526 if (idx >= 0)
527 return radv_physical_device_dispatch_table.entrypoints[idx];
528
529 idx = radv_get_device_entrypoint_index(name);
530 if (idx >= 0)
531 return radv_resolve_device_entrypoint(idx);
532
533 return NULL;
534 }""", output_encoding='utf-8')
535
536 U32_MASK = 2**32 - 1
537
538 PRIME_FACTOR = 5024183
539 PRIME_STEP = 19
540
541 def round_to_pow2(x):
542 return 2**int(math.ceil(math.log(x, 2)))
543
544 class StringIntMapEntry(object):
545 def __init__(self, string, num):
546 self.string = string
547 self.num = num
548
549 # Calculate the same hash value that we will calculate in C.
550 h = 0
551 for c in string:
552 h = ((h * PRIME_FACTOR) + ord(c)) & U32_MASK
553 self.hash = h
554
555 self.offset = None
556
557 class StringIntMap(object):
558 def __init__(self):
559 self.baked = False
560 self.strings = dict()
561
562 def add_string(self, string, num):
563 assert not self.baked
564 assert string not in self.strings
565 assert num >= 0 and num < 2**31
566 self.strings[string] = StringIntMapEntry(string, num)
567
568 def bake(self):
569 self.sorted_strings = \
570 sorted(self.strings.values(), key=lambda x: x.string)
571 offset = 0
572 for entry in self.sorted_strings:
573 entry.offset = offset
574 offset += len(entry.string) + 1
575
576 # Save off some values that we'll need in C
577 self.hash_size = round_to_pow2(len(self.strings) * 1.25)
578 self.hash_mask = self.hash_size - 1
579 self.prime_factor = PRIME_FACTOR
580 self.prime_step = PRIME_STEP
581
582 self.mapping = [-1] * self.hash_size
583 self.collisions = [0] * 10
584 for idx, s in enumerate(self.sorted_strings):
585 level = 0
586 h = s.hash
587 while self.mapping[h & self.hash_mask] >= 0:
588 h = h + PRIME_STEP
589 level = level + 1
590 self.collisions[min(level, 9)] += 1
591 self.mapping[h & self.hash_mask] = idx
592
593 EntrypointParam = namedtuple('EntrypointParam', 'type name decl')
594
595 class EntrypointBase(object):
596 def __init__(self, name):
597 self.name = name
598 self.alias = None
599 self.guard = None
600 self.enabled = False
601 self.num = None
602 # Extensions which require this entrypoint
603 self.core_version = None
604 self.extensions = []
605
606 def prefixed_name(self, prefix):
607 assert self.name.startswith('vk')
608 return prefix + '_' + self.name[2:]
609
610 class Entrypoint(EntrypointBase):
611 def __init__(self, name, return_type, params, guard = None):
612 super(Entrypoint, self).__init__(name)
613 self.return_type = return_type
614 self.params = params
615 self.guard = guard
616
617 def is_physical_device_entrypoint(self):
618 return self.params[0].type in ('VkPhysicalDevice', )
619
620 def is_device_entrypoint(self):
621 return self.params[0].type in ('VkDevice', 'VkCommandBuffer', 'VkQueue')
622
623 def decl_params(self):
624 return ', '.join(p.decl for p in self.params)
625
626 def call_params(self):
627 return ', '.join(p.name for p in self.params)
628
629 class EntrypointAlias(EntrypointBase):
630 def __init__(self, name, entrypoint):
631 super(EntrypointAlias, self).__init__(name)
632 self.alias = entrypoint
633
634 def is_physical_device_entrypoint(self):
635 return self.alias.is_physical_device_entrypoint()
636
637 def is_device_entrypoint(self):
638 return self.alias.is_device_entrypoint()
639
640 def prefixed_name(self, prefix):
641 if self.alias.enabled:
642 return self.alias.prefixed_name(prefix)
643 return super(EntrypointAlias, self).prefixed_name(prefix)
644
645 @property
646 def params(self):
647 return self.alias.params
648
649 @property
650 def return_type(self):
651 return self.alias.return_type
652
653 def decl_params(self):
654 return self.alias.decl_params()
655
656 def call_params(self):
657 return self.alias.call_params()
658
659 def get_entrypoints(doc, entrypoints_to_defines):
660 """Extract the entry points from the registry."""
661 entrypoints = OrderedDict()
662
663 for command in doc.findall('./commands/command'):
664 if 'alias' in command.attrib:
665 alias = command.attrib['name']
666 target = command.attrib['alias']
667 entrypoints[alias] = EntrypointAlias(alias, entrypoints[target])
668 else:
669 name = command.find('./proto/name').text
670 ret_type = command.find('./proto/type').text
671 params = [EntrypointParam(
672 type = p.find('./type').text,
673 name = p.find('./name').text,
674 decl = ''.join(p.itertext())
675 ) for p in command.findall('./param')]
676 guard = entrypoints_to_defines.get(name)
677 # They really need to be unique
678 assert name not in entrypoints
679 entrypoints[name] = Entrypoint(name, ret_type, params, guard)
680
681 for feature in doc.findall('./feature'):
682 assert feature.attrib['api'] == 'vulkan'
683 version = VkVersion(feature.attrib['number'])
684 if version > MAX_API_VERSION:
685 continue
686
687 for command in feature.findall('./require/command'):
688 e = entrypoints[command.attrib['name']]
689 e.enabled = True
690 assert e.core_version is None
691 e.core_version = version
692
693 supported_exts = dict((ext.name, ext) for ext in EXTENSIONS)
694 for extension in doc.findall('.extensions/extension'):
695 ext_name = extension.attrib['name']
696 if ext_name not in supported_exts:
697 continue
698
699 ext = supported_exts[ext_name]
700 ext.type = extension.attrib['type']
701
702 for command in extension.findall('./require/command'):
703 e = entrypoints[command.attrib['name']]
704 e.enabled = True
705 assert e.core_version is None
706 e.extensions.append(ext)
707
708 # if the base command is not supported by the driver yet, don't alias aliases
709 for e in entrypoints.values():
710 if e.alias and not e.alias.enabled:
711 e_clone = copy.deepcopy(e.alias)
712 e_clone.enabled = True
713 e_clone.name = e.name
714 entrypoints[e.name] = e_clone
715
716 return [e for e in entrypoints.values() if e.enabled]
717
718
719 def get_entrypoints_defines(doc):
720 """Maps entry points to extension defines."""
721 entrypoints_to_defines = {}
722
723 platform_define = {}
724 for platform in doc.findall('./platforms/platform'):
725 name = platform.attrib['name']
726 define = platform.attrib['protect']
727 platform_define[name] = define
728
729 for extension in doc.findall('./extensions/extension[@platform]'):
730 platform = extension.attrib['platform']
731 define = platform_define[platform]
732
733 for entrypoint in extension.findall('./require/command'):
734 fullname = entrypoint.attrib['name']
735 entrypoints_to_defines[fullname] = define
736
737 return entrypoints_to_defines
738
739 def main():
740 parser = argparse.ArgumentParser()
741 parser.add_argument('--outdir', help='Where to write the files.',
742 required=True)
743 parser.add_argument('--xml',
744 help='Vulkan API XML file.',
745 required=True,
746 action='append',
747 dest='xml_files')
748 args = parser.parse_args()
749
750 entrypoints = []
751
752 for filename in args.xml_files:
753 doc = et.parse(filename)
754 entrypoints += get_entrypoints(doc, get_entrypoints_defines(doc))
755
756 device_entrypoints = []
757 physical_device_entrypoints = []
758 instance_entrypoints = []
759 for e in entrypoints:
760 if e.is_device_entrypoint():
761 device_entrypoints.append(e)
762 elif e.is_physical_device_entrypoint():
763 physical_device_entrypoints.append(e)
764 else:
765 instance_entrypoints.append(e)
766
767 device_strmap = StringIntMap()
768 for num, e in enumerate(device_entrypoints):
769 device_strmap.add_string(e.name, num)
770 e.num = num
771 device_strmap.bake()
772
773 physical_device_strmap = StringIntMap()
774 for num, e in enumerate(physical_device_entrypoints):
775 physical_device_strmap.add_string(e.name, num)
776 e.num = num
777 physical_device_strmap.bake()
778
779 instance_strmap = StringIntMap()
780 for num, e in enumerate(instance_entrypoints):
781 instance_strmap.add_string(e.name, num)
782 e.num = num
783 instance_strmap.bake()
784
785 # For outputting entrypoints.h we generate a radv_EntryPoint() prototype
786 # per entry point.
787 try:
788 with open(os.path.join(args.outdir, 'radv_entrypoints.h'), 'wb') as f:
789 f.write(TEMPLATE_H.render(instance_entrypoints=instance_entrypoints,
790 physical_device_entrypoints=physical_device_entrypoints,
791 device_entrypoints=device_entrypoints,
792 LAYERS=LAYERS,
793 filename=os.path.basename(__file__)))
794 with open(os.path.join(args.outdir, 'radv_entrypoints.c'), 'wb') as f:
795 f.write(TEMPLATE_C.render(instance_entrypoints=instance_entrypoints,
796 physical_device_entrypoints=physical_device_entrypoints,
797 device_entrypoints=device_entrypoints,
798 LAYERS=LAYERS,
799 instance_strmap=instance_strmap,
800 physical_device_strmap=physical_device_strmap,
801 device_strmap=device_strmap,
802 filename=os.path.basename(__file__)))
803 except Exception:
804 # In the event there's an error, this imports some helpers from mako
805 # to print a useful stack trace and prints it, then exits with
806 # status 1, if python is run with debug; otherwise it just raises
807 # the exception
808 if __debug__:
809 import sys
810 from mako import exceptions
811 sys.stderr.write(exceptions.text_error_template().render() + '\n')
812 sys.exit(1)
813 raise
814
815
816 if __name__ == '__main__':
817 main()