Mesa (master): anv: Return trampoline entrypoints from GetInstanceProcAddr

Jason Ekstrand jekstrand at kemper.freedesktop.org
Tue Jan 23 08:38:21 UTC 2018


Module: Mesa
Branch: master
Commit: de00e8227b00740e3fe91c5c8fd0b2498751606c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=de00e8227b00740e3fe91c5c8fd0b2498751606c

Author: Jason Ekstrand <jason.ekstrand at intel.com>
Date:   Sat Jan 20 10:39:16 2018 -0800

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 at igalia.com>

---

 src/intel/vulkan/anv_device.c           |  5 +++-
 src/intel/vulkan/anv_entrypoints_gen.py | 46 +++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index 8fcc73eaba..0cba17aa16 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 5bae1949a8..1bab885180 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)
 




More information about the mesa-commit mailing list