diff options
author | 2016-03-24 09:11:06 +0800 | |
---|---|---|
committer | 2016-04-07 21:15:03 +0800 | |
commit | eb7db124e46da9a9210cf868353f5ea79502ffec (patch) | |
tree | 58801422f306957db776bcaa000e648ce7b6bd82 | |
parent | b262ddcfaba592ca153beddb120aeb68b64e6e63 (diff) |
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
-rw-r--r-- | vulkan/libvulkan/Android.mk | 1 | ||||
-rw-r--r-- | vulkan/libvulkan/code-generator.tmpl | 390 | ||||
-rw-r--r-- | vulkan/libvulkan/dispatch.tmpl | 39 | ||||
-rw-r--r-- | vulkan/libvulkan/dispatch_gen.cpp | 66 | ||||
-rw-r--r-- | vulkan/libvulkan/driver.cpp | 62 | ||||
-rw-r--r-- | vulkan/libvulkan/driver.h | 22 | ||||
-rw-r--r-- | vulkan/libvulkan/driver_gen.cpp | 376 | ||||
-rw-r--r-- | vulkan/libvulkan/driver_gen.h | 61 | ||||
-rw-r--r-- | vulkan/libvulkan/loader.cpp | 348 | ||||
-rw-r--r-- | vulkan/libvulkan/loader.h | 23 |
10 files changed, 982 insertions, 406 deletions
diff --git a/vulkan/libvulkan/Android.mk b/vulkan/libvulkan/Android.mk index 665d45eac3..62d12797b1 100644 --- a/vulkan/libvulkan/Android.mk +++ b/vulkan/libvulkan/Android.mk @@ -44,6 +44,7 @@ LOCAL_SRC_FILES := \ 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 7ebe983dba..f7083c3146 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 @@ bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) { {{/* +------------------------------------------------------------------------------- + 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 @@ bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) { {{/* +------------------------------------------------------------------------------ + 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 @@ bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) { {{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 67ead4a055..fd778790bf 100644 --- a/vulkan/libvulkan/dispatch.tmpl +++ b/vulkan/libvulkan/dispatch.tmpl @@ -118,47 +118,8 @@ struct DriverDispatchTable {« ¶ 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 eacf1a1094..fa199bd25c 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 4acc867201..68ae5c8314 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -143,5 +143,67 @@ const VkAllocationCallbacks& GetDefaultAllocator() { 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 de9d1c65a0..28b0ce6cde 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 @@ struct DeviceData { 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 0000000000..d725df5a62 --- /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 0000000000..63dadcbdb3 --- /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 2d48fda688..8c68efa70a 100644 --- a/vulkan/libvulkan/loader.cpp +++ b/vulkan/libvulkan/loader.cpp @@ -142,7 +142,7 @@ bool LoadVulkanHAL() { 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 Instance { }; 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 @@ void DestroyInstance(Instance* instance, 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 @@ VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, // 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 @@ VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, } // 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 @@ VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, 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 @@ VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance, 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 @@ VkResult EnumerateDeviceExtensionProperties_Bottom( 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 @@ VkResult CreateDevice_Bottom(VkPhysicalDevice gpu, } } + // 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 @@ VkResult CreateDevice_Bottom(VkPhysicalDevice gpu, 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 @@ void DestroyInstance_Bottom(VkInstance vkinstance, 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 @@ bool InitLoader(hwvulkan_device_t* dev) { 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 255b6c517d..15b773d713 100644 --- a/vulkan/libvulkan/loader.h +++ b/vulkan/libvulkan/loader.h @@ -43,7 +43,6 @@ typedef std::bitset<kDeviceExtensionCount> DeviceExtensionSet; // ----------------------------------------------------------------------------- // 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 @@ bool InitLoader(hwvulkan_device_t* dev); // 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 void DestroySwapchainKHR_Bottom(VkDevice device, VkSwapchainKHR swapc 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 // ----------------------------------------------------------------------------- |