vulkan: rework driver::Get*ProcAddr
Introduce driver::ProcHook which is a struct to describe an intercepted
function. Given a function name, GetProcHook returns a ProcHook if the
function is intercepted. NULL otherwise.
A ProcHook has three function pointers. ProcHook::proc points to the real
intercepting function. ProcHook::disabled_proc points to a no-op function
that logs an error. ProcHook::checked_proc points to a trampoline that
calls either ProcHook::proc or ProcHook::disabled_proc.
For core functions, driver::Get*ProcAddr simply return ProcHook::proc.
For extension functions, driver::Get*ProcAddr return ProcHook::proc when
the extension is known to be enabled. They return ProcHook::disabled_proc
when the extension is known to be disabled. Finally, they return
ProcHook::checked_proc when they do not know if the extension is enabled
or not.
All ProcHooks as well as their disabled_proc/checked_proc are generated in
driver_gen.cpp. This allows us to get rid of all hand-written "_Disabled"
functions, all no-op "_Bottom" functions, and special cases for
VK_ANDROID_native_buffer. The reworked driver::Get*ProcAddr also detects
more applications' errors and logs them.
Change-Id: I8e6f476f450688b5547fd75243c66cb603c516b5
diff --git a/vulkan/libvulkan/Android.mk b/vulkan/libvulkan/Android.mk
index 665d45e..62d1279 100644
--- a/vulkan/libvulkan/Android.mk
+++ b/vulkan/libvulkan/Android.mk
@@ -44,6 +44,7 @@
debug_report.cpp \
dispatch_gen.cpp \
driver.cpp \
+ driver_gen.cpp \
layers_extensions.cpp \
loader.cpp \
swapchain.cpp \
diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl
index 7ebe983..f7083c3 100644
--- a/vulkan/libvulkan/code-generator.tmpl
+++ b/vulkan/libvulkan/code-generator.tmpl
@@ -21,6 +21,8 @@
{{Macro "DefineGlobals" $}}
{{$ | Macro "api_gen.h" | Format (Global "clang-format") | Write "api_gen.h" }}
{{$ | Macro "api_gen.cpp" | Format (Global "clang-format") | Write "api_gen.cpp"}}
+{{$ | Macro "driver_gen.h" | Format (Global "clang-format") | Write "driver_gen.h"}}
+{{$ | Macro "driver_gen.cpp" | Format (Global "clang-format") | Write "driver_gen.cpp"}}
{{/*
-------------------------------------------------------------------------------
@@ -147,6 +149,110 @@
{{/*
+-------------------------------------------------------------------------------
+ driver_gen.h
+-------------------------------------------------------------------------------
+*/}}
+{{define "driver_gen.h"}}
+{{Macro "Copyright"}}
+¶
+// WARNING: This file is generated. See ../README.md for instructions.
+¶
+#ifndef LIBVULKAN_DRIVER_GEN_H
+#define LIBVULKAN_DRIVER_GEN_H
+¶
+#include <vulkan/vulkan.h>
+#include <vulkan/vk_android_native_buffer.h>
+¶
+namespace vulkan {«
+namespace driver {«
+¶
+{{Macro "driver.C++.DefineProcHookType"}}
+¶
+const ProcHook* GetProcHook(const char* name);
+ProcHook::Extension GetProcHookExtension(const char* name);
+¶
+»} // namespace driver
+»} // namespace vulkan
+¶
+#endif // LIBVULKAN_DRIVER_TABLE_H
+¶{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+ driver_gen.cpp
+-------------------------------------------------------------------------------
+*/}}
+{{define "driver_gen.cpp"}}
+{{Macro "Copyright"}}
+¶
+// WARNING: This file is generated. See ../README.md for instructions.
+¶
+#include <string.h>
+#include <algorithm>
+#include <log/log.h>
+¶
+#include "driver.h"
+#include "loader.h"
+¶
+namespace vulkan {«
+namespace driver {«
+¶
+namespace {«
+¶
+// clang-format off
+¶
+{{range $f := AllCommands $}}
+ {{Macro "driver.C++.DefineProcHookStubs" $f}}
+{{end}}
+// clang-format on
+¶
+const ProcHook g_proc_hooks[] = {
+ // clang-format off
+ {{range $f := SortBy (AllCommands $) "FunctionName"}}
+ {{if (Macro "driver.IsIntercepted" $f)}}
+ {{ if (Macro "IsGloballyDispatched" $f)}}
+ {{Macro "driver.C++.DefineGlobalProcHook" $f}}
+ {{else if (Macro "IsInstanceDispatched" $f)}}
+ {{Macro "driver.C++.DefineInstanceProcHook" $f}}
+ {{else if (Macro "IsDeviceDispatched" $f)}}
+ {{Macro "driver.C++.DefineDeviceProcHook" $f}}
+ {{end}}
+ {{end}}
+ {{end}}
+ // clang-format on
+};
+¶
+»} // anonymous
+¶
+const ProcHook* GetProcHook(const char* name) {
+ const auto& begin = g_proc_hooks;
+ const auto& end = g_proc_hooks +
+ sizeof(g_proc_hooks) / sizeof(g_proc_hooks[0]);
+ const auto hook = std::lower_bound(begin, end, name,
+ [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; });
+ return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr;
+}
+¶
+ProcHook::Extension GetProcHookExtension(const char* name) {
+ {{$exts := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}}
+ // clang-format off
+ {{range $e := $exts}}
+ if (strcmp(name, "{{$e}}") == 0) return ProcHook::{{TrimPrefix "VK_" $e}};
+ {{end}}
+ // clang-format on
+ return ProcHook::EXTENSION_UNKNOWN;
+}
+¶
+»} // namespace driver
+»} // namespace vulkan
+¶
+// clang-format on
+¶{{end}}
+
+
+{{/*
------------------------------------------------------------------------------
Emits a declaration of a dispatch table entry.
------------------------------------------------------------------------------
@@ -386,6 +492,277 @@
{{/*
+------------------------------------------------------------------------------
+ Emits a list of extensions intercepted by vulkan::driver.
+------------------------------------------------------------------------------
+*/}}
+{{define "driver.InterceptedExtensions"}}
+VK_ANDROID_native_buffer
+VK_EXT_debug_report
+VK_KHR_android_surface
+VK_KHR_surface
+VK_KHR_swapchain
+{{end}}
+
+
+{{/*
+------------------------------------------------------------------------------
+ Emits true if an extension is intercepted by vulkan::driver.
+------------------------------------------------------------------------------
+*/}}
+{{define "driver.IsExtensionIntercepted"}}
+ {{$ext_name := index $.Arguments 0}}
+ {{$filters := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}}
+
+ {{range $f := $filters}}
+ {{if eq $ext_name $f}}true{{end}}
+ {{end}}
+{{end}}
+
+
+{{/*
+------------------------------------------------------------------------------
+ Emits true if a function is intercepted by vulkan::driver.
+------------------------------------------------------------------------------
+*/}}
+{{define "driver.IsIntercepted"}}
+ {{AssertType $ "Function"}}
+
+ {{if (Macro "IsFunctionSupported" $)}}
+ {{/* Create functions of dispatchable objects */}}
+ {{ if eq $.Name "vkCreateInstance"}}true
+ {{else 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 "vkEnumerateInstanceExtensionProperties"}}true
+ {{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
+
+ {{end}}
+
+ {{$ext := GetAnnotation $ "extension"}}
+ {{if $ext}}
+ {{Macro "driver.IsExtensionIntercepted" $ext}}
+ {{end}}
+
+ {{end}}
+{{end}}
+
+
+{{/*
+------------------------------------------------------------------------------
+ Emits true if a function needs ProcHook stubs.
+------------------------------------------------------------------------------
+*/}}
+{{define "driver.NeedProcHookStubs"}}
+ {{AssertType $ "Function"}}
+
+ {{if (Macro "driver.IsIntercepted" $)}}
+ {{$ext := GetAnnotation $ "extension"}}
+ {{if $ext}}
+ {{if not (Macro "IsExtensionInternal" $ext)}}true{{end}}
+ {{end}}
+ {{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+ Emits definition of struct ProcHook.
+-------------------------------------------------------------------------------
+*/}}
+{{define "driver.C++.DefineProcHookType"}}
+ struct ProcHook {
+ enum Type {
+ GLOBAL,
+ INSTANCE,
+ DEVICE,
+ };
+
+ enum Extension {
+ {{$exts := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}}
+ {{range $e := $exts}}
+ {{TrimPrefix "VK_" $e}},
+ {{end}}
+ ¶
+ EXTENSION_CORE, // valid bit
+ EXTENSION_COUNT,
+ EXTENSION_UNKNOWN,
+ };
+ ¶
+ const char* name;
+ Type type;
+ Extension extension;
+ ¶
+ PFN_vkVoidFunction proc;
+ PFN_vkVoidFunction disabled_proc; // nullptr for global hooks
+ PFN_vkVoidFunction checked_proc; // nullptr for global/instance hooks
+ };
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+ Emits definitions of stub functions for ProcHook.
+-------------------------------------------------------------------------------
+*/}}
+{{define "driver.C++.DefineProcHookStubs"}}
+ {{AssertType $ "Function"}}
+
+ {{if (Macro "driver.NeedProcHookStubs" $)}}
+ {{$ext := GetAnnotation $ "extension"}}
+ {{$ext_name := index $ext.Arguments 0}}
+
+ {{$base := (Macro "BaseName" $)}}
+ {{$unnamed_params := (ForEach $.CallParameters "ParameterType" | JoinWith ", ")}}
+
+ VKAPI_ATTR {{Node "Type" $.Return}} disabled{{$base}}({{$unnamed_params}}) {
+ ALOGE("{{$ext_name}} not enabled. {{$.Name}} not executed.");
+ {{if not (IsVoid $.Return.Type)}}return VK_SUCCESS;{{end}}
+ }
+ {{if (Macro "IsDeviceDispatched" $)}}
+ ¶
+ VKAPI_ATTR {{Node "Type" $.Return}} checked{{$base}}({{Macro "Parameters" $}}) {
+ {{if not (IsVoid $.Return.Type)}}return §{{end}}
+
+ {{$p0 := index $.CallParameters 0}}
+ {{$ext_hook := Strings ("ProcHook::") (Macro "BaseName" $ext)}}
+ (GetData({{$p0.Name}}).hook_extensions[{{$ext_hook}}]) ? §
+ {{$base}}_Bottom({{Macro "Arguments" $}}) : §
+ disabled{{$base}}({{Macro "Arguments" $}});
+ }
+ {{end}}
+ ¶
+ {{end}}
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+ Emits definition of a global ProcHook.
+-------------------------------------------------------------------------------
+*/}}
+{{define "driver.C++.DefineGlobalProcHook"}}
+ {{AssertType $ "Function"}}
+
+ {{$base := (Macro "BaseName" $)}}
+
+ {{$ext := GetAnnotation $ "extension"}}
+ {{if $ext}}
+ {{Error "invalid global extension"}}
+ {{end}}
+
+ {
+ "{{$.Name}}",
+ ProcHook::GLOBAL,
+ ProcHook::EXTENSION_CORE,
+ {{if eq $.Name "vkEnumerateInstanceExtensionProperties"}}
+ reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
+ {{else}}
+ reinterpret_cast<PFN_vkVoidFunction>({{$base}}_Bottom),
+ {{end}}
+ nullptr,
+ nullptr,
+ },
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+ Emits definition of an instance ProcHook.
+-------------------------------------------------------------------------------
+*/}}
+{{define "driver.C++.DefineInstanceProcHook"}}
+ {{AssertType $ "Function"}}
+
+ {{$base := (Macro "BaseName" $)}}
+
+ {
+ "{{$.Name}}",
+ ProcHook::INSTANCE,
+
+ {{$ext := GetAnnotation $ "extension"}}
+ {{if $ext}}
+ ProcHook::{{Macro "BaseName" $ext}},
+
+ {{if (Macro "IsExtensionInternal" $ext)}}
+ nullptr,
+ nullptr,
+ nullptr,
+ {{else}}
+ reinterpret_cast<PFN_vkVoidFunction>({{$base}}_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabled{{$base}}),
+ nullptr,
+ {{end}}
+ {{else}}
+ ProcHook::EXTENSION_CORE,
+
+ {{if eq $.Name "vkGetInstanceProcAddr"}}
+ reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
+ {{else}}
+ reinterpret_cast<PFN_vkVoidFunction>({{$base}}_Bottom),
+ {{end}}
+ nullptr,
+ nullptr,
+ {{end}}
+ },
+{{end}}
+
+
+{{/*
+-------------------------------------------------------------------------------
+ Emits definition of a device ProcHook.
+-------------------------------------------------------------------------------
+*/}}
+{{define "driver.C++.DefineDeviceProcHook"}}
+ {{AssertType $ "Function"}}
+
+ {{$base := (Macro "BaseName" $)}}
+
+ {
+ "{{$.Name}}",
+ ProcHook::DEVICE,
+
+ {{$ext := GetAnnotation $ "extension"}}
+ {{if $ext}}
+ ProcHook::{{Macro "BaseName" $ext}},
+
+ {{if (Macro "IsExtensionInternal" $ext)}}
+ nullptr,
+ nullptr,
+ nullptr,
+ {{else}}
+ reinterpret_cast<PFN_vkVoidFunction>({{$base}}_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabled{{$base}}),
+ reinterpret_cast<PFN_vkVoidFunction>(checked{{$base}}),
+ {{end}}
+ {{else}}
+ ProcHook::EXTENSION_CORE,
+
+ {{if eq $.Name "vkGetDeviceProcAddr"}}
+ reinterpret_cast<PFN_vkVoidFunction>({{$base}}),
+ {{else}}
+ reinterpret_cast<PFN_vkVoidFunction>({{$base}}_Bottom),
+ {{end}}
+ nullptr,
+ nullptr,
+ {{end}}
+ },
+{{end}}
+
+
+{{/*
-------------------------------------------------------------------------------
Emits a function/extension name without the "vk"/"VK_" prefix.
-------------------------------------------------------------------------------
@@ -517,3 +894,16 @@
{{else if eq $ext "VK_KHR_android_surface"}}true
{{end}}
{{end}}
+
+
+{{/*
+------------------------------------------------------------------------------
+ Reports whether an extension is internal to the loader and drivers,
+ so the loader should not enumerate it.
+------------------------------------------------------------------------------
+*/}}
+{{define "IsExtensionInternal"}}
+ {{$ext := index $.Arguments 0}}
+ {{ if eq $ext "VK_ANDROID_native_buffer"}}true
+ {{end}}
+{{end}}
diff --git a/vulkan/libvulkan/dispatch.tmpl b/vulkan/libvulkan/dispatch.tmpl
index 67ead4a..fd77879 100644
--- a/vulkan/libvulkan/dispatch.tmpl
+++ b/vulkan/libvulkan/dispatch.tmpl
@@ -118,47 +118,8 @@
¶
using namespace vulkan;
¶
-namespace {
-¶
-struct NameProc {
- const char* name;
- PFN_vkVoidFunction proc;
-};
-¶
-PFN_vkVoidFunction Lookup(const char* name, const NameProc* begin, const NameProc* end) {
- const auto& entry = std::lower_bound(
- begin, end, name,
- [](const NameProc& e, const char* n) { return strcmp(e.name, n) < 0; });
- if (entry == end || strcmp(entry->name, name) != 0)
- return nullptr;
- return entry->proc;
-}
-¶
-template <size_t N>
-PFN_vkVoidFunction Lookup(const char* name, const NameProc (&procs)[N]) {
- return Lookup(name, procs, procs + N);
-}
-¶
-const NameProc kLoaderBottomProcs[] = {«
- // clang-format off
- {{range $f := SortBy (AllCommands $) "FunctionName"}}
- {{if (Macro "HasLoaderBottomImpl" $f)}}
- {"{{$f.Name}}", reinterpret_cast<PFN_vkVoidFunction>(§
- static_cast<{{Macro "FunctionPtrName" $f}}>(§
- {{Macro "BaseName" $f}}_Bottom))},
- {{end}}
- {{end}}
- // clang-format on
-»};
-¶
-} // anonymous namespace
-¶
namespace vulkan {
¶
-PFN_vkVoidFunction GetLoaderBottomProcAddr(const char* name) {
- return Lookup(name, kLoaderBottomProcs);
-}
-¶
bool LoadDriverDispatchTable(VkInstance instance,
PFN_vkGetInstanceProcAddr get_proc_addr,
const InstanceExtensionSet& extensions,
diff --git a/vulkan/libvulkan/dispatch_gen.cpp b/vulkan/libvulkan/dispatch_gen.cpp
index eacf1a1..fa199bd 100644
--- a/vulkan/libvulkan/dispatch_gen.cpp
+++ b/vulkan/libvulkan/dispatch_gen.cpp
@@ -24,74 +24,8 @@
using namespace vulkan;
-namespace {
-
-struct NameProc {
- const char* name;
- PFN_vkVoidFunction proc;
-};
-
-PFN_vkVoidFunction Lookup(const char* name,
- const NameProc* begin,
- const NameProc* end) {
- const auto& entry = std::lower_bound(
- begin, end, name,
- [](const NameProc& e, const char* n) { return strcmp(e.name, n) < 0; });
- if (entry == end || strcmp(entry->name, name) != 0)
- return nullptr;
- return entry->proc;
-}
-
-template <size_t N>
-PFN_vkVoidFunction Lookup(const char* name, const NameProc (&procs)[N]) {
- return Lookup(name, procs, procs + N);
-}
-
-const NameProc kLoaderBottomProcs[] = {
- // clang-format off
- {"vkAcquireNextImageKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkAcquireNextImageKHR>(AcquireNextImageKHR_Bottom))},
- {"vkAllocateCommandBuffers", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkAllocateCommandBuffers>(AllocateCommandBuffers_Bottom))},
- {"vkCreateAndroidSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateAndroidSurfaceKHR>(CreateAndroidSurfaceKHR_Bottom))},
- {"vkCreateDebugReportCallbackEXT", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateDebugReportCallbackEXT>(CreateDebugReportCallbackEXT_Bottom))},
- {"vkCreateDevice", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateDevice>(CreateDevice_Bottom))},
- {"vkCreateInstance", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateInstance>(CreateInstance_Bottom))},
- {"vkCreateSwapchainKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkCreateSwapchainKHR>(CreateSwapchainKHR_Bottom))},
- {"vkDebugReportMessageEXT", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDebugReportMessageEXT>(DebugReportMessageEXT_Bottom))},
- {"vkDestroyDebugReportCallbackEXT", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroyDebugReportCallbackEXT>(DestroyDebugReportCallbackEXT_Bottom))},
- {"vkDestroyDevice", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroyDevice>(DestroyDevice_Bottom))},
- {"vkDestroyInstance", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroyInstance>(DestroyInstance_Bottom))},
- {"vkDestroySurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroySurfaceKHR>(DestroySurfaceKHR_Bottom))},
- {"vkDestroySwapchainKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkDestroySwapchainKHR>(DestroySwapchainKHR_Bottom))},
- {"vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkEnumerateDeviceExtensionProperties>(EnumerateDeviceExtensionProperties_Bottom))},
- {"vkEnumerateDeviceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkEnumerateDeviceLayerProperties>(EnumerateDeviceLayerProperties_Bottom))},
- {"vkEnumeratePhysicalDevices", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkEnumeratePhysicalDevices>(EnumeratePhysicalDevices_Bottom))},
- {"vkGetDeviceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetDeviceProcAddr>(GetDeviceProcAddr_Bottom))},
- {"vkGetDeviceQueue", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetDeviceQueue>(GetDeviceQueue_Bottom))},
- {"vkGetInstanceProcAddr", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetInstanceProcAddr>(GetInstanceProcAddr_Bottom))},
- {"vkGetPhysicalDeviceFeatures", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetPhysicalDeviceFeatures>(GetPhysicalDeviceFeatures_Bottom))},
- {"vkGetPhysicalDeviceFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetPhysicalDeviceFormatProperties>(GetPhysicalDeviceFormatProperties_Bottom))},
- {"vkGetPhysicalDeviceImageFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetPhysicalDeviceImageFormatProperties>(GetPhysicalDeviceImageFormatProperties_Bottom))},
- {"vkGetPhysicalDeviceMemoryProperties", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetPhysicalDeviceMemoryProperties>(GetPhysicalDeviceMemoryProperties_Bottom))},
- {"vkGetPhysicalDeviceProperties", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetPhysicalDeviceProperties>(GetPhysicalDeviceProperties_Bottom))},
- {"vkGetPhysicalDeviceQueueFamilyProperties", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetPhysicalDeviceQueueFamilyProperties>(GetPhysicalDeviceQueueFamilyProperties_Bottom))},
- {"vkGetPhysicalDeviceSparseImageFormatProperties", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetPhysicalDeviceSparseImageFormatProperties>(GetPhysicalDeviceSparseImageFormatProperties_Bottom))},
- {"vkGetPhysicalDeviceSurfaceCapabilitiesKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR>(GetPhysicalDeviceSurfaceCapabilitiesKHR_Bottom))},
- {"vkGetPhysicalDeviceSurfaceFormatsKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR>(GetPhysicalDeviceSurfaceFormatsKHR_Bottom))},
- {"vkGetPhysicalDeviceSurfacePresentModesKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR>(GetPhysicalDeviceSurfacePresentModesKHR_Bottom))},
- {"vkGetPhysicalDeviceSurfaceSupportKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetPhysicalDeviceSurfaceSupportKHR>(GetPhysicalDeviceSurfaceSupportKHR_Bottom))},
- {"vkGetSwapchainImagesKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetSwapchainImagesKHR>(GetSwapchainImagesKHR_Bottom))},
- {"vkQueuePresentKHR", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkQueuePresentKHR>(QueuePresentKHR_Bottom))},
- // clang-format on
-};
-
-} // anonymous namespace
-
namespace vulkan {
-PFN_vkVoidFunction GetLoaderBottomProcAddr(const char* name) {
- return Lookup(name, kLoaderBottomProcs);
-}
-
bool LoadDriverDispatchTable(VkInstance instance,
PFN_vkGetInstanceProcAddr get_proc_addr,
const InstanceExtensionSet& extensions,
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 4acc867..68ae5c8 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -143,5 +143,67 @@
return kDefaultAllocCallbacks;
}
+PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
+ const ProcHook* hook = GetProcHook(pName);
+ if (!hook)
+ return g_hwdevice->GetInstanceProcAddr(instance, pName);
+
+ if (!instance) {
+ if (hook->type == ProcHook::GLOBAL)
+ return hook->proc;
+
+ ALOGE(
+ "Invalid use of vkGetInstanceProcAddr to query %s without an "
+ "instance",
+ pName);
+
+ // Some naughty layers expect
+ //
+ // vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice");
+ //
+ // to work.
+ return (strcmp(pName, "vkCreateDevice") == 0) ? hook->proc : nullptr;
+ }
+
+ PFN_vkVoidFunction proc;
+
+ switch (hook->type) {
+ case ProcHook::INSTANCE:
+ proc = (GetData(instance).hook_extensions[hook->extension])
+ ? hook->proc
+ : hook->disabled_proc;
+ break;
+ case ProcHook::DEVICE:
+ proc = (hook->extension == ProcHook::EXTENSION_CORE)
+ ? hook->proc
+ : hook->checked_proc;
+ break;
+ default:
+ ALOGE(
+ "Invalid use of vkGetInstanceProcAddr to query %s with an "
+ "instance",
+ pName);
+ proc = nullptr;
+ break;
+ }
+
+ return proc;
+}
+
+PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
+ const ProcHook* hook = GetProcHook(pName);
+ if (!hook)
+ return GetData(device).get_device_proc_addr(device, pName);
+
+ if (hook->type != ProcHook::DEVICE) {
+ ALOGE("Invalid use of vkGetDeviceProcAddr to query %s", pName);
+ return nullptr;
+ }
+
+ return (GetData(device).hook_extensions[hook->extension])
+ ? hook->proc
+ : hook->disabled_proc;
+}
+
} // namespace driver
} // namespace vulkan
diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h
index de9d1c6..28b0ce6 100644
--- a/vulkan/libvulkan/driver.h
+++ b/vulkan/libvulkan/driver.h
@@ -18,6 +18,7 @@
#define LIBVULKAN_DRIVER_H 1
#include <inttypes.h>
+#include <bitset>
#include <type_traits>
#include <log/log.h>
@@ -25,6 +26,7 @@
#include <hardware/hwvulkan.h>
#include "api_gen.h"
+#include "driver_gen.h"
namespace vulkan {
@@ -61,15 +63,35 @@
namespace driver {
struct InstanceData {
+ InstanceData(const VkAllocationCallbacks& alloc)
+ : opaque_api_data(), allocator(alloc) {
+ hook_extensions.set(ProcHook::EXTENSION_CORE);
+ hal_extensions.set(ProcHook::EXTENSION_CORE);
+ }
+
api::InstanceData opaque_api_data;
const VkAllocationCallbacks allocator;
+
+ std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions;
+ std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions;
};
struct DeviceData {
+ DeviceData(const VkAllocationCallbacks& alloc)
+ : opaque_api_data(), allocator(alloc), get_device_proc_addr(nullptr) {
+ hook_extensions.set(ProcHook::EXTENSION_CORE);
+ hal_extensions.set(ProcHook::EXTENSION_CORE);
+ }
+
api::DeviceData opaque_api_data;
const VkAllocationCallbacks allocator;
+
+ std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions;
+ std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions;
+
+ PFN_vkGetDeviceProcAddr get_device_proc_addr;
};
bool Debuggable();
diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp
new file mode 100644
index 0000000..d725df5
--- /dev/null
+++ b/vulkan/libvulkan/driver_gen.cpp
@@ -0,0 +1,376 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// WARNING: This file is generated. See ../README.md for instructions.
+
+#include <string.h>
+#include <algorithm>
+#include <log/log.h>
+
+#include "driver.h"
+#include "loader.h"
+
+namespace vulkan {
+namespace driver {
+
+namespace {
+
+// clang-format off
+
+VKAPI_ATTR void disabledDestroySurfaceKHR(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks*) {
+ ALOGE("VK_KHR_surface not enabled. vkDestroySurfaceKHR not executed.");
+}
+
+VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice, uint32_t, VkSurfaceKHR, VkBool32*) {
+ ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceSupportKHR not executed.");
+ return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice, VkSurfaceKHR, VkSurfaceCapabilitiesKHR*) {
+ ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceCapabilitiesKHR not executed.");
+ return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice, VkSurfaceKHR, uint32_t*, VkSurfaceFormatKHR*) {
+ ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceFormatsKHR not executed.");
+ return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice, VkSurfaceKHR, uint32_t*, VkPresentModeKHR*) {
+ ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfacePresentModesKHR not executed.");
+ return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult disabledCreateSwapchainKHR(VkDevice, const VkSwapchainCreateInfoKHR*, const VkAllocationCallbacks*, VkSwapchainKHR*) {
+ ALOGE("VK_KHR_swapchain not enabled. vkCreateSwapchainKHR not executed.");
+ return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult checkedCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain) {
+ return (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) ? CreateSwapchainKHR_Bottom(device, pCreateInfo, pAllocator, pSwapchain) : disabledCreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
+}
+
+VKAPI_ATTR void disabledDestroySwapchainKHR(VkDevice, VkSwapchainKHR, const VkAllocationCallbacks*) {
+ ALOGE("VK_KHR_swapchain not enabled. vkDestroySwapchainKHR not executed.");
+}
+
+VKAPI_ATTR void checkedDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator) {
+ (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) ? DestroySwapchainKHR_Bottom(device, swapchain, pAllocator) : disabledDestroySwapchainKHR(device, swapchain, pAllocator);
+}
+
+VKAPI_ATTR VkResult disabledGetSwapchainImagesKHR(VkDevice, VkSwapchainKHR, uint32_t*, VkImage*) {
+ ALOGE("VK_KHR_swapchain not enabled. vkGetSwapchainImagesKHR not executed.");
+ return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult checkedGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages) {
+ return (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) ? GetSwapchainImagesKHR_Bottom(device, swapchain, pSwapchainImageCount, pSwapchainImages) : disabledGetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
+}
+
+VKAPI_ATTR VkResult disabledAcquireNextImageKHR(VkDevice, VkSwapchainKHR, uint64_t, VkSemaphore, VkFence, uint32_t*) {
+ ALOGE("VK_KHR_swapchain not enabled. vkAcquireNextImageKHR not executed.");
+ return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult checkedAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex) {
+ return (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) ? AcquireNextImageKHR_Bottom(device, swapchain, timeout, semaphore, fence, pImageIndex) : disabledAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
+}
+
+VKAPI_ATTR VkResult disabledQueuePresentKHR(VkQueue, const VkPresentInfoKHR*) {
+ ALOGE("VK_KHR_swapchain not enabled. vkQueuePresentKHR not executed.");
+ return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult checkedQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPresentInfo) {
+ return (GetData(queue).hook_extensions[ProcHook::KHR_swapchain]) ? QueuePresentKHR_Bottom(queue, pPresentInfo) : disabledQueuePresentKHR(queue, pPresentInfo);
+}
+
+VKAPI_ATTR VkResult disabledCreateAndroidSurfaceKHR(VkInstance, const VkAndroidSurfaceCreateInfoKHR*, const VkAllocationCallbacks*, VkSurfaceKHR*) {
+ ALOGE("VK_KHR_android_surface not enabled. vkCreateAndroidSurfaceKHR not executed.");
+ return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult disabledCreateDebugReportCallbackEXT(VkInstance, const VkDebugReportCallbackCreateInfoEXT*, const VkAllocationCallbacks*, VkDebugReportCallbackEXT*) {
+ ALOGE("VK_EXT_debug_report not enabled. vkCreateDebugReportCallbackEXT not executed.");
+ return VK_SUCCESS;
+}
+
+VKAPI_ATTR void disabledDestroyDebugReportCallbackEXT(VkInstance, VkDebugReportCallbackEXT, const VkAllocationCallbacks*) {
+ ALOGE("VK_EXT_debug_report not enabled. vkDestroyDebugReportCallbackEXT not executed.");
+}
+
+VKAPI_ATTR void disabledDebugReportMessageEXT(VkInstance, VkDebugReportFlagsEXT, VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t, const char*, const char*) {
+ ALOGE("VK_EXT_debug_report not enabled. vkDebugReportMessageEXT not executed.");
+}
+
+// clang-format on
+
+const ProcHook g_proc_hooks[] = {
+ // clang-format off
+ {
+ "vkAcquireImageANDROID",
+ ProcHook::DEVICE,
+ ProcHook::ANDROID_native_buffer,
+ nullptr,
+ nullptr,
+ nullptr,
+ },
+ {
+ "vkAcquireNextImageKHR",
+ ProcHook::DEVICE,
+ ProcHook::KHR_swapchain,
+ reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabledAcquireNextImageKHR),
+ reinterpret_cast<PFN_vkVoidFunction>(checkedAcquireNextImageKHR),
+ },
+ {
+ "vkAllocateCommandBuffers",
+ ProcHook::DEVICE,
+ ProcHook::EXTENSION_CORE,
+ reinterpret_cast<PFN_vkVoidFunction>(AllocateCommandBuffers_Bottom),
+ nullptr,
+ nullptr,
+ },
+ {
+ "vkCreateAndroidSurfaceKHR",
+ ProcHook::INSTANCE,
+ ProcHook::KHR_android_surface,
+ reinterpret_cast<PFN_vkVoidFunction>(CreateAndroidSurfaceKHR_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabledCreateAndroidSurfaceKHR),
+ nullptr,
+ },
+ {
+ "vkCreateDebugReportCallbackEXT",
+ ProcHook::INSTANCE,
+ ProcHook::EXT_debug_report,
+ reinterpret_cast<PFN_vkVoidFunction>(CreateDebugReportCallbackEXT_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabledCreateDebugReportCallbackEXT),
+ nullptr,
+ },
+ {
+ "vkCreateDevice",
+ ProcHook::INSTANCE,
+ ProcHook::EXTENSION_CORE,
+ reinterpret_cast<PFN_vkVoidFunction>(CreateDevice_Bottom),
+ nullptr,
+ nullptr,
+ },
+ {
+ "vkCreateInstance",
+ ProcHook::GLOBAL,
+ ProcHook::EXTENSION_CORE,
+ reinterpret_cast<PFN_vkVoidFunction>(CreateInstance_Bottom),
+ nullptr,
+ nullptr,
+ },
+ {
+ "vkCreateSwapchainKHR",
+ ProcHook::DEVICE,
+ ProcHook::KHR_swapchain,
+ reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabledCreateSwapchainKHR),
+ reinterpret_cast<PFN_vkVoidFunction>(checkedCreateSwapchainKHR),
+ },
+ {
+ "vkDebugReportMessageEXT",
+ ProcHook::INSTANCE,
+ ProcHook::EXT_debug_report,
+ reinterpret_cast<PFN_vkVoidFunction>(DebugReportMessageEXT_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabledDebugReportMessageEXT),
+ nullptr,
+ },
+ {
+ "vkDestroyDebugReportCallbackEXT",
+ ProcHook::INSTANCE,
+ ProcHook::EXT_debug_report,
+ reinterpret_cast<PFN_vkVoidFunction>(DestroyDebugReportCallbackEXT_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabledDestroyDebugReportCallbackEXT),
+ nullptr,
+ },
+ {
+ "vkDestroyDevice",
+ ProcHook::DEVICE,
+ ProcHook::EXTENSION_CORE,
+ reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice_Bottom),
+ nullptr,
+ nullptr,
+ },
+ {
+ "vkDestroyInstance",
+ ProcHook::INSTANCE,
+ ProcHook::EXTENSION_CORE,
+ reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance_Bottom),
+ nullptr,
+ nullptr,
+ },
+ {
+ "vkDestroySurfaceKHR",
+ ProcHook::INSTANCE,
+ ProcHook::KHR_surface,
+ reinterpret_cast<PFN_vkVoidFunction>(DestroySurfaceKHR_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabledDestroySurfaceKHR),
+ nullptr,
+ },
+ {
+ "vkDestroySwapchainKHR",
+ ProcHook::DEVICE,
+ ProcHook::KHR_swapchain,
+ reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabledDestroySwapchainKHR),
+ reinterpret_cast<PFN_vkVoidFunction>(checkedDestroySwapchainKHR),
+ },
+ {
+ "vkEnumerateDeviceExtensionProperties",
+ ProcHook::INSTANCE,
+ ProcHook::EXTENSION_CORE,
+ reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties_Bottom),
+ nullptr,
+ nullptr,
+ },
+ {
+ "vkEnumerateInstanceExtensionProperties",
+ ProcHook::GLOBAL,
+ ProcHook::EXTENSION_CORE,
+ reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties),
+ nullptr,
+ nullptr,
+ },
+ {
+ "vkEnumeratePhysicalDevices",
+ ProcHook::INSTANCE,
+ ProcHook::EXTENSION_CORE,
+ reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices_Bottom),
+ nullptr,
+ nullptr,
+ },
+ {
+ "vkGetDeviceProcAddr",
+ ProcHook::DEVICE,
+ ProcHook::EXTENSION_CORE,
+ reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr),
+ nullptr,
+ nullptr,
+ },
+ {
+ "vkGetDeviceQueue",
+ ProcHook::DEVICE,
+ ProcHook::EXTENSION_CORE,
+ reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue_Bottom),
+ nullptr,
+ nullptr,
+ },
+ {
+ "vkGetInstanceProcAddr",
+ ProcHook::INSTANCE,
+ ProcHook::EXTENSION_CORE,
+ reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr),
+ nullptr,
+ nullptr,
+ },
+ {
+ "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
+ ProcHook::INSTANCE,
+ ProcHook::KHR_surface,
+ reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilitiesKHR_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabledGetPhysicalDeviceSurfaceCapabilitiesKHR),
+ nullptr,
+ },
+ {
+ "vkGetPhysicalDeviceSurfaceFormatsKHR",
+ ProcHook::INSTANCE,
+ ProcHook::KHR_surface,
+ reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormatsKHR_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabledGetPhysicalDeviceSurfaceFormatsKHR),
+ nullptr,
+ },
+ {
+ "vkGetPhysicalDeviceSurfacePresentModesKHR",
+ ProcHook::INSTANCE,
+ ProcHook::KHR_surface,
+ reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabledGetPhysicalDeviceSurfacePresentModesKHR),
+ nullptr,
+ },
+ {
+ "vkGetPhysicalDeviceSurfaceSupportKHR",
+ ProcHook::INSTANCE,
+ ProcHook::KHR_surface,
+ reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceSupportKHR_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabledGetPhysicalDeviceSurfaceSupportKHR),
+ nullptr,
+ },
+ {
+ "vkGetSwapchainGrallocUsageANDROID",
+ ProcHook::DEVICE,
+ ProcHook::ANDROID_native_buffer,
+ nullptr,
+ nullptr,
+ nullptr,
+ },
+ {
+ "vkGetSwapchainImagesKHR",
+ ProcHook::DEVICE,
+ ProcHook::KHR_swapchain,
+ reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabledGetSwapchainImagesKHR),
+ reinterpret_cast<PFN_vkVoidFunction>(checkedGetSwapchainImagesKHR),
+ },
+ {
+ "vkQueuePresentKHR",
+ ProcHook::DEVICE,
+ ProcHook::KHR_swapchain,
+ reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR_Bottom),
+ reinterpret_cast<PFN_vkVoidFunction>(disabledQueuePresentKHR),
+ reinterpret_cast<PFN_vkVoidFunction>(checkedQueuePresentKHR),
+ },
+ {
+ "vkQueueSignalReleaseImageANDROID",
+ ProcHook::DEVICE,
+ ProcHook::ANDROID_native_buffer,
+ nullptr,
+ nullptr,
+ nullptr,
+ },
+ // clang-format on
+};
+
+} // anonymous
+
+const ProcHook* GetProcHook(const char* name) {
+ const auto& begin = g_proc_hooks;
+ const auto& end =
+ g_proc_hooks + sizeof(g_proc_hooks) / sizeof(g_proc_hooks[0]);
+ const auto hook = std::lower_bound(
+ begin, end, name,
+ [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; });
+ return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr;
+}
+
+ProcHook::Extension GetProcHookExtension(const char* name) {
+ // clang-format off
+ if (strcmp(name, "VK_ANDROID_native_buffer") == 0) return ProcHook::ANDROID_native_buffer;
+ if (strcmp(name, "VK_EXT_debug_report") == 0) return ProcHook::EXT_debug_report;
+ if (strcmp(name, "VK_KHR_android_surface") == 0) return ProcHook::KHR_android_surface;
+ if (strcmp(name, "VK_KHR_surface") == 0) return ProcHook::KHR_surface;
+ if (strcmp(name, "VK_KHR_swapchain") == 0) return ProcHook::KHR_swapchain;
+ // clang-format on
+ return ProcHook::EXTENSION_UNKNOWN;
+}
+
+} // namespace driver
+} // namespace vulkan
+
+// clang-format on
diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h
new file mode 100644
index 0000000..63dadcb
--- /dev/null
+++ b/vulkan/libvulkan/driver_gen.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// WARNING: This file is generated. See ../README.md for instructions.
+
+#ifndef LIBVULKAN_DRIVER_GEN_H
+#define LIBVULKAN_DRIVER_GEN_H
+
+#include <vulkan/vulkan.h>
+#include <vulkan/vk_android_native_buffer.h>
+
+namespace vulkan {
+namespace driver {
+
+struct ProcHook {
+ enum Type {
+ GLOBAL,
+ INSTANCE,
+ DEVICE,
+ };
+ enum Extension {
+ ANDROID_native_buffer,
+ EXT_debug_report,
+ KHR_android_surface,
+ KHR_surface,
+ KHR_swapchain,
+
+ EXTENSION_CORE, // valid bit
+ EXTENSION_COUNT,
+ EXTENSION_UNKNOWN,
+ };
+
+ const char* name;
+ Type type;
+ Extension extension;
+
+ PFN_vkVoidFunction proc;
+ PFN_vkVoidFunction disabled_proc; // nullptr for global hooks
+ PFN_vkVoidFunction checked_proc; // nullptr for global/instance hooks
+};
+
+const ProcHook* GetProcHook(const char* name);
+ProcHook::Extension GetProcHookExtension(const char* name);
+
+} // namespace driver
+} // namespace vulkan
+
+#endif // LIBVULKAN_DRIVER_TABLE_H
diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp
index 2d48fda..8c68efa 100644
--- a/vulkan/libvulkan/loader.cpp
+++ b/vulkan/libvulkan/loader.cpp
@@ -142,7 +142,7 @@
struct Instance {
Instance(const VkAllocationCallbacks* alloc_callbacks)
- : base{{}, *alloc_callbacks},
+ : base(*alloc_callbacks),
alloc(&base.allocator),
num_physical_devices(0) {
memset(physical_devices, 0, sizeof(physical_devices));
@@ -169,15 +169,13 @@
};
struct Device {
- Device(Instance* instance_)
- : base{{}, *instance_->alloc}, instance(instance_) {
+ Device(Instance* instance_) : base(*instance_->alloc), instance(instance_) {
enabled_extensions.reset();
}
driver::DeviceData base;
Instance* instance;
- PFN_vkGetDeviceProcAddr get_device_proc_addr;
DeviceExtensionSet enabled_extensions;
};
@@ -272,6 +270,32 @@
allocator->pfnFree(allocator->pUserData, instance);
}
+driver::ProcHook::Extension InstanceExtensionToProcHookExtension(
+ InstanceExtension id) {
+ switch (id) {
+ case kKHR_surface:
+ return driver::ProcHook::KHR_surface;
+ case kKHR_android_surface:
+ return driver::ProcHook::KHR_android_surface;
+ case kEXT_debug_report:
+ return driver::ProcHook::EXT_debug_report;
+ default:
+ return driver::ProcHook::EXTENSION_UNKNOWN;
+ }
+}
+
+driver::ProcHook::Extension DeviceExtensionToProcHookExtension(
+ DeviceExtension id) {
+ switch (id) {
+ case kKHR_swapchain:
+ return driver::ProcHook::KHR_swapchain;
+ case kANDROID_native_buffer:
+ return driver::ProcHook::ANDROID_native_buffer;
+ default:
+ return driver::ProcHook::EXTENSION_UNKNOWN;
+ }
+}
+
} // anonymous namespace
namespace vulkan {
@@ -297,6 +321,7 @@
// Check that all enabled extensions are supported
uint32_t num_driver_extensions = 0;
+ bool enable_kEXT_debug_report = false;
for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
const char* name = create_info->ppEnabledExtensionNames[i];
InstanceExtension id = InstanceExtensionFromName(name);
@@ -312,11 +337,27 @@
}
// The loader natively supports debug report.
if (id == kEXT_debug_report) {
+ enable_kEXT_debug_report = true;
continue;
}
}
}
+ auto& hal_exts = instance.base.hal_extensions;
+ for (size_t i = 0; i < instance.enabled_extensions.size(); i++) {
+ if (instance.enabled_extensions[i]) {
+ auto bit = InstanceExtensionToProcHookExtension(
+ static_cast<InstanceExtension>(i));
+ if (bit != driver::ProcHook::EXTENSION_UNKNOWN)
+ hal_exts.set(bit);
+ }
+ }
+
+ auto& hook_exts = instance.base.hook_extensions;
+ hook_exts = hal_exts;
+ if (enable_kEXT_debug_report)
+ hook_exts.set(driver::ProcHook::EXT_debug_report);
+
VkInstanceCreateInfo driver_create_info = *create_info;
driver_create_info.pNext = StripCreateExtensions(create_info->pNext);
driver_create_info.enabledLayerCount = 0;
@@ -430,111 +471,6 @@
return VK_SUCCESS;
}
-VkResult CreateAndroidSurfaceKHR_Disabled(VkInstance,
- const VkAndroidSurfaceCreateInfoKHR*,
- const VkAllocationCallbacks*,
- VkSurfaceKHR*) {
- ALOGE(
- "VK_KHR_android_surface not enabled. vkCreateAndroidSurfaceKHR not "
- "executed.");
-
- return VK_SUCCESS;
-}
-
-void DestroySurfaceKHR_Disabled(VkInstance,
- VkSurfaceKHR,
- const VkAllocationCallbacks*) {
- ALOGE("VK_KHR_surface not enabled. vkDestroySurfaceKHR not executed.");
-}
-
-VkResult GetPhysicalDeviceSurfaceSupportKHR_Disabled(VkPhysicalDevice,
- uint32_t,
- VkSurfaceKHR,
- VkBool32*) {
- ALOGE(
- "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceSupportKHR not "
- "executed.");
-
- return VK_SUCCESS;
-}
-
-VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR_Disabled(
- VkPhysicalDevice,
- VkSurfaceKHR,
- VkSurfaceCapabilitiesKHR*) {
- ALOGE(
- "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceapabilitiesKHR "
- "not executed.");
-
- return VK_SUCCESS;
-}
-
-VkResult GetPhysicalDeviceSurfaceFormatsKHR_Disabled(VkPhysicalDevice,
- VkSurfaceKHR,
- uint32_t*,
- VkSurfaceFormatKHR*) {
- ALOGE(
- "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceFormatsKHR not "
- "executed.");
-
- return VK_SUCCESS;
-}
-
-VkResult GetPhysicalDeviceSurfacePresentModesKHR_Disabled(VkPhysicalDevice,
- VkSurfaceKHR,
- uint32_t*,
- VkPresentModeKHR*) {
- ALOGE(
- "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfacePresentModesKHR "
- "not executed.");
-
- return VK_SUCCESS;
-}
-
-PFN_vkVoidFunction GetInstanceProcAddr_Bottom(VkInstance vkinstance,
- const char* name) {
- PFN_vkVoidFunction pfn;
-
- if (vkinstance) {
- Instance& instance = GetDispatchParent(vkinstance);
- if (!instance.enabled_extensions[kKHR_android_surface]) {
- // KHR_android_surface is not enabled, use error stubs instead
- if (strcmp(name, "vkCreateAndroidSurfaceKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- CreateAndroidSurfaceKHR_Disabled);
- }
- }
- if (!instance.enabled_extensions[kKHR_surface]) {
- // KHR_surface is not enabled, use error stubs instead
- if (strcmp(name, "vkDestroySurfaceKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- DestroySurfaceKHR_Disabled);
- }
- if (strcmp(name, "vkGetPhysicalDeviceSurfaceSupportKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- GetPhysicalDeviceSurfaceSupportKHR_Disabled);
- }
- if (strcmp(name, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR") ==
- 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- GetPhysicalDeviceSurfaceCapabilitiesKHR_Disabled);
- }
- if (strcmp(name, "vkGetPhysicalDeviceSurfaceFormatsKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- GetPhysicalDeviceSurfaceFormatsKHR_Disabled);
- }
- if (strcmp(name, "vkGetPhysicalDeviceSurfacePresentModesKHR") ==
- 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- GetPhysicalDeviceSurfacePresentModesKHR_Disabled);
- }
- }
- }
- if ((pfn = GetLoaderBottomProcAddr(name)))
- return pfn;
- return g_hwdevice->GetInstanceProcAddr(vkinstance, name);
-}
-
VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance,
uint32_t* pdev_count,
VkPhysicalDevice* pdevs) {
@@ -549,69 +485,6 @@
return VK_SUCCESS;
}
-void GetPhysicalDeviceProperties_Bottom(
- VkPhysicalDevice pdev,
- VkPhysicalDeviceProperties* properties) {
- GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceProperties(
- pdev, properties);
-}
-
-void GetPhysicalDeviceFeatures_Bottom(VkPhysicalDevice pdev,
- VkPhysicalDeviceFeatures* features) {
- GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFeatures(pdev,
- features);
-}
-
-void GetPhysicalDeviceMemoryProperties_Bottom(
- VkPhysicalDevice pdev,
- VkPhysicalDeviceMemoryProperties* properties) {
- GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceMemoryProperties(
- pdev, properties);
-}
-
-void GetPhysicalDeviceQueueFamilyProperties_Bottom(
- VkPhysicalDevice pdev,
- uint32_t* pCount,
- VkQueueFamilyProperties* properties) {
- GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceQueueFamilyProperties(
- pdev, pCount, properties);
-}
-
-void GetPhysicalDeviceFormatProperties_Bottom(VkPhysicalDevice pdev,
- VkFormat format,
- VkFormatProperties* properties) {
- GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFormatProperties(
- pdev, format, properties);
-}
-
-VkResult GetPhysicalDeviceImageFormatProperties_Bottom(
- VkPhysicalDevice pdev,
- VkFormat format,
- VkImageType type,
- VkImageTiling tiling,
- VkImageUsageFlags usage,
- VkImageCreateFlags flags,
- VkImageFormatProperties* properties) {
- return GetDispatchParent(pdev)
- .drv.dispatch.GetPhysicalDeviceImageFormatProperties(
- pdev, format, type, tiling, usage, flags, properties);
-}
-
-void GetPhysicalDeviceSparseImageFormatProperties_Bottom(
- VkPhysicalDevice pdev,
- VkFormat format,
- VkImageType type,
- VkSampleCountFlagBits samples,
- VkImageUsageFlags usage,
- VkImageTiling tiling,
- uint32_t* properties_count,
- VkSparseImageFormatProperties* properties) {
- GetDispatchParent(pdev)
- .drv.dispatch.GetPhysicalDeviceSparseImageFormatProperties(
- pdev, format, type, samples, usage, tiling, properties_count,
- properties);
-}
-
VKAPI_ATTR
VkResult EnumerateDeviceExtensionProperties_Bottom(
VkPhysicalDevice pdev,
@@ -646,16 +519,6 @@
return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS;
}
-// This is a no-op, the Top function returns the aggregate layer property
-// data. This is to keep the dispatch generator happy.
-VKAPI_ATTR
-VkResult EnumerateDeviceLayerProperties_Bottom(
- VkPhysicalDevice /*pdev*/,
- uint32_t* /*properties_count*/,
- VkLayerProperties* /*properties*/) {
- return VK_SUCCESS;
-}
-
VKAPI_ATTR
VkResult CreateDevice_Bottom(VkPhysicalDevice gpu,
const VkDeviceCreateInfo* create_info,
@@ -710,6 +573,26 @@
}
}
+ // Unlike instance->enabled_extensions, device->enabled_extensions maps to
+ // hook extensions.
+ auto& hook_exts = device->base.hook_extensions;
+ for (size_t i = 0; i < device->enabled_extensions.size(); i++) {
+ if (device->enabled_extensions[i]) {
+ auto bit = DeviceExtensionToProcHookExtension(
+ static_cast<DeviceExtension>(i));
+ if (bit != driver::ProcHook::EXTENSION_UNKNOWN)
+ hook_exts.set(bit);
+ }
+ }
+
+ auto& hal_exts = device->base.hal_extensions;
+ hal_exts = hook_exts;
+ // map VK_KHR_swapchain to VK_ANDROID_native_buffer
+ if (hal_exts[driver::ProcHook::KHR_swapchain]) {
+ hal_exts.reset(driver::ProcHook::KHR_swapchain);
+ hal_exts.set(driver::ProcHook::ANDROID_native_buffer);
+ }
+
driver_create_info.enabledExtensionCount = num_driver_extensions;
driver_create_info.ppEnabledExtensionNames = driver_extensions;
VkDevice drv_device;
@@ -725,9 +608,11 @@
return VK_ERROR_INITIALIZATION_FAILED;
}
- device->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(
- instance.drv.dispatch.GetDeviceProcAddr(drv_device,
- "vkGetDeviceProcAddr"));
+ device->base.get_device_proc_addr =
+ reinterpret_cast<PFN_vkGetDeviceProcAddr>(
+ instance.drv.dispatch.GetDeviceProcAddr(drv_device,
+ "vkGetDeviceProcAddr"));
+
*device_out = drv_device;
return VK_SUCCESS;
}
@@ -745,91 +630,6 @@
DestroyInstance(&instance, allocator, vkinstance);
}
-VkResult CreateSwapchainKHR_Disabled(VkDevice,
- const VkSwapchainCreateInfoKHR*,
- const VkAllocationCallbacks*,
- VkSwapchainKHR*) {
- ALOGE("VK_KHR_swapchain not enabled. vkCreateSwapchainKHR not executed.");
-
- return VK_SUCCESS;
-}
-
-void DestroySwapchainKHR_Disabled(VkDevice,
- VkSwapchainKHR,
- const VkAllocationCallbacks*) {
- ALOGE("VK_KHR_swapchain not enabled. vkDestroySwapchainKHR not executed.");
-}
-
-VkResult GetSwapchainImagesKHR_Disabled(VkDevice,
- VkSwapchainKHR,
- uint32_t*,
- VkImage*) {
- ALOGE(
- "VK_KHR_swapchain not enabled. vkGetSwapchainImagesKHR not executed.");
-
- return VK_SUCCESS;
-}
-
-VkResult AcquireNextImageKHR_Disabled(VkDevice,
- VkSwapchainKHR,
- uint64_t,
- VkSemaphore,
- VkFence,
- uint32_t*) {
- ALOGE("VK_KHR_swapchain not enabled. vkAcquireNextImageKHR not executed.");
-
- return VK_SUCCESS;
-}
-
-VkResult QueuePresentKHR_Disabled(VkQueue, const VkPresentInfoKHR*) {
- ALOGE("VK_KHR_swapchain not enabled. vkQueuePresentKHR not executed.");
-
- return VK_SUCCESS;
-}
-
-PFN_vkVoidFunction GetDeviceProcAddr_Bottom(VkDevice vkdevice,
- const char* name) {
- if (strcmp(name, "vkCreateDevice") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(CreateDevice_Bottom);
- }
-
- Device& device = GetDispatchParent(vkdevice);
- if (!device.enabled_extensions[kKHR_swapchain]) {
- if (strcmp(name, "vkCreateSwapchainKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- CreateSwapchainKHR_Disabled);
- }
- if (strcmp(name, "vkDestroySwapchainKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- DestroySwapchainKHR_Disabled);
- }
- if (strcmp(name, "vkGetSwapchainImagesKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- GetSwapchainImagesKHR_Disabled);
- }
- if (strcmp(name, "vkAcquireNextSwapchainImageKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- AcquireNextImageKHR_Disabled);
- }
- if (strcmp(name, "vkQueuePresentKHR") == 0) {
- return reinterpret_cast<PFN_vkVoidFunction>(
- QueuePresentKHR_Disabled);
- }
- }
-
- // VK_ANDROID_native_buffer should be hidden from applications and layers.
- // TODO(jessehall): Generate this as part of GetLoaderBottomProcAddr.
- PFN_vkVoidFunction pfn;
- if (strcmp(name, "vkGetSwapchainGrallocUsageANDROID") == 0 ||
- strcmp(name, "vkAcquireImageANDROID") == 0 ||
- strcmp(name, "vkQueueSignalReleaseImageANDROID") == 0) {
- return nullptr;
- }
- if ((pfn = GetLoaderBottomProcAddr(name)))
- return pfn;
- return GetDispatchParent(vkdevice).get_device_proc_addr(vkdevice, name);
-}
-
void DestroyDevice_Bottom(VkDevice vkdevice, const VkAllocationCallbacks*) {
DestroyDevice(&GetDispatchParent(vkdevice), vkdevice);
}
@@ -904,14 +704,6 @@
namespace driver {
-PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
- return GetInstanceProcAddr_Bottom(instance, pName);
-}
-
-PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) {
- return GetDeviceProcAddr_Bottom(device, pName);
-}
-
VkResult EnumerateInstanceExtensionProperties(
const char* pLayerName,
uint32_t* pPropertyCount,
diff --git a/vulkan/libvulkan/loader.h b/vulkan/libvulkan/loader.h
index 255b6c5..15b773d 100644
--- a/vulkan/libvulkan/loader.h
+++ b/vulkan/libvulkan/loader.h
@@ -43,7 +43,6 @@
// -----------------------------------------------------------------------------
// dispatch_gen.cpp
-PFN_vkVoidFunction GetLoaderBottomProcAddr(const char* name);
bool LoadDriverDispatchTable(VkInstance instance,
PFN_vkGetInstanceProcAddr get_proc_addr,
const InstanceExtensionSet& extensions,
@@ -56,20 +55,10 @@
// clang-format off
VKAPI_ATTR VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, const VkAllocationCallbacks* allocator, VkInstance* vkinstance);
-VKAPI_ATTR PFN_vkVoidFunction GetInstanceProcAddr_Bottom(VkInstance, const char* name);
VKAPI_ATTR VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance, uint32_t* pdev_count, VkPhysicalDevice* pdevs);
-VKAPI_ATTR void GetPhysicalDeviceProperties_Bottom(VkPhysicalDevice pdev, VkPhysicalDeviceProperties* properties);
-VKAPI_ATTR void GetPhysicalDeviceFeatures_Bottom(VkPhysicalDevice pdev, VkPhysicalDeviceFeatures* features);
-VKAPI_ATTR void GetPhysicalDeviceMemoryProperties_Bottom(VkPhysicalDevice pdev, VkPhysicalDeviceMemoryProperties* properties);
-VKAPI_ATTR void GetPhysicalDeviceQueueFamilyProperties_Bottom(VkPhysicalDevice pdev, uint32_t* properties_count, VkQueueFamilyProperties* properties);
-VKAPI_ATTR void GetPhysicalDeviceFormatProperties_Bottom(VkPhysicalDevice pdev, VkFormat format, VkFormatProperties* properties);
-VKAPI_ATTR VkResult GetPhysicalDeviceImageFormatProperties_Bottom(VkPhysicalDevice pdev, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* properties);
-VKAPI_ATTR void GetPhysicalDeviceSparseImageFormatProperties_Bottom(VkPhysicalDevice pdev, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* properties_count, VkSparseImageFormatProperties* properties);
VKAPI_ATTR VkResult EnumerateDeviceExtensionProperties_Bottom(VkPhysicalDevice pdev, const char* layer_name, uint32_t* properties_count, VkExtensionProperties* properties);
-VKAPI_ATTR VkResult EnumerateDeviceLayerProperties_Bottom(VkPhysicalDevice pdev, uint32_t* properties_count, VkLayerProperties* properties);
VKAPI_ATTR VkResult CreateDevice_Bottom(VkPhysicalDevice pdev, const VkDeviceCreateInfo* create_info, const VkAllocationCallbacks* allocator, VkDevice* device_out);
VKAPI_ATTR void DestroyInstance_Bottom(VkInstance vkinstance, const VkAllocationCallbacks* allocator);
-VKAPI_ATTR PFN_vkVoidFunction GetDeviceProcAddr_Bottom(VkDevice vkdevice, const char* name);
VKAPI_ATTR void DestroyDevice_Bottom(VkDevice device, const VkAllocationCallbacks* pAllocator);
VKAPI_ATTR void GetDeviceQueue_Bottom(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue);
VKAPI_ATTR VkResult AllocateCommandBuffers_Bottom(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers);
@@ -98,18 +87,6 @@
VKAPI_ATTR VkResult GetSwapchainImagesKHR_Bottom(VkDevice device, VkSwapchainKHR swapchain_handle, uint32_t* count, VkImage* images);
VKAPI_ATTR VkResult AcquireNextImageKHR_Bottom(VkDevice device, VkSwapchainKHR swapchain_handle, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* image_index);
VKAPI_ATTR VkResult QueuePresentKHR_Bottom(VkQueue queue, const VkPresentInfoKHR* present_info);
-
-VKAPI_ATTR VkResult CreateAndroidSurfaceKHR_Disabled(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
-VKAPI_ATTR void DestroySurfaceKHR_Disabled(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks*);
-VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceSupportKHR_Disabled(VkPhysicalDevice, uint32_t, VkSurfaceKHR, VkBool32*);
-VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR_Disabled(VkPhysicalDevice, VkSurfaceKHR, VkSurfaceCapabilitiesKHR*);
-VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceFormatsKHR_Disabled(VkPhysicalDevice, VkSurfaceKHR, uint32_t*, VkSurfaceFormatKHR*);
-VKAPI_ATTR VkResult GetPhysicalDeviceSurfacePresentModesKHR_Disabled(VkPhysicalDevice, VkSurfaceKHR, uint32_t*, VkPresentModeKHR*);
-VKAPI_ATTR VkResult CreateSwapchainKHR_Disabled(VkDevice device, const VkSwapchainCreateInfoKHR* create_info, const VkAllocationCallbacks* allocator, VkSwapchainKHR* swapchain_handle);
-VKAPI_ATTR void DestroySwapchainKHR_Disabled(VkDevice device, VkSwapchainKHR swapchain_handle, const VkAllocationCallbacks* allocator);
-VKAPI_ATTR VkResult GetSwapchainImagesKHR_Disabled(VkDevice device, VkSwapchainKHR swapchain_handle, uint32_t* count, VkImage* images);
-VKAPI_ATTR VkResult AcquireNextImageKHR_Disabled(VkDevice device, VkSwapchainKHR swapchain_handle, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* image_index);
-VKAPI_ATTR VkResult QueuePresentKHR_Disabled(VkQueue queue, const VkPresentInfoKHR* present_info);
// clang-format on
// -----------------------------------------------------------------------------