diff options
author | Jason Ekstrand <[email protected]> | 2018-01-20 10:39:16 -0800 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2018-01-23 00:15:40 -0800 |
commit | de00e8227b00740e3fe91c5c8fd0b2498751606c (patch) | |
tree | 3658a0db8123e86fb22b4a92aeab22d860b31375 /src/intel | |
parent | eac29f3a6dc7f2659cdb34301a57b2618db1ed12 (diff) |
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 <[email protected]>
Diffstat (limited to 'src/intel')
-rw-r--r-- | src/intel/vulkan/anv_device.c | 5 | ||||
-rw-r--r-- | src/intel/vulkan/anv_entrypoints_gen.py | 46 |
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) |