vulkan: rework DriverDispatchTable
Generate {Instance,Device}DriverTable from code-generator.tmpl to replace
dispatch.tmpl entirely. The new code avoids initializing
VK_ANDROID_native_buffer entries when the extension is not enabled. The
separation of instance and device driver tables also allows us to
initialize the device driver table with vkGetDeviceProcAddr, which is
expected to return more efficient function pointers on properly
implemented HALs.
CreateInstance_Bottom always has a potential resource leak when the
HAL-created instance does not contain HWVULKAN_DISPATCH_MAGIC.
CreateDevice_Bottom now has the same issue. Both of them will be fixed in
following commits.
Change-Id: If7800ef23098121f1fff643a2c5224c2c9be0711
diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl
index f7083c3..23c2717 100644
--- a/vulkan/libvulkan/code-generator.tmpl
+++ b/vulkan/libvulkan/code-generator.tmpl
@@ -46,7 +46,7 @@
// clang-format off
{{range $f := AllCommands $}}
{{if (Macro "api.IsInstanceDispatchTableEntry" $f)}}
- {{Macro "C++.DeclareDispatchTableEntry" $f}};
+ {{Macro "C++.DeclareTableEntry" $f}};
{{end}}
{{end}}
// clang-format on
@@ -56,7 +56,7 @@
// clang-format off
{{range $f := AllCommands $}}
{{if (Macro "api.IsDeviceDispatchTableEntry" $f)}}
- {{Macro "C++.DeclareDispatchTableEntry" $f}};
+ {{Macro "C++.DeclareTableEntry" $f}};
{{end}}
{{end}}
// clang-format on
@@ -91,7 +91,9 @@
namespace vulkan {«
namespace api {«
¶
-{{Macro "C++.DefineInitProcMacros" "dispatch"}}
+{{Macro "C++.DefineInitProcMacro" "dispatch"}}
+¶
+{{Macro "api.C++.DefineInitProcExtMacro"}}
¶
bool InitDispatchTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc) {
auto& data = GetData(instance);
@@ -169,9 +171,32 @@
¶
{{Macro "driver.C++.DefineProcHookType"}}
¶
+struct InstanceDriverTable {
+ // clang-format off
+ {{range $f := AllCommands $}}
+ {{if (Macro "driver.IsInstanceDriverTableEntry" $f)}}
+ {{Macro "C++.DeclareTableEntry" $f}};
+ {{end}}
+ {{end}}
+ // clang-format on
+};
+¶
+struct DeviceDriverTable {
+ // clang-format off
+ {{range $f := AllCommands $}}
+ {{if (Macro "driver.IsDeviceDriverTableEntry" $f)}}
+ {{Macro "C++.DeclareTableEntry" $f}};
+ {{end}}
+ {{end}}
+ // clang-format on
+};
+¶
const ProcHook* GetProcHook(const char* name);
ProcHook::Extension GetProcHookExtension(const char* name);
¶
+bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc);
+bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc);
+¶
»} // namespace driver
»} // namespace vulkan
¶
@@ -245,6 +270,42 @@
return ProcHook::EXTENSION_UNKNOWN;
}
¶
+{{Macro "C++.DefineInitProcMacro" "driver"}}
+¶
+{{Macro "driver.C++.DefineInitProcExtMacro"}}
+¶
+bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc)
+{
+ auto& data = GetData(instance);
+ bool success = true;
+ ¶
+ // clang-format off
+ {{range $f := AllCommands $}}
+ {{if (Macro "driver.IsInstanceDriverTableEntry" $f)}}
+ {{Macro "C++.InitProc" $f}}
+ {{end}}
+ {{end}}
+ // clang-format on
+ ¶
+ return success;
+}
+¶
+bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc)
+{
+ auto& data = GetData(dev);
+ bool success = true;
+ ¶
+ // clang-format off
+ {{range $f := AllCommands $}}
+ {{if (Macro "driver.IsDeviceDriverTableEntry" $f)}}
+ {{Macro "C++.InitProc" $f}}
+ {{end}}
+ {{end}}
+ // clang-format on
+ ¶
+ return success;
+}
+¶
»} // namespace driver
»} // namespace vulkan
¶
@@ -254,10 +315,10 @@
{{/*
------------------------------------------------------------------------------
- Emits a declaration of a dispatch table entry.
+ Emits a declaration of a dispatch/driver table entry.
------------------------------------------------------------------------------
*/}}
-{{define "C++.DeclareDispatchTableEntry"}}
+{{define "C++.DeclareTableEntry"}}
{{AssertType $ "Function"}}
{{Macro "FunctionPtrName" $}} {{Macro "BaseName" $}}
@@ -266,10 +327,10 @@
{{/*
-------------------------------------------------------------------------------
- Emits macros to help initialize dispatch tables.
+ Emits INIT_PROC macro.
-------------------------------------------------------------------------------
*/}}
-{{define "C++.DefineInitProcMacros"}}
+{{define "C++.DefineInitProcMacro"}}
#define UNLIKELY(expr) __builtin_expect((expr), 0)
¶
#define INIT_PROC(obj, proc) do { \
@@ -280,11 +341,6 @@
success = false; \
} \
} while(0)
- ¶
- // TODO do we want to point to a stub or nullptr when ext is not enabled?
- #define INIT_PROC_EXT(ext, obj, proc) do { \
- INIT_PROC(obj, proc); \
- } while(0)
{{end}}
@@ -368,6 +424,19 @@
{{/*
+-------------------------------------------------------------------------------
+ Emits INIT_PROC_EXT macro for vulkan::api.
+-------------------------------------------------------------------------------
+*/}}
+{{define "api.C++.DefineInitProcExtMacro"}}
+ // TODO do we want to point to a stub or nullptr when ext is not enabled?
+ #define INIT_PROC_EXT(ext, obj, proc) do { \
+ INIT_PROC(obj, proc); \
+ } while(0)
+{{end}}
+
+
+{{/*
------------------------------------------------------------------------------
Emits code for vkGetInstanceProcAddr for function interception.
------------------------------------------------------------------------------
@@ -614,6 +683,19 @@
{{/*
-------------------------------------------------------------------------------
+ Emits INIT_PROC_EXT macro for vulkan::driver.
+-------------------------------------------------------------------------------
+*/}}
+{{define "driver.C++.DefineInitProcExtMacro"}}
+ #define INIT_PROC_EXT(ext, obj, proc) do { \
+ if (data.hal_extensions[ProcHook::ext]) \
+ INIT_PROC(obj, proc); \
+ } while(0)
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
Emits definitions of stub functions for ProcHook.
-------------------------------------------------------------------------------
*/}}
@@ -764,6 +846,78 @@
{{/*
-------------------------------------------------------------------------------
+ Emits true if a function is needed by vulkan::driver.
+-------------------------------------------------------------------------------
+*/}}
+{{define "driver.IsDriverTableEntry"}}
+ {{AssertType $ "Function"}}
+
+ {{if (Macro "IsFunctionSupported" $)}}
+ {{/* Create functions of dispatchable objects */}}
+ {{ if eq $.Name "vkCreateDevice"}}true
+ {{else if eq $.Name "vkGetDeviceQueue"}}true
+ {{else if eq $.Name "vkAllocateCommandBuffers"}}true
+
+ {{/* Destroy functions of dispatchable objects */}}
+ {{else if eq $.Name "vkDestroyInstance"}}true
+ {{else if eq $.Name "vkDestroyDevice"}}true
+
+ {{/* Enumeration of extensions */}}
+ {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true
+
+ {{/* We cache physical devices in loader.cpp */}}
+ {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true
+
+ {{else if eq $.Name "vkGetInstanceProcAddr"}}true
+ {{else if eq $.Name "vkGetDeviceProcAddr"}}true
+
+ {{/* VK_KHR_swapchain->VK_ANDROID_native_buffer translation */}}
+ {{else if eq $.Name "vkCreateImage"}}true
+ {{else if eq $.Name "vkDestroyImage"}}true
+
+ {{end}}
+
+ {{$ext := GetAnnotation $ "extension"}}
+ {{if $ext}}
+ {{$ext_name := index $ext.Arguments 0}}
+ {{ if eq $ext_name "VK_ANDROID_native_buffer"}}true
+ {{else if eq $ext_name "VK_EXT_debug_report"}}true
+ {{end}}
+ {{end}}
+ {{end}}
+{{end}}
+
+
+{{/*
+------------------------------------------------------------------------------
+ Emits true if an instance-dispatched function is needed by vulkan::driver.
+------------------------------------------------------------------------------
+*/}}
+{{define "driver.IsInstanceDriverTableEntry"}}
+ {{AssertType $ "Function"}}
+
+ {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsInstanceDispatched" $)}}
+ true
+ {{end}}
+{{end}}
+
+
+{{/*
+------------------------------------------------------------------------------
+ Emits true if a device-dispatched function is needed by vulkan::driver.
+------------------------------------------------------------------------------
+*/}}
+{{define "driver.IsDeviceDriverTableEntry"}}
+ {{AssertType $ "Function"}}
+
+ {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsDeviceDispatched" $)}}
+ true
+ {{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
Emits a function/extension name without the "vk"/"VK_" prefix.
-------------------------------------------------------------------------------
*/}}