+ };
+ };
+};
+
+% for e in entrypoints:
+ % if e.alias:
+ <% continue %>
+ % endif
+ % if e.guard is not None:
+#ifdef ${e.guard}
+ % endif
+ % for layer in LAYERS:
+ ${e.return_type} ${e.prefixed_name(layer)}(${e.decl_params()});
+ % endfor
+ % if e.guard is not None:
+#endif // ${e.guard}
+ % endif
+% endfor
+""", output_encoding='utf-8')
+
+TEMPLATE_C = Template(u"""\
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/* This file generated from ${filename}, don't edit directly. */
+
+#include "radv_private.h"
+
+struct string_map_entry {
+ uint32_t name;
+ uint32_t hash;
+ uint32_t num;
+};
+
+/* We use a big string constant to avoid lots of relocations from the entry
+ * point table to lots of little strings. The entries in the entry point table
+ * store the index into this big string.
+ */
+
+static const char strings[] =
+% for s in strmap.sorted_strings:
+ "${s.string}\\0"
+% endfor
+;
+
+static const struct string_map_entry string_map_entries[] = {
+% for s in strmap.sorted_strings:
+ { ${s.offset}, ${'{:0=#8x}'.format(s.hash)}, ${s.num} }, /* ${s.string} */
+% endfor
+};
+
+/* Hash table stats:
+ * size ${len(strmap.sorted_strings)} entries
+ * collisions entries:
+% for i in range(10):
+ * ${i}${'+' if i == 9 else ' '} ${strmap.collisions[i]}
+% endfor
+ */
+
+#define none 0xffff
+static const uint16_t string_map[${strmap.hash_size}] = {
+% for e in strmap.mapping:
+ ${ '{:0=#6x}'.format(e) if e >= 0 else 'none' },
+% endfor
+};
+
+/* Weak aliases for all potential implementations. These will resolve to
+ * NULL if they're not defined, which lets the resolve_entrypoint() function
+ * either pick the correct entry point.
+ */
+
+% for layer in LAYERS:
+ % for e in entrypoints:
+ % if e.alias:
+ <% continue %>
+ % endif
+ % if e.guard is not None:
+#ifdef ${e.guard}
+ % endif
+ ${e.return_type} ${e.prefixed_name(layer)}(${e.decl_params()}) __attribute__ ((weak));
+ % if e.guard is not None:
+#endif // ${e.guard}
+ % endif
+ % endfor
+
+ const struct radv_dispatch_table ${layer}_layer = {
+ % for e in entrypoints:
+ % if e.guard is not None:
+#ifdef ${e.guard}
+ % endif
+ .${e.name} = ${e.prefixed_name(layer)},
+ % if e.guard is not None:
+#endif // ${e.guard}
+ % endif
+ % endfor
+ };
+% endfor
+
+static void * __attribute__ ((noinline))
+radv_resolve_entrypoint(uint32_t index)
+{
+ return radv_layer.entrypoints[index];
+}
+
+/** Return true if the core version or extension in which the given entrypoint
+ * is defined is enabled.
+ *
+ * If instance is NULL, we only allow the 3 commands explicitly allowed by the vk
+ * spec.
+ *
+ * If device is NULL, all device extensions are considered enabled.
+ */
+static bool
+radv_entrypoint_is_enabled(int index, uint32_t core_version,
+ const struct radv_instance_extension_table *instance,
+ const struct radv_device_extension_table *device)
+{
+ switch (index) {
+% for e in entrypoints:
+ case ${e.num}:
+ % if not e.device_command:
+ if (device) return false;
+ % endif
+ % if e.name == 'vkCreateInstance' or e.name == 'vkEnumerateInstanceExtensionProperties' or e.name == 'vkEnumerateInstanceLayerProperties' or e.name == 'vkEnumerateInstanceVersion':
+ return !device;
+ % elif e.core_version:
+ return instance && ${e.core_version.c_vk_version()} <= core_version;
+ % elif e.extensions:
+ % for ext in e.extensions:
+ % if ext.type == 'instance':
+ if (instance && instance->${ext.name[3:]}) return true;
+ % else:
+ if (instance && (!device || device->${ext.name[3:]})) return true;
+ % endif
+ %endfor
+ return false;
+ % else:
+ return instance;
+ % endif
+% endfor
+ default:
+ return false;
+ }
+}
+
+static bool
+radv_entrypoint_is_enabled_physical_device(int index, uint32_t core_version,
+ const struct radv_instance_extension_table *instance)
+{
+ switch (index) {
+% for e in entrypoints:
+ %if e.physical_device_command:
+ case ${e.num}:
+ % if e.core_version:
+ return instance && ${e.core_version.c_vk_version()} <= core_version;
+ % elif e.extensions:
+ % for ext in e.extensions:
+ % if ext.type == 'instance':
+ if (instance && instance->${ext.name[3:]}) return true;
+ % else:
+ return true;
+ % endif
+ %endfor
+ return false;
+ % else:
+ return instance;
+ % endif
+ %endif
+% endfor
+ default:
+ return false;
+ }
+}
+
+static int
+radv_lookup_entrypoint(const char *name)
+{
+ static const uint32_t prime_factor = ${strmap.prime_factor};
+ static const uint32_t prime_step = ${strmap.prime_step};
+ const struct string_map_entry *e;
+ uint32_t hash, h;
+ uint16_t i;
+ const char *p;
+
+ hash = 0;
+ for (p = name; *p; p++)
+ hash = hash * prime_factor + *p;
+
+ h = hash;
+ while (1) {
+ i = string_map[h & ${strmap.hash_mask}];
+ if (i == none)
+ return -1;
+ e = &string_map_entries[i];
+ if (e->hash == hash && strcmp(name, strings + e->name) == 0)
+ return e->num;
+ h += prime_step;
+ }
+
+ return -1;
+}
+
+void *
+radv_lookup_entrypoint_unchecked(const char *name)
+{
+ int index = radv_lookup_entrypoint(name);
+ if (index < 0)
+ return NULL;
+ return radv_resolve_entrypoint(index);
+}
+
+void *
+radv_lookup_entrypoint_checked(const char *name,
+ uint32_t core_version,
+ const struct radv_instance_extension_table *instance,
+ const struct radv_device_extension_table *device)
+{
+ int index = radv_lookup_entrypoint(name);
+ if (index < 0 || !radv_entrypoint_is_enabled(index, core_version, instance, device))
+ return NULL;
+ return radv_resolve_entrypoint(index);
+}
+
+void *
+radv_lookup_physical_device_entrypoint_checked(const char *name,
+ uint32_t core_version,
+ const struct radv_instance_extension_table *instance)
+{
+ int index = radv_lookup_entrypoint(name);
+ if (index < 0 || !radv_entrypoint_is_enabled_physical_device(index, core_version, instance))
+ return NULL;
+ return radv_resolve_entrypoint(index);
+}
+
+""", output_encoding='utf-8')
+