summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Ekstrand <jason.ekstrand@intel.com>2018-01-20 10:39:16 -0800
committerJason Ekstrand <jason.ekstrand@intel.com>2018-01-23 00:15:40 -0800
commitde00e8227b00740e3fe91c5c8fd0b2498751606c (patch)
tree3658a0db8123e86fb22b4a92aeab22d860b31375
parenteac29f3a6dc7f2659cdb34301a57b2618db1ed12 (diff)
downloadmesa-de00e8227b00740e3fe91c5c8fd0b2498751606c.tar.gz
anv: Return trampoline entrypoints from GetInstanceProcAddr
Technically, the Vulkan spec requires that we return valid entrypoints for all core functionality and any available device extensions. This means that, for gen-specific functions, we need to return a trampoline which looks at the device and calls the right device function. In 99% of cases, the loader will do this for us but, aparently, we're supposed to do it too. It's a tiny increase in binary size for us to carry this around but really not bad. Before: text data bss dec hex filename 3541775 204112 6136 3752023 394057 libvulkan_intel.so After: text data bss dec hex filename 3551463 205632 6136 3763231 396c1f libvulkan_intel.so Reviewed-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
-rw-r--r--src/intel/vulkan/anv_device.c5
-rw-r--r--src/intel/vulkan/anv_entrypoints_gen.py46
2 files changed, 50 insertions, 1 deletions
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index 8fcc73eaba1..0cba17aa169 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -582,8 +582,11 @@ VkResult anv_CreateInstance(
if (!anv_entrypoint_is_enabled(i, instance->apiVersion,
&instance->enabled_extensions, NULL)) {
instance->dispatch.entrypoints[i] = NULL;
- } else {
+ } else if (anv_dispatch_table.entrypoints[i] != NULL) {
instance->dispatch.entrypoints[i] = anv_dispatch_table.entrypoints[i];
+ } else {
+ instance->dispatch.entrypoints[i] =
+ anv_tramp_dispatch_table.entrypoints[i];
}
}
diff --git a/src/intel/vulkan/anv_entrypoints_gen.py b/src/intel/vulkan/anv_entrypoints_gen.py
index 5bae1949a80..1bab885180d 100644
--- a/src/intel/vulkan/anv_entrypoints_gen.py
+++ b/src/intel/vulkan/anv_entrypoints_gen.py
@@ -71,6 +71,7 @@ struct anv_dispatch_table {
%for layer in LAYERS:
extern const struct anv_dispatch_table ${layer}_dispatch_table;
%endfor
+extern const struct anv_dispatch_table anv_tramp_dispatch_table;
% for e in entrypoints:
% if e.guard is not None:
@@ -164,6 +165,48 @@ static const struct anv_entrypoint entrypoints[] = {
};
% endfor
+
+/** Trampoline entrypoints for all device functions */
+
+% for e in entrypoints:
+ % if e.params[0].type not in ('VkDevice', 'VkCommandBuffer'):
+ <% continue %>
+ % endif
+ % if e.guard is not None:
+#ifdef ${e.guard}
+ % endif
+ static ${e.return_type}
+ ${e.prefixed_name('anv_tramp')}(${e.decl_params()})
+ {
+ % if e.params[0].type == 'VkDevice':
+ ANV_FROM_HANDLE(anv_device, anv_device, ${e.params[0].name});
+ return anv_device->dispatch.${e.name}(${e.call_params()});
+ % else:
+ ANV_FROM_HANDLE(anv_cmd_buffer, anv_cmd_buffer, ${e.params[0].name});
+ return anv_cmd_buffer->device->dispatch.${e.name}(${e.call_params()});
+ % endif
+ }
+ % if e.guard is not None:
+#endif // ${e.guard}
+ % endif
+% endfor
+
+const struct anv_dispatch_table anv_tramp_dispatch_table = {
+% for e in entrypoints:
+ % if e.params[0].type not in ('VkDevice', 'VkCommandBuffer'):
+ <% continue %>
+ % endif
+ % if e.guard is not None:
+#ifdef ${e.guard}
+ % endif
+ .${e.name} = ${e.prefixed_name('anv_tramp')},
+ % if e.guard is not None:
+#endif // ${e.guard}
+ % endif
+% endfor
+};
+
+
/** Return true if the core version or extension in which the given entrypoint
* is defined is enabled.
*
@@ -322,6 +365,9 @@ class Entrypoint(object):
def decl_params(self):
return ', '.join(p.decl for p in self.params)
+ def call_params(self):
+ return ', '.join(p.name for p in self.params)
+
def get_c_hash(self):
return cal_hash(self.name)