loader: Add dynamic dispatch for unknown device extension entrypoints
GetInstancePorcAddr() is specified to return trampoline entrypoints for all
Vulkan core and extension entrypoints that are dispatched on an instance object
or a child of that instance object. However, typically, device extensions would
be unknown to the loader (don't want to rev the loader everytime an IHV creates
a new device extension).
This patch allows loader to dynamically discover device extension entrypoints
and configure generic trampoline code for these discovered device extensions.
diff --git a/loader/vk-loader-generate.py b/loader/vk-loader-generate.py
index 143af61..e2c794d 100755
--- a/loader/vk-loader-generate.py
+++ b/loader/vk-loader-generate.py
@@ -91,6 +91,7 @@
/*
*
* Copyright (C) 2015 Valve Corporation
+ * All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -111,6 +112,8 @@
* DEALINGS IN THE SOFTWARE.
*
* Author: Jon Ashburn <jon@lunarg.com>
+ * Author: Chia-I Wu <olv@lunarg.com>
+ * Author: Courtney Goeltzenleuchter <courtney@lunarg.com>
*/"""
def generate_header(self):
@@ -122,6 +125,37 @@
def generate_footer(self):
pass
+class DevExtTrampolineSubcommand(Subcommand):
+ def generate_header(self):
+ lines = []
+ lines.append("#include \"vk_loader_platform.h\"")
+ lines.append("#include \"loader.h\"")
+ lines.append("#if defined(__linux__)")
+ lines.append("#pragma GCC optimize(3) // force gcc to use tail-calls")
+ lines.append("#endif")
+ return "\n".join(lines)
+
+ def generate_body(self):
+ lines = []
+ for i in range(250):
+ lines.append('\nVKAPI_ATTR void VKAPI_CALL vkDevExt%s(VkDevice device)' % i)
+ lines.append('{')
+ lines.append(' const struct loader_dev_dispatch_table *disp;')
+ lines.append(' disp = loader_get_dev_dispatch(device);')
+ lines.append(' disp->ext_dispatch.DevExt[%s](device);' % i)
+ lines.append('}')
+ lines.append('')
+ lines.append('void *loader_get_dev_ext_trampoline(uint32_t index)')
+ lines.append('{')
+ lines.append(' switch (index) {')
+ for i in range(250):
+ lines.append(' case %s:' % i)
+ lines.append(' return vkDevExt%s;' % i)
+ lines.append(' }')
+ lines.append(' return NULL;')
+ lines.append('}')
+ return "\n".join(lines)
+
class LoaderEntrypointsSubcommand(Subcommand):
def generate_header(self):
return "#include \"loader.h\""
@@ -412,6 +446,7 @@
def main():
subcommands = {
+ "dev-ext-trampoline": DevExtTrampolineSubcommand,
"loader-entrypoints": LoaderEntrypointsSubcommand,
"dispatch-table-ops": DispatchTableOpsSubcommand,
"win-def-file": WinDefFileSubcommand,