diff options
-rw-r--r-- | vulkan/api/platform.api | 1 | ||||
-rw-r--r-- | vulkan/api/vulkan.api | 45 | ||||
-rw-r--r-- | vulkan/libvulkan/Android.mk | 4 | ||||
-rw-r--r-- | vulkan/libvulkan/api.cpp | 2 | ||||
-rw-r--r-- | vulkan/libvulkan/code-generator.tmpl | 553 | ||||
-rw-r--r-- | vulkan/libvulkan/debug_report.cpp | 73 | ||||
-rw-r--r-- | vulkan/libvulkan/debug_report.h | 9 | ||||
-rw-r--r-- | vulkan/libvulkan/dispatch.tmpl | 365 | ||||
-rw-r--r-- | vulkan/libvulkan/dispatch_gen.cpp | 226 | ||||
-rw-r--r-- | vulkan/libvulkan/driver.cpp | 769 | ||||
-rw-r--r-- | vulkan/libvulkan/driver.h | 43 | ||||
-rw-r--r-- | vulkan/libvulkan/driver_gen.cpp | 431 | ||||
-rw-r--r-- | vulkan/libvulkan/driver_gen.h (renamed from vulkan/libvulkan/dispatch_gen.h) | 62 | ||||
-rw-r--r-- | vulkan/libvulkan/layers_extensions.cpp | 28 | ||||
-rw-r--r-- | vulkan/libvulkan/layers_extensions.h | 64 | ||||
-rw-r--r-- | vulkan/libvulkan/loader.cpp | 1045 | ||||
-rw-r--r-- | vulkan/libvulkan/loader.h | 155 | ||||
-rw-r--r-- | vulkan/libvulkan/swapchain.cpp | 104 | ||||
-rw-r--r-- | vulkan/libvulkan/swapchain.h | 42 |
19 files changed, 2086 insertions, 1935 deletions
diff --git a/vulkan/api/platform.api b/vulkan/api/platform.api index 980722db0c..7aa19e7461 100644 --- a/vulkan/api/platform.api +++ b/vulkan/api/platform.api @@ -43,6 +43,7 @@ type u64 size_t // VK_USE_PLATFORM_ANDROID_KHR @internal class ANativeWindow {} +@internal type void* buffer_handle_t // VK_USE_PLATFORM_WIN32_KHR @internal type void* HINSTANCE diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api index 10565abb8b..ae690a323b 100644 --- a/vulkan/api/vulkan.api +++ b/vulkan/api/vulkan.api @@ -75,6 +75,9 @@ define NULL_HANDLE 0 @extension("VK_KHR_win32_surface") define VK_KHR_WIN32_SURFACE_SPEC_VERSION 5 @extension("VK_KHR_win32_surface") define VK_KHR_WIN32_SURFACE_NAME "VK_KHR_win32_surface" +@extension("VK_ANDROID_native_buffer") define VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 5 +@extension("VK_ANDROID_native_buffer") define VK_ANDROID_NATIVE_BUFFER_NAME "VK_ANDROID_native_buffer" + @extension("VK_EXT_debug_report") define VK_EXT_DEBUG_REPORT_SPEC_VERSION 1 @extension("VK_EXT_debug_report") define VK_EXT_DEBUG_REPORT_NAME "VK_EXT_debug_report" @@ -646,6 +649,9 @@ enum VkStructureType { //@extension("VK_KHR_win32_surface") VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, + //@extension("VK_ANDROID_native_buffer") + VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID = 1000010000, + //@extension("VK_EXT_debug_report") VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = 1000011000, } @@ -2591,6 +2597,16 @@ class VkWin32SurfaceCreateInfoKHR { platform.HWND hwnd } +@extension("VK_ANDROID_native_buffer") +class VkNativeBufferANDROID { + VkStructureType sType + const void* pNext + platform.buffer_handle_t handle + int stride + int format + int usage +} + @extension("VK_EXT_debug_report") class VkDebugReportCallbackCreateInfoEXT { VkStructureType sType @@ -5134,6 +5150,35 @@ cmd VkResult vkGetPhysicalDeviceWin32PresentationSupportKHR( return ? } +@extension("VK_ANDROID_native_buffer") +cmd VkResult vkGetSwapchainGrallocUsageANDROID( + VkDevice device, + VkFormat format, + VkImageUsageFlags imageUsage, + int* grallocUsage) { + return ? +} + +@extension("VK_ANDROID_native_buffer") +cmd VkResult vkAcquireImageANDROID( + VkDevice device, + VkImage image, + int nativeFenceFd, + VkSemaphore semaphore, + VkFence fence) { + return ? +} + +@extension("VK_ANDROID_native_buffer") +cmd VkResult vkQueueSignalReleaseImageANDROID( + VkQueue queue, + u32 waitSemaphoreCount, + const VkSemaphore* pWaitSemaphores, + VkImage image, + int* pNativeFenceFd) { + return ? +} + @extension("VK_EXT_debug_report") @external type void* PFN_vkDebugReportCallbackEXT @extension("VK_EXT_debug_report") diff --git a/vulkan/libvulkan/Android.mk b/vulkan/libvulkan/Android.mk index e60d74c079..0979471161 100644 --- a/vulkan/libvulkan/Android.mk +++ b/vulkan/libvulkan/Android.mk @@ -42,9 +42,9 @@ LOCAL_SRC_FILES := \ api.cpp \ api_gen.cpp \ debug_report.cpp \ - dispatch_gen.cpp \ + driver.cpp \ + driver_gen.cpp \ layers_extensions.cpp \ - loader.cpp \ swapchain.cpp \ vulkan_loader_data.cpp LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk diff --git a/vulkan/libvulkan/api.cpp b/vulkan/libvulkan/api.cpp index 549886feaf..e463f028ce 100644 --- a/vulkan/libvulkan/api.cpp +++ b/vulkan/libvulkan/api.cpp @@ -33,7 +33,7 @@ #include <vulkan/vk_layer_interface.h> #include "api.h" #include "driver.h" -#include "loader.h" +#include "layers_extensions.h" namespace vulkan { namespace api { diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl index 7ebe983dba..afe0d8417c 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"}} {{/* ------------------------------------------------------------------------------- @@ -44,7 +46,7 @@ struct InstanceDispatchTable { // clang-format off {{range $f := AllCommands $}} {{if (Macro "api.IsInstanceDispatchTableEntry" $f)}} - {{Macro "C++.DeclareDispatchTableEntry" $f}}; + {{Macro "C++.DeclareTableEntry" $f}}; {{end}} {{end}} // clang-format on @@ -54,7 +56,7 @@ struct DeviceDispatchTable { // clang-format off {{range $f := AllCommands $}} {{if (Macro "api.IsDeviceDispatchTableEntry" $f)}} - {{Macro "C++.DeclareDispatchTableEntry" $f}}; + {{Macro "C++.DeclareTableEntry" $f}}; {{end}} {{end}} // clang-format on @@ -89,7 +91,9 @@ bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc); namespace vulkan {« namespace api {« ¶ -{{Macro "C++.DefineInitProcMacros" "dispatch"}} +{{Macro "C++.DefineInitProcMacro" "dispatch"}} +¶ +{{Macro "api.C++.DefineInitProcExtMacro"}} ¶ bool InitDispatchTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc) { auto& data = GetData(instance); @@ -147,11 +151,173 @@ 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"}} +¶ +struct InstanceDriverTable { + // clang-format off + {{range $f := AllCommands $}} + {{if (Macro "driver.IsInstanceDriverTableEntry" $f)}} + {{Macro "C++.DeclareTableEntry" $f}}; + {{end}} + {{end}} + // clang-format on +}; +¶ +struct DeviceDriverTable { + // clang-format off + {{range $f := AllCommands $}} + {{if (Macro "driver.IsDeviceDriverTableEntry" $f)}} + {{Macro "C++.DeclareTableEntry" $f}}; + {{end}} + {{end}} + // clang-format on +}; +¶ +const ProcHook* GetProcHook(const char* name); +ProcHook::Extension GetProcHookExtension(const char* name); +¶ +bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc); +bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc); +¶ +»} // namespace driver +»} // namespace vulkan +¶ +#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" +¶ +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; +} +¶ +{{Macro "C++.DefineInitProcMacro" "driver"}} +¶ +{{Macro "driver.C++.DefineInitProcExtMacro"}} +¶ +bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc) +{ + auto& data = GetData(instance); + bool success = true; + ¶ + // clang-format off + {{range $f := AllCommands $}} + {{if (Macro "driver.IsInstanceDriverTableEntry" $f)}} + {{Macro "C++.InitProc" $f}} + {{end}} + {{end}} + // clang-format on + ¶ + return success; +} +¶ +bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) +{ + auto& data = GetData(dev); + bool success = true; + ¶ + // clang-format off + {{range $f := AllCommands $}} + {{if (Macro "driver.IsDeviceDriverTableEntry" $f)}} + {{Macro "C++.InitProc" $f}} + {{end}} + {{end}} + // clang-format on + ¶ + return success; +} +¶ +»} // namespace driver +»} // namespace vulkan +¶ +// clang-format on +¶{{end}} + + +{{/* ------------------------------------------------------------------------------ - Emits a declaration of a dispatch table entry. + Emits a declaration of a dispatch/driver table entry. ------------------------------------------------------------------------------ */}} -{{define "C++.DeclareDispatchTableEntry"}} +{{define "C++.DeclareTableEntry"}} {{AssertType $ "Function"}} {{Macro "FunctionPtrName" $}} {{Macro "BaseName" $}} @@ -160,10 +326,10 @@ bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) { {{/* ------------------------------------------------------------------------------- - Emits macros to help initialize dispatch tables. + Emits INIT_PROC macro. ------------------------------------------------------------------------------- */}} -{{define "C++.DefineInitProcMacros"}} +{{define "C++.DefineInitProcMacro"}} #define UNLIKELY(expr) __builtin_expect((expr), 0) ¶ #define INIT_PROC(obj, proc) do { \ @@ -174,11 +340,6 @@ bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) { success = false; \ } \ } while(0) - ¶ - // TODO do we want to point to a stub or nullptr when ext is not enabled? - #define INIT_PROC_EXT(ext, obj, proc) do { \ - INIT_PROC(obj, proc); \ - } while(0) {{end}} @@ -262,6 +423,19 @@ bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) { {{/* +------------------------------------------------------------------------------- + Emits INIT_PROC_EXT macro for vulkan::api. +------------------------------------------------------------------------------- +*/}} +{{define "api.C++.DefineInitProcExtMacro"}} + // TODO do we want to point to a stub or nullptr when ext is not enabled? + #define INIT_PROC_EXT(ext, obj, proc) do { \ + INIT_PROC(obj, proc); \ + } while(0) +{{end}} + + +{{/* ------------------------------------------------------------------------------ Emits code for vkGetInstanceProcAddr for function interception. ------------------------------------------------------------------------------ @@ -386,6 +560,348 @@ 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 "vkEnumeratePhysicalDevices"}}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 + + {{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 INIT_PROC_EXT macro for vulkan::driver. +------------------------------------------------------------------------------- +*/}} +{{define "driver.C++.DefineInitProcExtMacro"}} + #define INIT_PROC_EXT(ext, obj, proc) do { \ + if (data.hal_extensions[ProcHook::ext]) \ + INIT_PROC(obj, proc); \ + } while(0) +{{end}} + + +{{/* +------------------------------------------------------------------------------- + Emits definitions of stub functions for ProcHook. +------------------------------------------------------------------------------- +*/}} +{{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}}({{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, + reinterpret_cast<PFN_vkVoidFunction>({{$base}}), + 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}}), + reinterpret_cast<PFN_vkVoidFunction>(disabled{{$base}}), + nullptr, + {{end}} + {{else}} + ProcHook::EXTENSION_CORE, + reinterpret_cast<PFN_vkVoidFunction>({{$base}}), + 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}}), + reinterpret_cast<PFN_vkVoidFunction>(disabled{{$base}}), + reinterpret_cast<PFN_vkVoidFunction>(checked{{$base}}), + {{end}} + {{else}} + ProcHook::EXTENSION_CORE, + reinterpret_cast<PFN_vkVoidFunction>({{$base}}), + nullptr, + nullptr, + {{end}} + }, +{{end}} + + +{{/* +------------------------------------------------------------------------------- + Emits true if a function is needed by vulkan::driver. +------------------------------------------------------------------------------- +*/}} +{{define "driver.IsDriverTableEntry"}} + {{AssertType $ "Function"}} + + {{if (Macro "IsFunctionSupported" $)}} + {{/* Create functions of dispatchable objects */}} + {{ if eq $.Name "vkCreateDevice"}}true + {{else if eq $.Name "vkGetDeviceQueue"}}true + {{else if eq $.Name "vkAllocateCommandBuffers"}}true + + {{/* Destroy functions of dispatchable objects */}} + {{else if eq $.Name "vkDestroyInstance"}}true + {{else if eq $.Name "vkDestroyDevice"}}true + + {{else if eq $.Name "vkEnumerateDeviceLayerProperties"}}true + + {{/* Enumeration of extensions */}} + {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true + + {{/* We cache physical devices in loader.cpp */}} + {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true + + {{else if eq $.Name "vkGetInstanceProcAddr"}}true + {{else if eq $.Name "vkGetDeviceProcAddr"}}true + + {{/* VK_KHR_swapchain->VK_ANDROID_native_buffer translation */}} + {{else if eq $.Name "vkCreateImage"}}true + {{else if eq $.Name "vkDestroyImage"}}true + + {{end}} + + {{$ext := GetAnnotation $ "extension"}} + {{if $ext}} + {{$ext_name := index $ext.Arguments 0}} + {{ if eq $ext_name "VK_ANDROID_native_buffer"}}true + {{else if eq $ext_name "VK_EXT_debug_report"}}true + {{end}} + {{end}} + {{end}} +{{end}} + + +{{/* +------------------------------------------------------------------------------ + Emits true if an instance-dispatched function is needed by vulkan::driver. +------------------------------------------------------------------------------ +*/}} +{{define "driver.IsInstanceDriverTableEntry"}} + {{AssertType $ "Function"}} + + {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsInstanceDispatched" $)}} + true + {{end}} +{{end}} + + +{{/* +------------------------------------------------------------------------------ + Emits true if a device-dispatched function is needed by vulkan::driver. +------------------------------------------------------------------------------ +*/}} +{{define "driver.IsDeviceDriverTableEntry"}} + {{AssertType $ "Function"}} + + {{if and (Macro "driver.IsDriverTableEntry" $) (Macro "IsDeviceDispatched" $)}} + true + {{end}} +{{end}} + + +{{/* ------------------------------------------------------------------------------- Emits a function/extension name without the "vk"/"VK_" prefix. ------------------------------------------------------------------------------- @@ -517,3 +1033,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/debug_report.cpp b/vulkan/libvulkan/debug_report.cpp index 41b604063b..c4a1174191 100644 --- a/vulkan/libvulkan/debug_report.cpp +++ b/vulkan/libvulkan/debug_report.cpp @@ -14,9 +14,10 @@ * limitations under the License. */ -#include "loader.h" +#include "driver.h" namespace vulkan { +namespace driver { VkResult DebugReportCallbackList::CreateCallback( VkInstance instance, @@ -25,24 +26,22 @@ VkResult DebugReportCallbackList::CreateCallback( VkDebugReportCallbackEXT* callback) { VkDebugReportCallbackEXT driver_callback = VK_NULL_HANDLE; - if (GetDriverDispatch(instance).CreateDebugReportCallbackEXT) { - VkResult result = - GetDriverDispatch(instance).CreateDebugReportCallbackEXT( - GetDriverInstance(instance), create_info, allocator, - &driver_callback); + if (GetData(instance).driver.CreateDebugReportCallbackEXT) { + VkResult result = GetData(instance).driver.CreateDebugReportCallbackEXT( + instance, create_info, allocator, &driver_callback); if (result != VK_SUCCESS) return result; } const VkAllocationCallbacks* alloc = - allocator ? allocator : GetAllocator(instance); + allocator ? allocator : &GetData(instance).allocator; void* mem = alloc->pfnAllocation(alloc->pUserData, sizeof(Node), alignof(Node), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (!mem) { - if (GetDriverDispatch(instance).DestroyDebugReportCallbackEXT) { - GetDriverDispatch(instance).DestroyDebugReportCallbackEXT( - GetDriverInstance(instance), driver_callback, allocator); + if (GetData(instance).driver.DestroyDebugReportCallbackEXT) { + GetData(instance).driver.DestroyDebugReportCallbackEXT( + instance, driver_callback, allocator); } return VK_ERROR_OUT_OF_HOST_MEMORY; } @@ -68,13 +67,13 @@ void DebugReportCallbackList::DestroyCallback( prev->next = node->next; lock.unlock(); - if (GetDriverDispatch(instance).DestroyDebugReportCallbackEXT) { - GetDriverDispatch(instance).DestroyDebugReportCallbackEXT( - GetDriverInstance(instance), node->driver_callback, allocator); + if (GetData(instance).driver.DestroyDebugReportCallbackEXT) { + GetData(instance).driver.DestroyDebugReportCallbackEXT( + instance, node->driver_callback, allocator); } const VkAllocationCallbacks* alloc = - allocator ? allocator : GetAllocator(instance); + allocator ? allocator : &GetData(instance).allocator; alloc->pfnFree(alloc->pUserData, node); } @@ -95,40 +94,40 @@ void DebugReportCallbackList::Message(VkDebugReportFlagsEXT flags, } } -VkResult CreateDebugReportCallbackEXT_Bottom( +VkResult CreateDebugReportCallbackEXT( VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* create_info, const VkAllocationCallbacks* allocator, VkDebugReportCallbackEXT* callback) { - return GetDebugReportCallbacks(instance).CreateCallback( + return GetData(instance).debug_report_callbacks.CreateCallback( instance, create_info, allocator, callback); } -void DestroyDebugReportCallbackEXT_Bottom( - VkInstance instance, - VkDebugReportCallbackEXT callback, - const VkAllocationCallbacks* allocator) { +void DestroyDebugReportCallbackEXT(VkInstance instance, + VkDebugReportCallbackEXT callback, + const VkAllocationCallbacks* allocator) { if (callback) - GetDebugReportCallbacks(instance).DestroyCallback(instance, callback, - allocator); + GetData(instance).debug_report_callbacks.DestroyCallback( + instance, callback, allocator); } -void DebugReportMessageEXT_Bottom(VkInstance instance, - VkDebugReportFlagsEXT flags, - VkDebugReportObjectTypeEXT object_type, - uint64_t object, - size_t location, - int32_t message_code, - const char* layer_prefix, - const char* message) { - if (GetDriverDispatch(instance).DebugReportMessageEXT) { - GetDriverDispatch(instance).DebugReportMessageEXT( - GetDriverInstance(instance), flags, object_type, object, location, - message_code, layer_prefix, message); +void DebugReportMessageEXT(VkInstance instance, + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT object_type, + uint64_t object, + size_t location, + int32_t message_code, + const char* layer_prefix, + const char* message) { + if (GetData(instance).driver.DebugReportMessageEXT) { + GetData(instance).driver.DebugReportMessageEXT( + instance, flags, object_type, object, location, message_code, + layer_prefix, message); } - GetDebugReportCallbacks(instance).Message(flags, object_type, object, - location, message_code, - layer_prefix, message); + GetData(instance).debug_report_callbacks.Message(flags, object_type, object, + location, message_code, + layer_prefix, message); } +} // namespace driver } // namespace vulkan diff --git a/vulkan/libvulkan/debug_report.h b/vulkan/libvulkan/debug_report.h index c6f7570152..72b1887b1c 100644 --- a/vulkan/libvulkan/debug_report.h +++ b/vulkan/libvulkan/debug_report.h @@ -17,14 +17,16 @@ #ifndef LIBVULKAN_DEBUG_REPORT_H #define LIBVULKAN_DEBUG_REPORT_H 1 +#include <vulkan/vulkan.h> #include <shared_mutex> namespace vulkan { +namespace driver { // clang-format off -VKAPI_ATTR VkResult CreateDebugReportCallbackEXT_Bottom(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback); -VKAPI_ATTR void DestroyDebugReportCallbackEXT_Bottom(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator); -VKAPI_ATTR void DebugReportMessageEXT_Bottom(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage); +VKAPI_ATTR VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback); +VKAPI_ATTR void DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator); +VKAPI_ATTR void DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage); // clang-format on class DebugReportCallbackList { @@ -65,6 +67,7 @@ class DebugReportCallbackList { Node head_; }; +} // namespace driver } // namespace vulkan #endif // LIBVULKAN_DEBUG_REPORT_H diff --git a/vulkan/libvulkan/dispatch.tmpl b/vulkan/libvulkan/dispatch.tmpl deleted file mode 100644 index 67ead4a055..0000000000 --- a/vulkan/libvulkan/dispatch.tmpl +++ /dev/null @@ -1,365 +0,0 @@ -{{/* - * Copyright 2015 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. - */}} - -{{Include "../api/templates/vulkan_common.tmpl"}} -{{Global "clang-format" (Strings "clang-format" "-style=file")}} -{{Macro "DefineGlobals" $}} -{{$ | Macro "dispatch_gen.h" | Format (Global "clang-format") | Write "dispatch_gen.h" }} -{{$ | Macro "dispatch_gen.cpp" | Format (Global "clang-format") | Write "dispatch_gen.cpp"}} - -{{/* -------------------------------------------------------------------------------- - dispatch_gen.h -------------------------------------------------------------------------------- -*/}} -{{define "dispatch_gen.h"}} -/* -•* Copyright 2015 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 <vulkan/vk_android_native_buffer.h> -#include <vulkan/vulkan.h> -¶ -namespace vulkan { -¶ -struct DriverDispatchTable {« - // clang-format off - {{range $f := AllCommands $}} - {{if (Macro "IsInstanceDispatched" $f)}} - {{if not (Macro "IsLoaderFunction" $f)}} - {{Macro "FunctionPtrName" $f}} {{Macro "BaseName" $f}}; - {{end}} - {{end}} - {{end}} - - PFN_vkGetDeviceProcAddr GetDeviceProcAddr; - - PFN_vkDestroyDevice DestroyDevice; - PFN_vkGetDeviceQueue GetDeviceQueue; - PFN_vkAllocateCommandBuffers AllocateCommandBuffers; - - {{/* TODO(jessehall): Needed by swapchain code. Figure out a better way of - handling this that avoids the special case. Probably should rework - things so the driver dispatch table has all driver functions. Probably - need separate instance- and device-level copies, fill in all device- - dispatched functions in the device-level copies only, and change - GetDeviceProcAddr_Bottom to look in the already-loaded driver - dispatch table rather than forwarding to the driver's - vkGetDeviceProcAddr. */}} - PFN_vkCreateImage CreateImage; - PFN_vkDestroyImage DestroyImage; - - PFN_vkGetSwapchainGrallocUsageANDROID GetSwapchainGrallocUsageANDROID; - PFN_vkAcquireImageANDROID AcquireImageANDROID; - PFN_vkQueueSignalReleaseImageANDROID QueueSignalReleaseImageANDROID; - // clang-format on -»}; -¶ -} // namespace vulkan -¶{{end}} - - -{{/* -------------------------------------------------------------------------------- - dispatch_gen.cpp -------------------------------------------------------------------------------- -*/}} -{{define "dispatch_gen.cpp"}} -/* -•* Copyright 2015 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 <log/log.h> -#include <algorithm> -#include "loader.h" -¶ -#define UNLIKELY(expr) __builtin_expect((expr), 0) -¶ -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, - DriverDispatchTable& dispatch) {« - bool success = true; - // clang-format off - {{range $f := AllCommands $}} - {{if (Macro "IsInstanceDispatched" $f)}} - {{if not (Macro "IsLoaderFunction" $f)}} - {{$ext := GetAnnotation $f "extension"}} - {{if $ext}} - if (extensions[{{Macro "ExtensionConstant" $ext}}]) { - {{end}} - dispatch.{{Macro "BaseName" $f}} = § - reinterpret_cast<{{Macro "FunctionPtrName" $f}}>(§ - get_proc_addr(instance, "{{$f.Name}}")); - if (UNLIKELY(!dispatch.{{Macro "BaseName" $f}})) { - ALOGE("missing driver proc: %s", "{{$f.Name}}"); - success = false; - } - {{if $ext}} - } - {{end}} - {{end}} - {{end}} - {{end}} - dispatch.GetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(get_proc_addr(instance, "vkGetDeviceProcAddr")); - if (UNLIKELY(!dispatch.GetDeviceProcAddr)) { - ALOGE("missing driver proc: %s", "vkGetDeviceProcAddr"); - success = false; - } - dispatch.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(get_proc_addr(instance, "vkDestroyDevice")); - if (UNLIKELY(!dispatch.DestroyDevice)) { - ALOGE("missing driver proc: %s", "vkDestroyDevice"); - success = false; - } - dispatch.GetDeviceQueue = reinterpret_cast<PFN_vkGetDeviceQueue>(get_proc_addr(instance, "vkGetDeviceQueue")); - if (UNLIKELY(!dispatch.GetDeviceQueue)) { - ALOGE("missing driver proc: %s", "vkGetDeviceQueue"); - success = false; - } - dispatch.AllocateCommandBuffers = reinterpret_cast<PFN_vkAllocateCommandBuffers>(get_proc_addr(instance, "vkAllocateCommandBuffers")); - if (UNLIKELY(!dispatch.AllocateCommandBuffers)) { - ALOGE("missing driver proc: %s", "vkAllocateCommandBuffers"); - success = false; - } - dispatch.CreateImage = reinterpret_cast<PFN_vkCreateImage>(get_proc_addr(instance, "vkCreateImage")); - if (UNLIKELY(!dispatch.CreateImage)) { - ALOGE("missing driver proc: %s", "vkCreateImage"); - success = false; - } - dispatch.DestroyImage = reinterpret_cast<PFN_vkDestroyImage>(get_proc_addr(instance, "vkDestroyImage")); - if (UNLIKELY(!dispatch.DestroyImage)) { - ALOGE("missing driver proc: %s", "vkDestroyImage"); - success = false; - } - dispatch.GetSwapchainGrallocUsageANDROID = reinterpret_cast<PFN_vkGetSwapchainGrallocUsageANDROID>(get_proc_addr(instance, "vkGetSwapchainGrallocUsageANDROID")); - if (UNLIKELY(!dispatch.GetSwapchainGrallocUsageANDROID)) { - ALOGE("missing driver proc: %s", "vkGetSwapchainGrallocUsageANDROID"); - success = false; - } - dispatch.AcquireImageANDROID = reinterpret_cast<PFN_vkAcquireImageANDROID>(get_proc_addr(instance, "vkAcquireImageANDROID")); - if (UNLIKELY(!dispatch.AcquireImageANDROID)) { - ALOGE("missing driver proc: %s", "vkAcquireImageANDROID"); - success = false; - } - dispatch.QueueSignalReleaseImageANDROID = reinterpret_cast<PFN_vkQueueSignalReleaseImageANDROID>(get_proc_addr(instance, "vkQueueSignalReleaseImageANDROID")); - if (UNLIKELY(!dispatch.QueueSignalReleaseImageANDROID)) { - ALOGE("missing driver proc: %s", "vkQueueSignalReleaseImageANDROID"); - success = false; - } - // clang-format on - return success; -»} -¶ -} // namespace vulkan -¶{{end}} - - -{{/* -------------------------------------------------------------------------------- - Map an extension name to InstanceExtension or DeviceExtension enum value -------------------------------------------------------------------------------- -*/}} -{{define "ExtensionConstant"}} - {{$name := index $.Arguments 0}} - {{ if (eq $name "VK_KHR_surface")}}kKHR_surface - {{else if (eq $name "VK_KHR_android_surface")}}kKHR_android_surface - {{else if (eq $name "VK_EXT_debug_report")}}kEXT_debug_report - {{end}} -{{end}} - - -{{/* -------------------------------------------------------------------------------- - Emits a function name without the "vk" prefix. -------------------------------------------------------------------------------- -*/}} -{{define "BaseName"}} - {{AssertType $ "Function"}} - {{TrimPrefix "vk" $.Name}} -{{end}} - - -{{/* ------------------------------------------------------------------------------- - Emit "true" for supported functions that undergo table dispatch. Only global - functions and functions handled in the loader top without calling into - lower layers are not dispatched. ------------------------------------------------------------------------------- -*/}} -{{define "IsInstanceDispatched"}} - {{AssertType $ "Function"}} - {{if and (Macro "IsFunctionSupported" $) (eq (Macro "Vtbl" $) "Instance")}} - {{if and (ne $.Name "vkEnumerateDeviceLayerProperties") (ne $.Name "vkGetInstanceProcAddr")}}true{{end}} - {{end}} -{{end}} - - -{{/* ------------------------------------------------------------------------------- - Emit "true" if a function is core or from a supportable extension. ------------------------------------------------------------------------------- -*/}} -{{define "IsFunctionSupported"}} - {{AssertType $ "Function"}} - {{if not (GetAnnotation $ "pfn")}} - {{$ext := GetAnnotation $ "extension"}} - {{if not $ext}}true - {{else if not (Macro "IsExtensionBlacklisted" $ext)}}true - {{end}} - {{end}} -{{end}} - - -{{/* ------------------------------------------------------------------------------- - Reports whether an extension function is implemented entirely by the loader, - and not implemented by drivers. ------------------------------------------------------------------------------- -*/}} -{{define "IsLoaderFunction"}} - {{AssertType $ "Function"}} - - {{$ext := GetAnnotation $ "extension"}} - {{if $ext}} - {{Macro "IsLoaderExtension" $ext}} - {{end}} -{{end}} - - -{{/* -------------------------------------------------------------------------------- - Emit "true" if the loader has a bottom-level implementation for the function - which terminates the dispatch chain. -------------------------------------------------------------------------------- -*/}} -{{define "HasLoaderBottomImpl"}} - {{AssertType $ "Function"}} - - {{if (Macro "IsFunctionSupported" $)}} - {{ if (eq (Macro "Vtbl" $) "Instance")}}true - {{else if (Macro "IsLoaderFunction" $)}}true - {{else if (eq $.Name "vkCreateInstance")}}true - {{else if (eq $.Name "vkGetDeviceProcAddr")}}true - {{else if (eq $.Name "vkDestroyDevice")}}true - {{else if (eq $.Name "vkGetDeviceQueue")}}true - {{else if (eq $.Name "vkAllocateCommandBuffers")}}true - {{end}} - {{end}} -{{end}} - - -{{/* ------------------------------------------------------------------------------- - Emit "true" if an extension is unsupportable on Android. ------------------------------------------------------------------------------- -*/}} -{{define "IsExtensionBlacklisted"}} - {{$ext := index $.Arguments 0}} - {{ if eq $ext "VK_KHR_display"}}true - {{else if eq $ext "VK_KHR_display_swapchain"}}true - {{else if eq $ext "VK_KHR_xlib_surface"}}true - {{else if eq $ext "VK_KHR_xcb_surface"}}true - {{else if eq $ext "VK_KHR_wayland_surface"}}true - {{else if eq $ext "VK_KHR_mir_surface"}}true - {{else if eq $ext "VK_KHR_win32_surface"}}true - {{end}} -{{end}} - - -{{/* ------------------------------------------------------------------------------- - Reports whether an extension is implemented entirely by the loader, - so drivers should not enumerate it. ------------------------------------------------------------------------------- -*/}} -{{define "IsLoaderExtension"}} - {{$ext := index $.Arguments 0}} - {{ if eq $ext "VK_KHR_surface"}}true - {{else if eq $ext "VK_KHR_swapchain"}}true - {{else if eq $ext "VK_KHR_android_surface"}}true - {{end}} -{{end}} diff --git a/vulkan/libvulkan/dispatch_gen.cpp b/vulkan/libvulkan/dispatch_gen.cpp deleted file mode 100644 index eacf1a1094..0000000000 --- a/vulkan/libvulkan/dispatch_gen.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2015 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 <log/log.h> -#include <algorithm> -#include "loader.h" - -#define UNLIKELY(expr) __builtin_expect((expr), 0) - -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, - DriverDispatchTable& dispatch) { - bool success = true; - // clang-format off - dispatch.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>(get_proc_addr(instance, "vkDestroyInstance")); - if (UNLIKELY(!dispatch.DestroyInstance)) { - ALOGE("missing driver proc: %s", "vkDestroyInstance"); - success = false; - } - dispatch.EnumeratePhysicalDevices = reinterpret_cast<PFN_vkEnumeratePhysicalDevices>(get_proc_addr(instance, "vkEnumeratePhysicalDevices")); - if (UNLIKELY(!dispatch.EnumeratePhysicalDevices)) { - ALOGE("missing driver proc: %s", "vkEnumeratePhysicalDevices"); - success = false; - } - dispatch.GetPhysicalDeviceProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(get_proc_addr(instance, "vkGetPhysicalDeviceProperties")); - if (UNLIKELY(!dispatch.GetPhysicalDeviceProperties)) { - ALOGE("missing driver proc: %s", "vkGetPhysicalDeviceProperties"); - success = false; - } - dispatch.GetPhysicalDeviceQueueFamilyProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceQueueFamilyProperties>(get_proc_addr(instance, "vkGetPhysicalDeviceQueueFamilyProperties")); - if (UNLIKELY(!dispatch.GetPhysicalDeviceQueueFamilyProperties)) { - ALOGE("missing driver proc: %s", "vkGetPhysicalDeviceQueueFamilyProperties"); - success = false; - } - dispatch.GetPhysicalDeviceMemoryProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceMemoryProperties>(get_proc_addr(instance, "vkGetPhysicalDeviceMemoryProperties")); - if (UNLIKELY(!dispatch.GetPhysicalDeviceMemoryProperties)) { - ALOGE("missing driver proc: %s", "vkGetPhysicalDeviceMemoryProperties"); - success = false; - } - dispatch.GetPhysicalDeviceFeatures = reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures>(get_proc_addr(instance, "vkGetPhysicalDeviceFeatures")); - if (UNLIKELY(!dispatch.GetPhysicalDeviceFeatures)) { - ALOGE("missing driver proc: %s", "vkGetPhysicalDeviceFeatures"); - success = false; - } - dispatch.GetPhysicalDeviceFormatProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties>(get_proc_addr(instance, "vkGetPhysicalDeviceFormatProperties")); - if (UNLIKELY(!dispatch.GetPhysicalDeviceFormatProperties)) { - ALOGE("missing driver proc: %s", "vkGetPhysicalDeviceFormatProperties"); - success = false; - } - dispatch.GetPhysicalDeviceImageFormatProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceImageFormatProperties>(get_proc_addr(instance, "vkGetPhysicalDeviceImageFormatProperties")); - if (UNLIKELY(!dispatch.GetPhysicalDeviceImageFormatProperties)) { - ALOGE("missing driver proc: %s", "vkGetPhysicalDeviceImageFormatProperties"); - success = false; - } - dispatch.CreateDevice = reinterpret_cast<PFN_vkCreateDevice>(get_proc_addr(instance, "vkCreateDevice")); - if (UNLIKELY(!dispatch.CreateDevice)) { - ALOGE("missing driver proc: %s", "vkCreateDevice"); - success = false; - } - dispatch.EnumerateDeviceExtensionProperties = reinterpret_cast<PFN_vkEnumerateDeviceExtensionProperties>(get_proc_addr(instance, "vkEnumerateDeviceExtensionProperties")); - if (UNLIKELY(!dispatch.EnumerateDeviceExtensionProperties)) { - ALOGE("missing driver proc: %s", "vkEnumerateDeviceExtensionProperties"); - success = false; - } - dispatch.GetPhysicalDeviceSparseImageFormatProperties = reinterpret_cast<PFN_vkGetPhysicalDeviceSparseImageFormatProperties>(get_proc_addr(instance, "vkGetPhysicalDeviceSparseImageFormatProperties")); - if (UNLIKELY(!dispatch.GetPhysicalDeviceSparseImageFormatProperties)) { - ALOGE("missing driver proc: %s", "vkGetPhysicalDeviceSparseImageFormatProperties"); - success = false; - } - if (extensions[kEXT_debug_report]) { - dispatch.CreateDebugReportCallbackEXT = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(get_proc_addr(instance, "vkCreateDebugReportCallbackEXT")); - if (UNLIKELY(!dispatch.CreateDebugReportCallbackEXT)) { - ALOGE("missing driver proc: %s", "vkCreateDebugReportCallbackEXT"); - success = false; - } - } - if (extensions[kEXT_debug_report]) { - dispatch.DestroyDebugReportCallbackEXT = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(get_proc_addr(instance, "vkDestroyDebugReportCallbackEXT")); - if (UNLIKELY(!dispatch.DestroyDebugReportCallbackEXT)) { - ALOGE("missing driver proc: %s", "vkDestroyDebugReportCallbackEXT"); - success = false; - } - } - if (extensions[kEXT_debug_report]) { - dispatch.DebugReportMessageEXT = reinterpret_cast<PFN_vkDebugReportMessageEXT>(get_proc_addr(instance, "vkDebugReportMessageEXT")); - if (UNLIKELY(!dispatch.DebugReportMessageEXT)) { - ALOGE("missing driver proc: %s", "vkDebugReportMessageEXT"); - success = false; - } - } - dispatch.GetDeviceProcAddr = reinterpret_cast<PFN_vkGetDeviceProcAddr>(get_proc_addr(instance, "vkGetDeviceProcAddr")); - if (UNLIKELY(!dispatch.GetDeviceProcAddr)) { - ALOGE("missing driver proc: %s", "vkGetDeviceProcAddr"); - success = false; - } - dispatch.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>(get_proc_addr(instance, "vkDestroyDevice")); - if (UNLIKELY(!dispatch.DestroyDevice)) { - ALOGE("missing driver proc: %s", "vkDestroyDevice"); - success = false; - } - dispatch.GetDeviceQueue = reinterpret_cast<PFN_vkGetDeviceQueue>(get_proc_addr(instance, "vkGetDeviceQueue")); - if (UNLIKELY(!dispatch.GetDeviceQueue)) { - ALOGE("missing driver proc: %s", "vkGetDeviceQueue"); - success = false; - } - dispatch.AllocateCommandBuffers = reinterpret_cast<PFN_vkAllocateCommandBuffers>(get_proc_addr(instance, "vkAllocateCommandBuffers")); - if (UNLIKELY(!dispatch.AllocateCommandBuffers)) { - ALOGE("missing driver proc: %s", "vkAllocateCommandBuffers"); - success = false; - } - dispatch.CreateImage = reinterpret_cast<PFN_vkCreateImage>(get_proc_addr(instance, "vkCreateImage")); - if (UNLIKELY(!dispatch.CreateImage)) { - ALOGE("missing driver proc: %s", "vkCreateImage"); - success = false; - } - dispatch.DestroyImage = reinterpret_cast<PFN_vkDestroyImage>(get_proc_addr(instance, "vkDestroyImage")); - if (UNLIKELY(!dispatch.DestroyImage)) { - ALOGE("missing driver proc: %s", "vkDestroyImage"); - success = false; - } - dispatch.GetSwapchainGrallocUsageANDROID = reinterpret_cast<PFN_vkGetSwapchainGrallocUsageANDROID>(get_proc_addr(instance, "vkGetSwapchainGrallocUsageANDROID")); - if (UNLIKELY(!dispatch.GetSwapchainGrallocUsageANDROID)) { - ALOGE("missing driver proc: %s", "vkGetSwapchainGrallocUsageANDROID"); - success = false; - } - dispatch.AcquireImageANDROID = reinterpret_cast<PFN_vkAcquireImageANDROID>(get_proc_addr(instance, "vkAcquireImageANDROID")); - if (UNLIKELY(!dispatch.AcquireImageANDROID)) { - ALOGE("missing driver proc: %s", "vkAcquireImageANDROID"); - success = false; - } - dispatch.QueueSignalReleaseImageANDROID = reinterpret_cast<PFN_vkQueueSignalReleaseImageANDROID>(get_proc_addr(instance, "vkQueueSignalReleaseImageANDROID")); - if (UNLIKELY(!dispatch.QueueSignalReleaseImageANDROID)) { - ALOGE("missing driver proc: %s", "vkQueueSignalReleaseImageANDROID"); - success = false; - } - // clang-format on - return success; -} - -} // namespace vulkan diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp new file mode 100644 index 0000000000..007c54dd9d --- /dev/null +++ b/vulkan/libvulkan/driver.cpp @@ -0,0 +1,769 @@ +/* + * 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. + */ + +#include <stdlib.h> +#include <string.h> +#include <algorithm> +#include <array> +#include <new> +#include <malloc.h> +#include <sys/prctl.h> + +#include "driver.h" + +// #define ENABLE_ALLOC_CALLSTACKS 1 +#if ENABLE_ALLOC_CALLSTACKS +#include <utils/CallStack.h> +#define ALOGD_CALLSTACK(...) \ + do { \ + ALOGD(__VA_ARGS__); \ + android::CallStack callstack; \ + callstack.update(); \ + callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, " "); \ + } while (false) +#else +#define ALOGD_CALLSTACK(...) \ + do { \ + } while (false) +#endif + +namespace vulkan { +namespace driver { + +namespace { + +class CreateInfoWrapper { + public: + CreateInfoWrapper(hwvulkan_device_t* hw_dev, + const VkInstanceCreateInfo& create_info, + const VkAllocationCallbacks& allocator); + CreateInfoWrapper(VkPhysicalDevice physical_dev, + const VkDeviceCreateInfo& create_info, + const VkAllocationCallbacks& allocator); + ~CreateInfoWrapper(); + + VkResult validate(); + + const std::bitset<ProcHook::EXTENSION_COUNT>& get_hook_extensions() const; + const std::bitset<ProcHook::EXTENSION_COUNT>& get_hal_extensions() const; + + explicit operator const VkInstanceCreateInfo*() const; + explicit operator const VkDeviceCreateInfo*() const; + + private: + struct ExtensionFilter { + VkExtensionProperties* exts; + uint32_t ext_count; + + const char** names; + uint32_t name_count; + }; + + VkResult sanitize_pnext(); + + VkResult sanitize_layers(); + VkResult sanitize_extensions(); + + VkResult query_extension_count(uint32_t& count) const; + VkResult enumerate_extensions(uint32_t& count, + VkExtensionProperties* props) const; + VkResult init_extension_filter(); + void filter_extension(const char* name); + + const bool is_instance_; + const VkAllocationCallbacks& allocator_; + + union { + hwvulkan_device_t* hw_dev_; + VkPhysicalDevice physical_dev_; + }; + + union { + VkInstanceCreateInfo instance_info_; + VkDeviceCreateInfo dev_info_; + }; + + ExtensionFilter extension_filter_; + + std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_; + std::bitset<ProcHook::EXTENSION_COUNT> hal_extensions_; +}; + +CreateInfoWrapper::CreateInfoWrapper(hwvulkan_device_t* hw_dev, + const VkInstanceCreateInfo& create_info, + const VkAllocationCallbacks& allocator) + : is_instance_(true), + allocator_(allocator), + hw_dev_(hw_dev), + instance_info_(create_info), + extension_filter_() { + hook_extensions_.set(ProcHook::EXTENSION_CORE); + hal_extensions_.set(ProcHook::EXTENSION_CORE); +} + +CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev, + const VkDeviceCreateInfo& create_info, + const VkAllocationCallbacks& allocator) + : is_instance_(false), + allocator_(allocator), + physical_dev_(physical_dev), + dev_info_(create_info), + extension_filter_() { + hook_extensions_.set(ProcHook::EXTENSION_CORE); + hal_extensions_.set(ProcHook::EXTENSION_CORE); +} + +CreateInfoWrapper::~CreateInfoWrapper() { + allocator_.pfnFree(allocator_.pUserData, extension_filter_.exts); + allocator_.pfnFree(allocator_.pUserData, extension_filter_.names); +} + +VkResult CreateInfoWrapper::validate() { + VkResult result = sanitize_pnext(); + if (result == VK_SUCCESS) + result = sanitize_layers(); + if (result == VK_SUCCESS) + result = sanitize_extensions(); + + return result; +} + +const std::bitset<ProcHook::EXTENSION_COUNT>& +CreateInfoWrapper::get_hook_extensions() const { + return hook_extensions_; +} + +const std::bitset<ProcHook::EXTENSION_COUNT>& +CreateInfoWrapper::get_hal_extensions() const { + return hal_extensions_; +} + +CreateInfoWrapper::operator const VkInstanceCreateInfo*() const { + return &instance_info_; +} + +CreateInfoWrapper::operator const VkDeviceCreateInfo*() const { + return &dev_info_; +} + +VkResult CreateInfoWrapper::sanitize_pnext() { + const struct StructHeader { + VkStructureType type; + const void* next; + } * header; + + if (is_instance_) { + header = reinterpret_cast<const StructHeader*>(instance_info_.pNext); + + // skip leading VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFOs + while (header && + header->type == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO) + header = reinterpret_cast<const StructHeader*>(header->next); + + instance_info_.pNext = header; + } else { + header = reinterpret_cast<const StructHeader*>(dev_info_.pNext); + + // skip leading VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFOs + while (header && + header->type == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO) + header = reinterpret_cast<const StructHeader*>(header->next); + + dev_info_.pNext = header; + } + + return VK_SUCCESS; +} + +VkResult CreateInfoWrapper::sanitize_layers() { + auto& layer_names = (is_instance_) ? instance_info_.ppEnabledLayerNames + : dev_info_.ppEnabledLayerNames; + auto& layer_count = (is_instance_) ? instance_info_.enabledLayerCount + : dev_info_.enabledLayerCount; + + // remove all layers + layer_names = nullptr; + layer_count = 0; + + return VK_SUCCESS; +} + +VkResult CreateInfoWrapper::sanitize_extensions() { + auto& ext_names = (is_instance_) ? instance_info_.ppEnabledExtensionNames + : dev_info_.ppEnabledExtensionNames; + auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount + : dev_info_.enabledExtensionCount; + if (!ext_count) + return VK_SUCCESS; + + VkResult result = init_extension_filter(); + if (result != VK_SUCCESS) + return result; + + for (uint32_t i = 0; i < ext_count; i++) + filter_extension(ext_names[i]); + + ext_names = extension_filter_.names; + ext_count = extension_filter_.name_count; + + return VK_SUCCESS; +} + +VkResult CreateInfoWrapper::query_extension_count(uint32_t& count) const { + if (is_instance_) { + return hw_dev_->EnumerateInstanceExtensionProperties(nullptr, &count, + nullptr); + } else { + const auto& driver = GetData(physical_dev_).driver; + return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr, + &count, nullptr); + } +} + +VkResult CreateInfoWrapper::enumerate_extensions( + uint32_t& count, + VkExtensionProperties* props) const { + if (is_instance_) { + return hw_dev_->EnumerateInstanceExtensionProperties(nullptr, &count, + props); + } else { + const auto& driver = GetData(physical_dev_).driver; + return driver.EnumerateDeviceExtensionProperties(physical_dev_, nullptr, + &count, props); + } +} + +VkResult CreateInfoWrapper::init_extension_filter() { + // query extension count + uint32_t count; + VkResult result = query_extension_count(count); + if (result != VK_SUCCESS || count == 0) + return result; + + auto& filter = extension_filter_; + filter.exts = + reinterpret_cast<VkExtensionProperties*>(allocator_.pfnAllocation( + allocator_.pUserData, sizeof(VkExtensionProperties) * count, + alignof(VkExtensionProperties), + VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)); + if (!filter.exts) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + // enumerate extensions + result = enumerate_extensions(count, filter.exts); + if (result != VK_SUCCESS && result != VK_INCOMPLETE) + return result; + + if (!count) + return VK_SUCCESS; + + filter.ext_count = count; + + // allocate name array + uint32_t enabled_ext_count = (is_instance_) + ? instance_info_.enabledExtensionCount + : dev_info_.enabledExtensionCount; + count = std::min(filter.ext_count, enabled_ext_count); + filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation( + allocator_.pUserData, sizeof(const char*) * count, alignof(const char*), + VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)); + if (!filter.names) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + return VK_SUCCESS; +} + +void CreateInfoWrapper::filter_extension(const char* name) { + auto& filter = extension_filter_; + + ProcHook::Extension ext_bit = GetProcHookExtension(name); + if (is_instance_) { + switch (ext_bit) { + case ProcHook::KHR_android_surface: + case ProcHook::KHR_surface: + hook_extensions_.set(ext_bit); + // return now as these extensions do not require HAL support + return; + case ProcHook::EXT_debug_report: + // both we and HAL can take part in + hook_extensions_.set(ext_bit); + break; + case ProcHook::EXTENSION_UNKNOWN: + // HAL's extensions + break; + default: + ALOGW("Ignored invalid instance extension %s", name); + return; + } + } else { + switch (ext_bit) { + case ProcHook::KHR_swapchain: + // map VK_KHR_swapchain to VK_ANDROID_native_buffer + name = VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME; + ext_bit = ProcHook::ANDROID_native_buffer; + break; + case ProcHook::EXTENSION_UNKNOWN: + // HAL's extensions + break; + default: + ALOGW("Ignored invalid device extension %s", name); + return; + } + } + + for (uint32_t i = 0; i < filter.ext_count; i++) { + const VkExtensionProperties& props = filter.exts[i]; + // ignore unknown extensions + if (strcmp(name, props.extensionName) != 0) + continue; + + if (ext_bit == ProcHook::ANDROID_native_buffer) + hook_extensions_.set(ProcHook::KHR_swapchain); + + filter.names[filter.name_count++] = name; + hal_extensions_.set(ext_bit); + + break; + } +} + +hwvulkan_device_t* g_hwdevice = nullptr; + +VKAPI_ATTR void* DefaultAllocate(void*, + size_t size, + size_t alignment, + VkSystemAllocationScope) { + void* ptr = nullptr; + // Vulkan requires 'alignment' to be a power of two, but posix_memalign + // additionally requires that it be at least sizeof(void*). + int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size); + ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment, + ret, ptr); + return ret == 0 ? ptr : nullptr; +} + +VKAPI_ATTR void* DefaultReallocate(void*, + void* ptr, + size_t size, + size_t alignment, + VkSystemAllocationScope) { + if (size == 0) { + free(ptr); + return nullptr; + } + + // TODO(jessehall): Right now we never shrink allocations; if the new + // request is smaller than the existing chunk, we just continue using it. + // Right now the loader never reallocs, so this doesn't matter. If that + // changes, or if this code is copied into some other project, this should + // probably have a heuristic to allocate-copy-free when doing so will save + // "enough" space. + size_t old_size = ptr ? malloc_usable_size(ptr) : 0; + if (size <= old_size) + return ptr; + + void* new_ptr = nullptr; + if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0) + return nullptr; + if (ptr) { + memcpy(new_ptr, ptr, std::min(old_size, size)); + free(ptr); + } + return new_ptr; +} + +VKAPI_ATTR void DefaultFree(void*, void* ptr) { + ALOGD_CALLSTACK("Free: %p", ptr); + free(ptr); +} + +InstanceData* AllocateInstanceData(const VkAllocationCallbacks& allocator) { + void* data_mem = allocator.pfnAllocation( + allocator.pUserData, sizeof(InstanceData), alignof(InstanceData), + VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); + if (!data_mem) + return nullptr; + + return new (data_mem) InstanceData(allocator); +} + +void FreeInstanceData(InstanceData* data, + const VkAllocationCallbacks& allocator) { + data->~InstanceData(); + allocator.pfnFree(allocator.pUserData, data); +} + +DeviceData* AllocateDeviceData(const VkAllocationCallbacks& allocator) { + void* data_mem = allocator.pfnAllocation( + allocator.pUserData, sizeof(DeviceData), alignof(DeviceData), + VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); + if (!data_mem) + return nullptr; + + return new (data_mem) DeviceData(allocator); +} + +void FreeDeviceData(DeviceData* data, const VkAllocationCallbacks& allocator) { + data->~DeviceData(); + allocator.pfnFree(allocator.pUserData, data); +} + +} // anonymous namespace + +bool Debuggable() { + return (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) >= 0); +} + +bool OpenHAL() { + if (g_hwdevice) + return true; + + const hwvulkan_module_t* module; + int result = + hw_get_module("vulkan", reinterpret_cast<const hw_module_t**>(&module)); + if (result != 0) { + ALOGE("failed to load vulkan hal: %s (%d)", strerror(-result), result); + return false; + } + + hwvulkan_device_t* device; + result = + module->common.methods->open(&module->common, HWVULKAN_DEVICE_0, + reinterpret_cast<hw_device_t**>(&device)); + if (result != 0) { + ALOGE("failed to open vulkan driver: %s (%d)", strerror(-result), + result); + return false; + } + + g_hwdevice = device; + + return true; +} + +const VkAllocationCallbacks& GetDefaultAllocator() { + static const VkAllocationCallbacks kDefaultAllocCallbacks = { + .pUserData = nullptr, + .pfnAllocation = DefaultAllocate, + .pfnReallocation = DefaultReallocate, + .pfnFree = DefaultFree, + }; + + 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).driver.GetDeviceProcAddr(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; +} + +VkResult EnumerateInstanceExtensionProperties( + const char* pLayerName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties) { + static const std::array<VkExtensionProperties, 2> loader_extensions = {{ + // WSI extensions + {VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION}, + {VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, + VK_KHR_ANDROID_SURFACE_SPEC_VERSION}, + }}; + + // enumerate our extensions first + if (!pLayerName && pProperties) { + uint32_t count = std::min( + *pPropertyCount, static_cast<uint32_t>(loader_extensions.size())); + + std::copy_n(loader_extensions.begin(), count, pProperties); + + if (count < loader_extensions.size()) { + *pPropertyCount = count; + return VK_INCOMPLETE; + } + + pProperties += count; + *pPropertyCount -= count; + } + + VkResult result = g_hwdevice->EnumerateInstanceExtensionProperties( + pLayerName, pPropertyCount, pProperties); + + if (!pLayerName && (result == VK_SUCCESS || result == VK_INCOMPLETE)) + *pPropertyCount += loader_extensions.size(); + + return result; +} + +VkResult EnumerateDeviceExtensionProperties( + VkPhysicalDevice physicalDevice, + const char* pLayerName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties) { + const InstanceData& data = GetData(physicalDevice); + + VkResult result = data.driver.EnumerateDeviceExtensionProperties( + physicalDevice, pLayerName, pPropertyCount, pProperties); + if (result != VK_SUCCESS && result != VK_INCOMPLETE) + return result; + + if (!pProperties) + return result; + + // map VK_ANDROID_native_buffer to VK_KHR_swapchain + for (uint32_t i = 0; i < *pPropertyCount; i++) { + auto& prop = pProperties[i]; + + if (strcmp(prop.extensionName, + VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0) + continue; + + memcpy(prop.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME, + sizeof(VK_KHR_SWAPCHAIN_EXTENSION_NAME)); + prop.specVersion = VK_KHR_SWAPCHAIN_SPEC_VERSION; + } + + return result; +} + +VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkInstance* pInstance) { + const VkAllocationCallbacks& data_allocator = + (pAllocator) ? *pAllocator : GetDefaultAllocator(); + + CreateInfoWrapper wrapper(g_hwdevice, *pCreateInfo, data_allocator); + VkResult result = wrapper.validate(); + if (result != VK_SUCCESS) + return result; + + InstanceData* data = AllocateInstanceData(data_allocator); + if (!data) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + data->hook_extensions |= wrapper.get_hook_extensions(); + data->hal_extensions |= wrapper.get_hal_extensions(); + + // call into the driver + VkInstance instance; + result = g_hwdevice->CreateInstance( + static_cast<const VkInstanceCreateInfo*>(wrapper), pAllocator, + &instance); + if (result != VK_SUCCESS) { + FreeInstanceData(data, data_allocator); + return result; + } + + // initialize InstanceDriverTable + if (!SetData(instance, *data) || + !InitDriverTable(instance, g_hwdevice->GetInstanceProcAddr)) { + data->driver.DestroyInstance = reinterpret_cast<PFN_vkDestroyInstance>( + g_hwdevice->GetInstanceProcAddr(instance, "vkDestroyInstance")); + if (data->driver.DestroyInstance) + data->driver.DestroyInstance(instance, pAllocator); + + FreeInstanceData(data, data_allocator); + + return VK_ERROR_INCOMPATIBLE_DRIVER; + } + + data->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>( + g_hwdevice->GetInstanceProcAddr(instance, "vkGetDeviceProcAddr")); + if (!data->get_device_proc_addr) { + data->driver.DestroyInstance(instance, pAllocator); + FreeInstanceData(data, data_allocator); + + return VK_ERROR_INCOMPATIBLE_DRIVER; + } + + *pInstance = instance; + + return VK_SUCCESS; +} + +void DestroyInstance(VkInstance instance, + const VkAllocationCallbacks* pAllocator) { + InstanceData& data = GetData(instance); + data.driver.DestroyInstance(instance, pAllocator); + + VkAllocationCallbacks local_allocator; + if (!pAllocator) { + local_allocator = data.allocator; + pAllocator = &local_allocator; + } + + FreeInstanceData(&data, *pAllocator); +} + +VkResult CreateDevice(VkPhysicalDevice physicalDevice, + const VkDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice) { + const InstanceData& instance_data = GetData(physicalDevice); + const VkAllocationCallbacks& data_allocator = + (pAllocator) ? *pAllocator : instance_data.allocator; + + CreateInfoWrapper wrapper(physicalDevice, *pCreateInfo, data_allocator); + VkResult result = wrapper.validate(); + if (result != VK_SUCCESS) + return result; + + DeviceData* data = AllocateDeviceData(data_allocator); + if (!data) + return VK_ERROR_OUT_OF_HOST_MEMORY; + + data->hook_extensions |= wrapper.get_hook_extensions(); + data->hal_extensions |= wrapper.get_hal_extensions(); + + // call into the driver + VkDevice dev; + result = instance_data.driver.CreateDevice( + physicalDevice, static_cast<const VkDeviceCreateInfo*>(wrapper), + pAllocator, &dev); + if (result != VK_SUCCESS) { + FreeDeviceData(data, data_allocator); + return result; + } + + // initialize DeviceDriverTable + if (!SetData(dev, *data) || + !InitDriverTable(dev, instance_data.get_device_proc_addr)) { + data->driver.DestroyDevice = reinterpret_cast<PFN_vkDestroyDevice>( + instance_data.get_device_proc_addr(dev, "vkDestroyDevice")); + if (data->driver.DestroyDevice) + data->driver.DestroyDevice(dev, pAllocator); + + FreeDeviceData(data, data_allocator); + + return VK_ERROR_INCOMPATIBLE_DRIVER; + } + + *pDevice = dev; + + return VK_SUCCESS; +} + +void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) { + DeviceData& data = GetData(device); + data.driver.DestroyDevice(device, pAllocator); + + VkAllocationCallbacks local_allocator; + if (!pAllocator) { + local_allocator = data.allocator; + pAllocator = &local_allocator; + } + + FreeDeviceData(&data, *pAllocator); +} + +VkResult EnumeratePhysicalDevices(VkInstance instance, + uint32_t* pPhysicalDeviceCount, + VkPhysicalDevice* pPhysicalDevices) { + const auto& data = GetData(instance); + + VkResult result = data.driver.EnumeratePhysicalDevices( + instance, pPhysicalDeviceCount, pPhysicalDevices); + if ((result == VK_SUCCESS || result == VK_INCOMPLETE) && pPhysicalDevices) { + for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) + SetData(pPhysicalDevices[i], data); + } + + return result; +} + +void GetDeviceQueue(VkDevice device, + uint32_t queueFamilyIndex, + uint32_t queueIndex, + VkQueue* pQueue) { + const auto& data = GetData(device); + + data.driver.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue); + SetData(*pQueue, data); +} + +VKAPI_ATTR VkResult +AllocateCommandBuffers(VkDevice device, + const VkCommandBufferAllocateInfo* pAllocateInfo, + VkCommandBuffer* pCommandBuffers) { + const auto& data = GetData(device); + + VkResult result = data.driver.AllocateCommandBuffers(device, pAllocateInfo, + pCommandBuffers); + if (result == VK_SUCCESS) { + for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) + SetData(pCommandBuffers[i], data); + } + + return result; +} + +} // namespace driver +} // namespace vulkan diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h index de9d1c65a0..22db93f577 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,9 @@ #include <hardware/hwvulkan.h> #include "api_gen.h" +#include "driver_gen.h" +#include "debug_report.h" +#include "swapchain.h" namespace vulkan { @@ -61,15 +65,43 @@ struct DeviceData { namespace driver { struct InstanceData { + InstanceData(const VkAllocationCallbacks& alloc) + : opaque_api_data(), + allocator(alloc), + driver(), + get_device_proc_addr(nullptr) { + 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; + + InstanceDriverTable driver; + PFN_vkGetDeviceProcAddr get_device_proc_addr; + + DebugReportCallbackList debug_report_callbacks; }; struct DeviceData { + DeviceData(const VkAllocationCallbacks& alloc) + : opaque_api_data(), allocator(alloc), driver() { + 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; + + DeviceDriverTable driver; }; bool Debuggable(); @@ -80,6 +112,17 @@ const VkAllocationCallbacks& GetDefaultAllocator(); VKAPI_ATTR PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName); VKAPI_ATTR PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName); VKAPI_ATTR VkResult EnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties); + +VKAPI_ATTR VkResult EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties); + +VKAPI_ATTR VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance); +VKAPI_ATTR void DestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator); +VKAPI_ATTR VkResult CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice); +VKAPI_ATTR void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult EnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); +VKAPI_ATTR void GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue); +VKAPI_ATTR VkResult AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers); // clang-format on template <typename DispatchableType> diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp new file mode 100644 index 0000000000..8b816bac96 --- /dev/null +++ b/vulkan/libvulkan/driver_gen.cpp @@ -0,0 +1,431 @@ +/* + * 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" + +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(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(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(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(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(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), + reinterpret_cast<PFN_vkVoidFunction>(disabledAcquireNextImageKHR), + reinterpret_cast<PFN_vkVoidFunction>(checkedAcquireNextImageKHR), + }, + { + "vkAllocateCommandBuffers", + ProcHook::DEVICE, + ProcHook::EXTENSION_CORE, + reinterpret_cast<PFN_vkVoidFunction>(AllocateCommandBuffers), + nullptr, + nullptr, + }, + { + "vkCreateAndroidSurfaceKHR", + ProcHook::INSTANCE, + ProcHook::KHR_android_surface, + reinterpret_cast<PFN_vkVoidFunction>(CreateAndroidSurfaceKHR), + reinterpret_cast<PFN_vkVoidFunction>(disabledCreateAndroidSurfaceKHR), + nullptr, + }, + { + "vkCreateDebugReportCallbackEXT", + ProcHook::INSTANCE, + ProcHook::EXT_debug_report, + reinterpret_cast<PFN_vkVoidFunction>(CreateDebugReportCallbackEXT), + reinterpret_cast<PFN_vkVoidFunction>(disabledCreateDebugReportCallbackEXT), + nullptr, + }, + { + "vkCreateDevice", + ProcHook::INSTANCE, + ProcHook::EXTENSION_CORE, + reinterpret_cast<PFN_vkVoidFunction>(CreateDevice), + nullptr, + nullptr, + }, + { + "vkCreateInstance", + ProcHook::GLOBAL, + ProcHook::EXTENSION_CORE, + reinterpret_cast<PFN_vkVoidFunction>(CreateInstance), + nullptr, + nullptr, + }, + { + "vkCreateSwapchainKHR", + ProcHook::DEVICE, + ProcHook::KHR_swapchain, + reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR), + reinterpret_cast<PFN_vkVoidFunction>(disabledCreateSwapchainKHR), + reinterpret_cast<PFN_vkVoidFunction>(checkedCreateSwapchainKHR), + }, + { + "vkDebugReportMessageEXT", + ProcHook::INSTANCE, + ProcHook::EXT_debug_report, + reinterpret_cast<PFN_vkVoidFunction>(DebugReportMessageEXT), + reinterpret_cast<PFN_vkVoidFunction>(disabledDebugReportMessageEXT), + nullptr, + }, + { + "vkDestroyDebugReportCallbackEXT", + ProcHook::INSTANCE, + ProcHook::EXT_debug_report, + reinterpret_cast<PFN_vkVoidFunction>(DestroyDebugReportCallbackEXT), + reinterpret_cast<PFN_vkVoidFunction>(disabledDestroyDebugReportCallbackEXT), + nullptr, + }, + { + "vkDestroyDevice", + ProcHook::DEVICE, + ProcHook::EXTENSION_CORE, + reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice), + nullptr, + nullptr, + }, + { + "vkDestroyInstance", + ProcHook::INSTANCE, + ProcHook::EXTENSION_CORE, + reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance), + nullptr, + nullptr, + }, + { + "vkDestroySurfaceKHR", + ProcHook::INSTANCE, + ProcHook::KHR_surface, + reinterpret_cast<PFN_vkVoidFunction>(DestroySurfaceKHR), + reinterpret_cast<PFN_vkVoidFunction>(disabledDestroySurfaceKHR), + nullptr, + }, + { + "vkDestroySwapchainKHR", + ProcHook::DEVICE, + ProcHook::KHR_swapchain, + reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR), + reinterpret_cast<PFN_vkVoidFunction>(disabledDestroySwapchainKHR), + reinterpret_cast<PFN_vkVoidFunction>(checkedDestroySwapchainKHR), + }, + { + "vkEnumerateDeviceExtensionProperties", + ProcHook::INSTANCE, + ProcHook::EXTENSION_CORE, + reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties), + 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), + 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), + 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), + reinterpret_cast<PFN_vkVoidFunction>(disabledGetPhysicalDeviceSurfaceCapabilitiesKHR), + nullptr, + }, + { + "vkGetPhysicalDeviceSurfaceFormatsKHR", + ProcHook::INSTANCE, + ProcHook::KHR_surface, + reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormatsKHR), + reinterpret_cast<PFN_vkVoidFunction>(disabledGetPhysicalDeviceSurfaceFormatsKHR), + nullptr, + }, + { + "vkGetPhysicalDeviceSurfacePresentModesKHR", + ProcHook::INSTANCE, + ProcHook::KHR_surface, + reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR), + reinterpret_cast<PFN_vkVoidFunction>(disabledGetPhysicalDeviceSurfacePresentModesKHR), + nullptr, + }, + { + "vkGetPhysicalDeviceSurfaceSupportKHR", + ProcHook::INSTANCE, + ProcHook::KHR_surface, + reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceSupportKHR), + 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), + reinterpret_cast<PFN_vkVoidFunction>(disabledGetSwapchainImagesKHR), + reinterpret_cast<PFN_vkVoidFunction>(checkedGetSwapchainImagesKHR), + }, + { + "vkQueuePresentKHR", + ProcHook::DEVICE, + ProcHook::KHR_swapchain, + reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR), + 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; +} + +#define UNLIKELY(expr) __builtin_expect((expr), 0) + +#define INIT_PROC(obj, proc) \ + do { \ + data.driver.proc = \ + reinterpret_cast<PFN_vk##proc>(get_proc(obj, "vk" #proc)); \ + if (UNLIKELY(!data.driver.proc)) { \ + ALOGE("missing " #obj " proc: vk" #proc); \ + success = false; \ + } \ + } while (0) + +#define INIT_PROC_EXT(ext, obj, proc) \ + do { \ + if (data.hal_extensions[ProcHook::ext]) \ + INIT_PROC(obj, proc); \ + } while (0) + +bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc) { + auto& data = GetData(instance); + bool success = true; + + // clang-format off + INIT_PROC(instance, DestroyInstance); + INIT_PROC(instance, EnumeratePhysicalDevices); + INIT_PROC(instance, GetInstanceProcAddr); + INIT_PROC(instance, CreateDevice); + INIT_PROC(instance, EnumerateDeviceLayerProperties); + INIT_PROC(instance, EnumerateDeviceExtensionProperties); + INIT_PROC_EXT(EXT_debug_report, instance, CreateDebugReportCallbackEXT); + INIT_PROC_EXT(EXT_debug_report, instance, DestroyDebugReportCallbackEXT); + INIT_PROC_EXT(EXT_debug_report, instance, DebugReportMessageEXT); + // clang-format on + + return success; +} + +bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) { + auto& data = GetData(dev); + bool success = true; + + // clang-format off + INIT_PROC(dev, GetDeviceProcAddr); + INIT_PROC(dev, DestroyDevice); + INIT_PROC(dev, GetDeviceQueue); + INIT_PROC(dev, CreateImage); + INIT_PROC(dev, DestroyImage); + INIT_PROC(dev, AllocateCommandBuffers); + INIT_PROC_EXT(ANDROID_native_buffer, dev, GetSwapchainGrallocUsageANDROID); + INIT_PROC_EXT(ANDROID_native_buffer, dev, AcquireImageANDROID); + INIT_PROC_EXT(ANDROID_native_buffer, dev, QueueSignalReleaseImageANDROID); + // clang-format on + + return success; +} + +} // namespace driver +} // namespace vulkan + +// clang-format on diff --git a/vulkan/libvulkan/dispatch_gen.h b/vulkan/libvulkan/driver_gen.h index ca31caf553..1eb7d79096 100644 --- a/vulkan/libvulkan/dispatch_gen.h +++ b/vulkan/libvulkan/driver_gen.h @@ -1,5 +1,5 @@ /* - * Copyright 2015 The Android Open Source Project + * 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. @@ -16,37 +16,77 @@ // WARNING: This file is generated. See ../README.md for instructions. -#include <vulkan/vk_android_native_buffer.h> +#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, + }; -struct DriverDispatchTable { + 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 +}; + +struct InstanceDriverTable { // clang-format off PFN_vkDestroyInstance DestroyInstance; PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices; - PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties; - PFN_vkGetPhysicalDeviceQueueFamilyProperties GetPhysicalDeviceQueueFamilyProperties; - PFN_vkGetPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties; - PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures; - PFN_vkGetPhysicalDeviceFormatProperties GetPhysicalDeviceFormatProperties; - PFN_vkGetPhysicalDeviceImageFormatProperties GetPhysicalDeviceImageFormatProperties; + PFN_vkGetInstanceProcAddr GetInstanceProcAddr; PFN_vkCreateDevice CreateDevice; + PFN_vkEnumerateDeviceLayerProperties EnumerateDeviceLayerProperties; PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties; - PFN_vkGetPhysicalDeviceSparseImageFormatProperties GetPhysicalDeviceSparseImageFormatProperties; PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT; PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT; PFN_vkDebugReportMessageEXT DebugReportMessageEXT; + // clang-format on +}; + +struct DeviceDriverTable { + // clang-format off PFN_vkGetDeviceProcAddr GetDeviceProcAddr; PFN_vkDestroyDevice DestroyDevice; PFN_vkGetDeviceQueue GetDeviceQueue; - PFN_vkAllocateCommandBuffers AllocateCommandBuffers; PFN_vkCreateImage CreateImage; PFN_vkDestroyImage DestroyImage; + PFN_vkAllocateCommandBuffers AllocateCommandBuffers; PFN_vkGetSwapchainGrallocUsageANDROID GetSwapchainGrallocUsageANDROID; PFN_vkAcquireImageANDROID AcquireImageANDROID; PFN_vkQueueSignalReleaseImageANDROID QueueSignalReleaseImageANDROID; // clang-format on }; +const ProcHook* GetProcHook(const char* name); +ProcHook::Extension GetProcHookExtension(const char* name); + +bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc); +bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc); + +} // namespace driver } // namespace vulkan + +#endif // LIBVULKAN_DRIVER_TABLE_H diff --git a/vulkan/libvulkan/layers_extensions.cpp b/vulkan/libvulkan/layers_extensions.cpp index aec0fd04e7..6b53a9aae5 100644 --- a/vulkan/libvulkan/layers_extensions.cpp +++ b/vulkan/libvulkan/layers_extensions.cpp @@ -16,7 +16,7 @@ // #define LOG_NDEBUG 0 -#include "loader.h" +#include "layers_extensions.h" #include <alloca.h> #include <dirent.h> #include <dlfcn.h> @@ -28,8 +28,6 @@ #include <log/log.h> #include <vulkan/vulkan_loader_data.h> -using namespace vulkan; - // TODO(jessehall): The whole way we deal with extensions is pretty hokey, and // not a good long-term solution. Having a hard-coded enum of extensions is // bad, of course. Representing sets of extensions (requested, supported, etc.) @@ -50,12 +48,13 @@ using namespace vulkan; // with a mask saying what kind(s) it is. namespace vulkan { +namespace api { + struct Layer { VkLayerProperties properties; size_t library_idx; std::vector<VkExtensionProperties> extensions; }; -} // namespace vulkan namespace { @@ -341,8 +340,6 @@ LayerRef GetLayerRef(std::vector<Layer>& layers, const char* name) { } // anonymous namespace -namespace vulkan { - void DiscoverLayers() { if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) DiscoverLayersInDirectory("/data/local/debug/vulkan"); @@ -425,22 +422,5 @@ bool LayerRef::SupportsExtension(const char* name) const { }) != layer_->extensions.cend(); } -InstanceExtension InstanceExtensionFromName(const char* name) { - if (strcmp(name, VK_KHR_SURFACE_EXTENSION_NAME) == 0) - return kKHR_surface; - if (strcmp(name, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) - return kKHR_android_surface; - if (strcmp(name, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) - return kEXT_debug_report; - return kInstanceExtensionCount; -} - -DeviceExtension DeviceExtensionFromName(const char* name) { - if (strcmp(name, VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) - return kKHR_swapchain; - if (strcmp(name, VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) == 0) - return kANDROID_native_buffer; - return kDeviceExtensionCount; -} - +} // namespace api } // namespace vulkan diff --git a/vulkan/libvulkan/layers_extensions.h b/vulkan/libvulkan/layers_extensions.h new file mode 100644 index 0000000000..7e7bfd379f --- /dev/null +++ b/vulkan/libvulkan/layers_extensions.h @@ -0,0 +1,64 @@ +/* + * Copyright 2015 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. + */ + +#ifndef LIBVULKAN_LAYERS_EXTENSIONS_H +#define LIBVULKAN_LAYERS_EXTENSIONS_H 1 + +#include <vulkan/vulkan.h> + +namespace vulkan { +namespace api { + +struct Layer; +class LayerRef { + public: + LayerRef(Layer* layer); + LayerRef(LayerRef&& other); + ~LayerRef(); + LayerRef(const LayerRef&) = delete; + LayerRef& operator=(const LayerRef&) = delete; + + const char* GetName() const; + uint32_t GetSpecVersion(); + + // provides bool-like behavior + operator const Layer*() const { return layer_; } + + PFN_vkGetInstanceProcAddr GetGetInstanceProcAddr() const; + PFN_vkGetDeviceProcAddr GetGetDeviceProcAddr() const; + + bool SupportsExtension(const char* name) const; + + private: + Layer* layer_; +}; + +void DiscoverLayers(); +uint32_t EnumerateInstanceLayers(uint32_t count, VkLayerProperties* properties); +uint32_t EnumerateDeviceLayers(uint32_t count, VkLayerProperties* properties); +void GetInstanceLayerExtensions(const char* name, + const VkExtensionProperties** properties, + uint32_t* count); +void GetDeviceLayerExtensions(const char* name, + const VkExtensionProperties** properties, + uint32_t* count); +LayerRef GetInstanceLayerRef(const char* name); +LayerRef GetDeviceLayerRef(const char* name); + +} // namespace api +} // namespace vulkan + +#endif // LIBVULKAN_LAYERS_EXTENSIONS_H diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp deleted file mode 100644 index 65b09db145..0000000000 --- a/vulkan/libvulkan/loader.cpp +++ /dev/null @@ -1,1045 +0,0 @@ -/* - * Copyright 2015 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. - */ - -// module header -#include "loader.h" -#include "driver.h" -// standard C headers -#include <dirent.h> -#include <dlfcn.h> -#include <inttypes.h> -#include <pthread.h> -#include <stdlib.h> -#include <string.h> -#include <sys/prctl.h> -// standard C++ headers -#include <algorithm> -#include <mutex> -#include <sstream> -#include <string> -#include <unordered_map> -#include <vector> -// platform/library headers -#include <cutils/properties.h> -#include <hardware/hwvulkan.h> -#include <log/log.h> -#include <vulkan/vulkan_loader_data.h> -#include <vulkan/vk_layer_interface.h> - -// #define ENABLE_ALLOC_CALLSTACKS 1 -#if ENABLE_ALLOC_CALLSTACKS -#include <utils/CallStack.h> -#define ALOGD_CALLSTACK(...) \ - do { \ - ALOGD(__VA_ARGS__); \ - android::CallStack callstack; \ - callstack.update(); \ - callstack.log(LOG_TAG, ANDROID_LOG_DEBUG, " "); \ - } while (false) -#else -#define ALOGD_CALLSTACK(...) \ - do { \ - } while (false) -#endif - -using namespace vulkan; - -static const uint32_t kMaxPhysicalDevices = 4; - -namespace { - -// ---------------------------------------------------------------------------- - -// Standard-library allocator that delegates to VkAllocationCallbacks. -// -// TODO(jessehall): This class currently always uses -// VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE. The scope to use could be a template -// parameter or a constructor parameter. The former would help catch bugs -// where we use the wrong scope, e.g. adding a command-scope string to an -// instance-scope vector. But that might also be pretty annoying to deal with. -template <class T> -class CallbackAllocator { - public: - typedef T value_type; - - CallbackAllocator(const VkAllocationCallbacks* alloc_input) - : alloc(alloc_input) {} - - template <class T2> - CallbackAllocator(const CallbackAllocator<T2>& other) - : alloc(other.alloc) {} - - T* allocate(std::size_t n) { - void* mem = - alloc->pfnAllocation(alloc->pUserData, n * sizeof(T), alignof(T), - VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); - if (!mem) - throw std::bad_alloc(); - return static_cast<T*>(mem); - } - - void deallocate(T* array, std::size_t /*n*/) noexcept { - alloc->pfnFree(alloc->pUserData, array); - } - - const VkAllocationCallbacks* alloc; -}; -// These are needed in order to move Strings -template <class T> -bool operator==(const CallbackAllocator<T>& alloc1, - const CallbackAllocator<T>& alloc2) { - return alloc1.alloc == alloc2.alloc; -} -template <class T> -bool operator!=(const CallbackAllocator<T>& alloc1, - const CallbackAllocator<T>& alloc2) { - return !(alloc1 == alloc2); -} - -template <class T> -using Vector = std::vector<T, CallbackAllocator<T>>; - -typedef std::basic_string<char, std::char_traits<char>, CallbackAllocator<char>> - String; - -// ---------------------------------------------------------------------------- - -VKAPI_ATTR void* DefaultAllocate(void*, - size_t size, - size_t alignment, - VkSystemAllocationScope) { - void* ptr = nullptr; - // Vulkan requires 'alignment' to be a power of two, but posix_memalign - // additionally requires that it be at least sizeof(void*). - int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size); - ALOGD_CALLSTACK("Allocate: size=%zu align=%zu => (%d) %p", size, alignment, - ret, ptr); - return ret == 0 ? ptr : nullptr; -} - -VKAPI_ATTR void* DefaultReallocate(void*, - void* ptr, - size_t size, - size_t alignment, - VkSystemAllocationScope) { - if (size == 0) { - free(ptr); - return nullptr; - } - - // TODO(jessehall): Right now we never shrink allocations; if the new - // request is smaller than the existing chunk, we just continue using it. - // Right now the loader never reallocs, so this doesn't matter. If that - // changes, or if this code is copied into some other project, this should - // probably have a heuristic to allocate-copy-free when doing so will save - // "enough" space. - size_t old_size = ptr ? malloc_usable_size(ptr) : 0; - if (size <= old_size) - return ptr; - - void* new_ptr = nullptr; - if (posix_memalign(&new_ptr, std::max(alignment, sizeof(void*)), size) != 0) - return nullptr; - if (ptr) { - memcpy(new_ptr, ptr, std::min(old_size, size)); - free(ptr); - } - return new_ptr; -} - -VKAPI_ATTR void DefaultFree(void*, void* ptr) { - ALOGD_CALLSTACK("Free: %p", ptr); - free(ptr); -} - -const VkAllocationCallbacks kDefaultAllocCallbacks = { - .pUserData = nullptr, - .pfnAllocation = DefaultAllocate, - .pfnReallocation = DefaultReallocate, - .pfnFree = DefaultFree, -}; - -// ---------------------------------------------------------------------------- -// Global Data and Initialization - -hwvulkan_device_t* g_hwdevice = nullptr; -InstanceExtensionSet g_driver_instance_extensions; - -void LoadVulkanHAL() { - static const hwvulkan_module_t* module; - int result = - hw_get_module("vulkan", reinterpret_cast<const hw_module_t**>(&module)); - if (result != 0) { - ALOGE("failed to load vulkan hal: %s (%d)", strerror(-result), result); - return; - } - result = module->common.methods->open( - &module->common, HWVULKAN_DEVICE_0, - reinterpret_cast<hw_device_t**>(&g_hwdevice)); - if (result != 0) { - ALOGE("failed to open vulkan driver: %s (%d)", strerror(-result), - result); - module = nullptr; - return; - } - - VkResult vkresult; - uint32_t count; - if ((vkresult = g_hwdevice->EnumerateInstanceExtensionProperties( - nullptr, &count, nullptr)) != VK_SUCCESS) { - ALOGE("driver EnumerateInstanceExtensionProperties failed: %d", - vkresult); - g_hwdevice->common.close(&g_hwdevice->common); - g_hwdevice = nullptr; - module = nullptr; - return; - } - VkExtensionProperties* extensions = static_cast<VkExtensionProperties*>( - alloca(count * sizeof(VkExtensionProperties))); - if ((vkresult = g_hwdevice->EnumerateInstanceExtensionProperties( - nullptr, &count, extensions)) != VK_SUCCESS) { - ALOGE("driver EnumerateInstanceExtensionProperties failed: %d", - vkresult); - g_hwdevice->common.close(&g_hwdevice->common); - g_hwdevice = nullptr; - module = nullptr; - return; - } - ALOGV_IF(count > 0, "Driver-supported instance extensions:"); - for (uint32_t i = 0; i < count; i++) { - ALOGV(" %s (v%u)", extensions[i].extensionName, - extensions[i].specVersion); - InstanceExtension id = - InstanceExtensionFromName(extensions[i].extensionName); - if (id != kInstanceExtensionCount) - g_driver_instance_extensions.set(id); - } - // Ignore driver attempts to support loader extensions - g_driver_instance_extensions.reset(kKHR_surface); - g_driver_instance_extensions.reset(kKHR_android_surface); -} - -// ----------------------------------------------------------------------------- - -struct Instance { - Instance(const VkAllocationCallbacks* alloc_callbacks) - : base{{}, *alloc_callbacks}, - alloc(&base.allocator), - num_physical_devices(0) { - memset(physical_devices, 0, sizeof(physical_devices)); - enabled_extensions.reset(); - memset(&drv.dispatch, 0, sizeof(drv.dispatch)); - } - - ~Instance() {} - - driver::InstanceData base; - - const VkAllocationCallbacks* alloc; - uint32_t num_physical_devices; - VkPhysicalDevice physical_devices_top[kMaxPhysicalDevices]; - VkPhysicalDevice physical_devices[kMaxPhysicalDevices]; - DeviceExtensionSet physical_device_driver_extensions[kMaxPhysicalDevices]; - - DebugReportCallbackList debug_report_callbacks; - InstanceExtensionSet enabled_extensions; - - struct { - DriverDispatchTable dispatch; - } drv; // may eventually be an array -}; - -struct Device { - 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; -}; - -template <typename THandle> -struct HandleTraits {}; -template <> -struct HandleTraits<VkInstance> { - typedef Instance LoaderObjectType; -}; -template <> -struct HandleTraits<VkPhysicalDevice> { - typedef Instance LoaderObjectType; -}; -template <> -struct HandleTraits<VkDevice> { - typedef Device LoaderObjectType; -}; -template <> -struct HandleTraits<VkQueue> { - typedef Device LoaderObjectType; -}; -template <> -struct HandleTraits<VkCommandBuffer> { - typedef Device LoaderObjectType; -}; - -template <typename THandle> -typename HandleTraits<THandle>::LoaderObjectType& GetDispatchParent( - THandle handle) { - // TODO(jessehall): Make Instance and Device POD types (by removing the - // non-default constructors), so that offsetof is actually legal to use. - // The specific case we're using here is safe in gcc/clang (and probably - // most other C++ compilers), but isn't guaranteed by C++. - typedef typename HandleTraits<THandle>::LoaderObjectType ObjectType; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Winvalid-offsetof" - const size_t kBaseOffset = offsetof(ObjectType, base); -#pragma clang diagnostic pop - - const auto& base = driver::GetData(handle); - uintptr_t base_addr = reinterpret_cast<uintptr_t>(&base); - uintptr_t object_addr = base_addr - kBaseOffset; - return *reinterpret_cast<ObjectType*>(object_addr); -} - -// ----------------------------------------------------------------------------- - -void DestroyDevice(Device* device, VkDevice vkdevice) { - const auto& instance = *device->instance; - - if (vkdevice != VK_NULL_HANDLE) - instance.drv.dispatch.DestroyDevice(vkdevice, instance.alloc); - - device->~Device(); - instance.alloc->pfnFree(instance.alloc->pUserData, device); -} - -/* - * This function will return the pNext pointer of any - * CreateInfo extensions that are not loader extensions. - * This is used to skip past the loader extensions prepended - * to the list during CreateInstance and CreateDevice. - */ -void* StripCreateExtensions(const void* pNext) { - VkLayerInstanceCreateInfo* create_info = - const_cast<VkLayerInstanceCreateInfo*>( - static_cast<const VkLayerInstanceCreateInfo*>(pNext)); - - while ( - create_info && - (create_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO || - create_info->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO)) { - create_info = const_cast<VkLayerInstanceCreateInfo*>( - static_cast<const VkLayerInstanceCreateInfo*>(create_info->pNext)); - } - - return create_info; -} - -// Clean up and deallocate an Instance; called from both the failure paths in -// CreateInstance_Top as well as from DestroyInstance_Top. This function does -// not call down the dispatch chain; that should be done before calling this -// function, iff the lower vkCreateInstance call has been made and returned -// successfully. -void DestroyInstance(Instance* instance, - const VkAllocationCallbacks* allocator, - VkInstance vkinstance) { - if (vkinstance != VK_NULL_HANDLE && instance->drv.dispatch.DestroyInstance) - instance->drv.dispatch.DestroyInstance(vkinstance, allocator); - - instance->~Instance(); - allocator->pfnFree(allocator->pUserData, instance); -} - -} // anonymous namespace - -namespace vulkan { - -// ----------------------------------------------------------------------------- -// "Bottom" functions. These are called at the end of the instance dispatch -// chain. - -VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, - const VkAllocationCallbacks* allocator, - VkInstance* vkinstance) { - VkResult result; - - if (!allocator) - allocator = &kDefaultAllocCallbacks; - - void* instance_mem = allocator->pfnAllocation( - allocator->pUserData, sizeof(Instance), alignof(Instance), - VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); - if (!instance_mem) - return VK_ERROR_OUT_OF_HOST_MEMORY; - Instance& instance = *new (instance_mem) Instance(allocator); - - // Check that all enabled extensions are supported - uint32_t num_driver_extensions = 0; - for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) { - const char* name = create_info->ppEnabledExtensionNames[i]; - InstanceExtension id = InstanceExtensionFromName(name); - if (id != kInstanceExtensionCount) { - if (g_driver_instance_extensions[id]) { - num_driver_extensions++; - instance.enabled_extensions.set(id); - continue; - } - if (id == kKHR_surface || id == kKHR_android_surface) { - instance.enabled_extensions.set(id); - continue; - } - // The loader natively supports debug report. - if (id == kEXT_debug_report) { - continue; - } - } - } - - VkInstanceCreateInfo driver_create_info = *create_info; - driver_create_info.pNext = StripCreateExtensions(create_info->pNext); - driver_create_info.enabledLayerCount = 0; - driver_create_info.ppEnabledLayerNames = nullptr; - driver_create_info.enabledExtensionCount = 0; - driver_create_info.ppEnabledExtensionNames = nullptr; - if (num_driver_extensions > 0) { - const char** names = static_cast<const char**>( - alloca(num_driver_extensions * sizeof(char*))); - for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) { - const char* name = create_info->ppEnabledExtensionNames[i]; - InstanceExtension id = InstanceExtensionFromName(name); - if (id != kInstanceExtensionCount) { - if (g_driver_instance_extensions[id]) { - names[driver_create_info.enabledExtensionCount++] = name; - continue; - } - } - } - driver_create_info.ppEnabledExtensionNames = names; - ALOG_ASSERT( - driver_create_info.enabledExtensionCount == num_driver_extensions, - "counted enabled driver instance extensions twice and got " - "different answers!"); - } - - VkInstance drv_instance; - result = g_hwdevice->CreateInstance(&driver_create_info, instance.alloc, - &drv_instance); - if (result != VK_SUCCESS) { - DestroyInstance(&instance, allocator, VK_NULL_HANDLE); - return result; - } - - if (!driver::SetData(drv_instance, instance.base)) { - DestroyInstance(&instance, allocator, drv_instance); - return VK_ERROR_INITIALIZATION_FAILED; - } - - if (!LoadDriverDispatchTable(drv_instance, g_hwdevice->GetInstanceProcAddr, - instance.enabled_extensions, - instance.drv.dispatch)) { - DestroyInstance(&instance, allocator, drv_instance); - return VK_ERROR_INITIALIZATION_FAILED; - } - - uint32_t num_physical_devices = 0; - result = instance.drv.dispatch.EnumeratePhysicalDevices( - drv_instance, &num_physical_devices, nullptr); - if (result != VK_SUCCESS) { - DestroyInstance(&instance, allocator, drv_instance); - return VK_ERROR_INITIALIZATION_FAILED; - } - num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices); - result = instance.drv.dispatch.EnumeratePhysicalDevices( - drv_instance, &num_physical_devices, instance.physical_devices); - if (result != VK_SUCCESS) { - DestroyInstance(&instance, allocator, drv_instance); - return VK_ERROR_INITIALIZATION_FAILED; - } - - Vector<VkExtensionProperties> extensions( - Vector<VkExtensionProperties>::allocator_type(instance.alloc)); - for (uint32_t i = 0; i < num_physical_devices; i++) { - if (!driver::SetData(instance.physical_devices[i], instance.base)) { - DestroyInstance(&instance, allocator, drv_instance); - return VK_ERROR_INITIALIZATION_FAILED; - } - - uint32_t count; - if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties( - instance.physical_devices[i], nullptr, &count, nullptr)) != - VK_SUCCESS) { - ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i, - result); - continue; - } - try { - extensions.resize(count); - } catch (std::bad_alloc&) { - ALOGE("instance creation failed: out of memory"); - DestroyInstance(&instance, allocator, drv_instance); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties( - instance.physical_devices[i], nullptr, &count, - extensions.data())) != VK_SUCCESS) { - ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i, - result); - continue; - } - ALOGV_IF(count > 0, "driver gpu[%u] supports extensions:", i); - for (const auto& extension : extensions) { - ALOGV(" %s (v%u)", extension.extensionName, extension.specVersion); - DeviceExtension id = - DeviceExtensionFromName(extension.extensionName); - if (id == kDeviceExtensionCount) { - ALOGW("driver gpu[%u] extension '%s' unknown to loader", i, - extension.extensionName); - } else { - instance.physical_device_driver_extensions[i].set(id); - } - } - // Ignore driver attempts to support loader extensions - instance.physical_device_driver_extensions[i].reset(kKHR_swapchain); - } - instance.num_physical_devices = num_physical_devices; - - *vkinstance = drv_instance; - - 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) { - Instance& instance = GetDispatchParent(vkinstance); - uint32_t count = instance.num_physical_devices; - if (pdevs) { - count = std::min(count, *pdev_count); - std::copy(instance.physical_devices, instance.physical_devices + count, - pdevs); - } - *pdev_count = count; - 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, - const char* layer_name, - uint32_t* properties_count, - VkExtensionProperties* properties) { - (void)layer_name; - - Instance& instance = GetDispatchParent(pdev); - - size_t gpu_idx = 0; - while (instance.physical_devices[gpu_idx] != pdev) - gpu_idx++; - const DeviceExtensionSet driver_extensions = - instance.physical_device_driver_extensions[gpu_idx]; - - // We only support VK_KHR_swapchain if the GPU supports - // VK_ANDROID_native_buffer - VkExtensionProperties* available = static_cast<VkExtensionProperties*>( - alloca(kDeviceExtensionCount * sizeof(VkExtensionProperties))); - uint32_t num_extensions = 0; - if (driver_extensions[kANDROID_native_buffer]) { - available[num_extensions++] = VkExtensionProperties{ - VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_SPEC_VERSION}; - } - - if (!properties || *properties_count > num_extensions) - *properties_count = num_extensions; - if (properties) - std::copy(available, available + *properties_count, properties); - - 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, - const VkAllocationCallbacks* allocator, - VkDevice* device_out) { - Instance& instance = GetDispatchParent(gpu); - - // FIXME(jessehall): We don't have good conventions or infrastructure yet to - // do better than just using the instance allocator and scope for - // everything. See b/26732122. - if (true /*!allocator*/) - allocator = instance.alloc; - - void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Device), - alignof(Device), - VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); - if (!mem) - return VK_ERROR_OUT_OF_HOST_MEMORY; - Device* device = new (mem) Device(&instance); - - size_t gpu_idx = 0; - while (instance.physical_devices[gpu_idx] != gpu) - gpu_idx++; - - VkDeviceCreateInfo driver_create_info = *create_info; - driver_create_info.pNext = StripCreateExtensions(create_info->pNext); - driver_create_info.enabledLayerCount = 0; - driver_create_info.ppEnabledLayerNames = nullptr; - - uint32_t num_driver_extensions = 0; - const char** driver_extensions = static_cast<const char**>( - alloca(create_info->enabledExtensionCount * sizeof(const char*))); - for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) { - const char* name = create_info->ppEnabledExtensionNames[i]; - DeviceExtension id = DeviceExtensionFromName(name); - if (id != kDeviceExtensionCount) { - if (instance.physical_device_driver_extensions[gpu_idx][id]) { - driver_extensions[num_driver_extensions++] = name; - device->enabled_extensions.set(id); - continue; - } - // Add the VK_ANDROID_native_buffer extension to the list iff - // the VK_KHR_swapchain extension was requested - if (id == kKHR_swapchain && - instance.physical_device_driver_extensions - [gpu_idx][kANDROID_native_buffer]) { - driver_extensions[num_driver_extensions++] = - VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME; - device->enabled_extensions.set(id); - continue; - } - } - } - - driver_create_info.enabledExtensionCount = num_driver_extensions; - driver_create_info.ppEnabledExtensionNames = driver_extensions; - VkDevice drv_device; - VkResult result = instance.drv.dispatch.CreateDevice( - gpu, &driver_create_info, allocator, &drv_device); - if (result != VK_SUCCESS) { - DestroyDevice(device, VK_NULL_HANDLE); - return VK_ERROR_INITIALIZATION_FAILED; - } - - if (!driver::SetData(drv_device, device->base)) { - DestroyDevice(device, drv_device); - return VK_ERROR_INITIALIZATION_FAILED; - } - - device->get_device_proc_addr = reinterpret_cast<PFN_vkGetDeviceProcAddr>( - instance.drv.dispatch.GetDeviceProcAddr(drv_device, - "vkGetDeviceProcAddr")); - *device_out = drv_device; - return VK_SUCCESS; -} - -void DestroyInstance_Bottom(VkInstance vkinstance, - const VkAllocationCallbacks* allocator) { - Instance& instance = GetDispatchParent(vkinstance); - - VkAllocationCallbacks local_allocator; - if (!allocator) { - local_allocator = *instance.alloc; - allocator = &local_allocator; - } - - 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); -} - -void GetDeviceQueue_Bottom(VkDevice vkdevice, - uint32_t family, - uint32_t index, - VkQueue* queue_out) { - const auto& device = GetDispatchParent(vkdevice); - const auto& instance = *device.instance; - - instance.drv.dispatch.GetDeviceQueue(vkdevice, family, index, queue_out); - driver::SetData(*queue_out, device.base); -} - -VkResult AllocateCommandBuffers_Bottom( - VkDevice vkdevice, - const VkCommandBufferAllocateInfo* alloc_info, - VkCommandBuffer* cmdbufs) { - const auto& device = GetDispatchParent(vkdevice); - const auto& instance = *device.instance; - - VkResult result = instance.drv.dispatch.AllocateCommandBuffers( - vkdevice, alloc_info, cmdbufs); - if (result == VK_SUCCESS) { - for (uint32_t i = 0; i < alloc_info->commandBufferCount; i++) - driver::SetData(cmdbufs[i], device.base); - } - - return result; -} - -// ----------------------------------------------------------------------------- - -const VkAllocationCallbacks* GetAllocator(VkInstance vkinstance) { - return GetDispatchParent(vkinstance).alloc; -} - -const VkAllocationCallbacks* GetAllocator(VkDevice vkdevice) { - return GetDispatchParent(vkdevice).instance->alloc; -} - -VkInstance GetDriverInstance(VkInstance instance) { - return instance; -} - -const DriverDispatchTable& GetDriverDispatch(VkInstance instance) { - return GetDispatchParent(instance).drv.dispatch; -} - -const DriverDispatchTable& GetDriverDispatch(VkDevice device) { - return GetDispatchParent(device).instance->drv.dispatch; -} - -const DriverDispatchTable& GetDriverDispatch(VkQueue queue) { - return GetDispatchParent(queue).instance->drv.dispatch; -} - -DebugReportCallbackList& GetDebugReportCallbacks(VkInstance instance) { - return GetDispatchParent(instance).debug_report_callbacks; -} - -namespace driver { - -bool Debuggable() { - return (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) >= 0); -} - -bool OpenHAL() { - if (!g_hwdevice) - LoadVulkanHAL(); - - return (g_hwdevice != nullptr); -} - -const VkAllocationCallbacks& GetDefaultAllocator() { - return kDefaultAllocCallbacks; -} - -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, - VkExtensionProperties* pProperties) { - (void)pLayerName; - - VkExtensionProperties* available = static_cast<VkExtensionProperties*>( - alloca(kInstanceExtensionCount * sizeof(VkExtensionProperties))); - uint32_t num_extensions = 0; - - available[num_extensions++] = VkExtensionProperties{ - VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION}; - available[num_extensions++] = - VkExtensionProperties{VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, - VK_KHR_ANDROID_SURFACE_SPEC_VERSION}; - if (g_driver_instance_extensions[kEXT_debug_report]) { - available[num_extensions++] = - VkExtensionProperties{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, - VK_EXT_DEBUG_REPORT_SPEC_VERSION}; - } - - if (!pProperties || *pPropertyCount > num_extensions) - *pPropertyCount = num_extensions; - if (pProperties) - std::copy(available, available + *pPropertyCount, pProperties); - - return *pPropertyCount < num_extensions ? VK_INCOMPLETE : VK_SUCCESS; -} - -} // namespace driver - -} // namespace vulkan diff --git a/vulkan/libvulkan/loader.h b/vulkan/libvulkan/loader.h deleted file mode 100644 index 0ec08b294a..0000000000 --- a/vulkan/libvulkan/loader.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2015 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. - */ - -#ifndef LIBVULKAN_LOADER_H -#define LIBVULKAN_LOADER_H 1 - -#include <bitset> -#include "dispatch_gen.h" -#include "debug_report.h" - -namespace vulkan { - -enum InstanceExtension { - kKHR_surface, - kKHR_android_surface, - kEXT_debug_report, - kInstanceExtensionCount -}; -typedef std::bitset<kInstanceExtensionCount> InstanceExtensionSet; - -enum DeviceExtension { - kKHR_swapchain, - kANDROID_native_buffer, - kDeviceExtensionCount -}; -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, - DriverDispatchTable& dispatch); - -// ----------------------------------------------------------------------------- -// loader.cpp - -// 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); -// clang-format on - -const VkAllocationCallbacks* GetAllocator(VkInstance instance); -const VkAllocationCallbacks* GetAllocator(VkDevice device); -VkInstance GetDriverInstance(VkInstance instance); -const DriverDispatchTable& GetDriverDispatch(VkInstance instance); -const DriverDispatchTable& GetDriverDispatch(VkDevice device); -const DriverDispatchTable& GetDriverDispatch(VkQueue queue); -DebugReportCallbackList& GetDebugReportCallbacks(VkInstance instance); - -// ----------------------------------------------------------------------------- -// swapchain.cpp - -// clang-format off -VKAPI_ATTR VkResult CreateAndroidSurfaceKHR_Bottom(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); -VKAPI_ATTR void DestroySurfaceKHR_Bottom(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* allocator); -VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceSupportKHR_Bottom(VkPhysicalDevice pdev, uint32_t queue_family, VkSurfaceKHR surface, VkBool32* pSupported); -VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR_Bottom(VkPhysicalDevice pdev, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* capabilities); -VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceFormatsKHR_Bottom(VkPhysicalDevice pdev, VkSurfaceKHR surface, uint32_t* count, VkSurfaceFormatKHR* formats); -VKAPI_ATTR VkResult GetPhysicalDeviceSurfacePresentModesKHR_Bottom(VkPhysicalDevice pdev, VkSurfaceKHR surface, uint32_t* count, VkPresentModeKHR* modes); -VKAPI_ATTR VkResult CreateSwapchainKHR_Bottom(VkDevice device, const VkSwapchainCreateInfoKHR* create_info, const VkAllocationCallbacks* allocator, VkSwapchainKHR* swapchain_handle); -VKAPI_ATTR void DestroySwapchainKHR_Bottom(VkDevice device, VkSwapchainKHR swapchain_handle, const VkAllocationCallbacks* allocator); -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 - -// ----------------------------------------------------------------------------- -// layers_extensions.cpp - -struct Layer; -class LayerRef { - public: - LayerRef(Layer* layer); - LayerRef(LayerRef&& other); - ~LayerRef(); - LayerRef(const LayerRef&) = delete; - LayerRef& operator=(const LayerRef&) = delete; - - const char* GetName() const; - uint32_t GetSpecVersion(); - - // provides bool-like behavior - operator const Layer*() const { return layer_; } - - PFN_vkGetInstanceProcAddr GetGetInstanceProcAddr() const; - PFN_vkGetDeviceProcAddr GetGetDeviceProcAddr() const; - - bool SupportsExtension(const char* name) const; - - private: - Layer* layer_; -}; - -void DiscoverLayers(); -uint32_t EnumerateInstanceLayers(uint32_t count, VkLayerProperties* properties); -uint32_t EnumerateDeviceLayers(uint32_t count, VkLayerProperties* properties); -void GetInstanceLayerExtensions(const char* name, - const VkExtensionProperties** properties, - uint32_t* count); -void GetDeviceLayerExtensions(const char* name, - const VkExtensionProperties** properties, - uint32_t* count); -LayerRef GetInstanceLayerRef(const char* name); -LayerRef GetDeviceLayerRef(const char* name); - -InstanceExtension InstanceExtensionFromName(const char* name); -DeviceExtension DeviceExtensionFromName(const char* name); - -} // namespace vulkan - -#endif // LIBVULKAN_LOADER_H diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp index ee52857916..320a2acc1d 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -21,14 +21,14 @@ #include <log/log.h> #include <sync/sync.h> -#include "loader.h" - -using namespace vulkan; +#include "driver.h" // TODO(jessehall): Currently we don't have a good error code for when a native // window operation fails. Just returning INITIALIZATION_FAILED for now. Later // versions (post SDK 0.9) of the API/extension have a better error code. // When updating to that version, audit all error returns. +namespace vulkan { +namespace driver { namespace { @@ -98,9 +98,9 @@ template <typename T, typename Host> std::shared_ptr<T> InitSharedPtr(Host host, T* obj) { try { obj->common.incRef(&obj->common); - return std::shared_ptr<T>( - obj, NativeBaseDeleter<T>(), - VulkanAllocator<T>(*GetAllocator(host), AllocScope<Host>::kScope)); + return std::shared_ptr<T>(obj, NativeBaseDeleter<T>(), + VulkanAllocator<T>(GetData(host).allocator, + AllocScope<Host>::kScope)); } catch (std::bad_alloc&) { return nullptr; } @@ -223,16 +223,14 @@ Swapchain* SwapchainFromHandle(VkSwapchainKHR handle) { } // anonymous namespace -namespace vulkan { - VKAPI_ATTR -VkResult CreateAndroidSurfaceKHR_Bottom( +VkResult CreateAndroidSurfaceKHR( VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* allocator, VkSurfaceKHR* out_surface) { if (!allocator) - allocator = GetAllocator(instance); + allocator = &GetData(instance).allocator; void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Surface), alignof(Surface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); @@ -266,30 +264,30 @@ VkResult CreateAndroidSurfaceKHR_Bottom( } VKAPI_ATTR -void DestroySurfaceKHR_Bottom(VkInstance instance, - VkSurfaceKHR surface_handle, - const VkAllocationCallbacks* allocator) { +void DestroySurfaceKHR(VkInstance instance, + VkSurfaceKHR surface_handle, + const VkAllocationCallbacks* allocator) { Surface* surface = SurfaceFromHandle(surface_handle); if (!surface) return; native_window_api_disconnect(surface->window.get(), NATIVE_WINDOW_API_EGL); surface->~Surface(); if (!allocator) - allocator = GetAllocator(instance); + allocator = &GetData(instance).allocator; allocator->pfnFree(allocator->pUserData, surface); } VKAPI_ATTR -VkResult GetPhysicalDeviceSurfaceSupportKHR_Bottom(VkPhysicalDevice /*pdev*/, - uint32_t /*queue_family*/, - VkSurfaceKHR /*surface*/, - VkBool32* supported) { +VkResult GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice /*pdev*/, + uint32_t /*queue_family*/, + VkSurfaceKHR /*surface*/, + VkBool32* supported) { *supported = VK_TRUE; return VK_SUCCESS; } VKAPI_ATTR -VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR_Bottom( +VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR( VkPhysicalDevice /*pdev*/, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* capabilities) { @@ -356,11 +354,10 @@ VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR_Bottom( } VKAPI_ATTR -VkResult GetPhysicalDeviceSurfaceFormatsKHR_Bottom( - VkPhysicalDevice /*pdev*/, - VkSurfaceKHR /*surface*/, - uint32_t* count, - VkSurfaceFormatKHR* formats) { +VkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice /*pdev*/, + VkSurfaceKHR /*surface*/, + uint32_t* count, + VkSurfaceFormatKHR* formats) { // TODO(jessehall): Fill out the set of supported formats. Longer term, add // a new gralloc method to query whether a (format, usage) pair is // supported, and check that for each gralloc format that corresponds to a @@ -385,11 +382,10 @@ VkResult GetPhysicalDeviceSurfaceFormatsKHR_Bottom( } VKAPI_ATTR -VkResult GetPhysicalDeviceSurfacePresentModesKHR_Bottom( - VkPhysicalDevice /*pdev*/, - VkSurfaceKHR /*surface*/, - uint32_t* count, - VkPresentModeKHR* modes) { +VkResult GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice /*pdev*/, + VkSurfaceKHR /*surface*/, + uint32_t* count, + VkPresentModeKHR* modes) { const VkPresentModeKHR kModes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR, }; @@ -406,15 +402,15 @@ VkResult GetPhysicalDeviceSurfacePresentModesKHR_Bottom( } VKAPI_ATTR -VkResult CreateSwapchainKHR_Bottom(VkDevice device, - const VkSwapchainCreateInfoKHR* create_info, - const VkAllocationCallbacks* allocator, - VkSwapchainKHR* swapchain_handle) { +VkResult CreateSwapchainKHR(VkDevice device, + const VkSwapchainCreateInfoKHR* create_info, + const VkAllocationCallbacks* allocator, + VkSwapchainKHR* swapchain_handle) { int err; VkResult result = VK_SUCCESS; if (!allocator) - allocator = GetAllocator(device); + allocator = &GetData(device).allocator; ALOGV_IF(create_info->imageArrayLayers != 1, "Swapchain imageArrayLayers (%u) != 1 not supported", @@ -435,7 +431,7 @@ VkResult CreateSwapchainKHR_Bottom(VkDevice device, // -- Configure the native window -- Surface& surface = *SurfaceFromHandle(create_info->surface); - const DriverDispatchTable& dispatch = GetDriverDispatch(device); + const auto& dispatch = GetData(device).driver; int native_format = HAL_PIXEL_FORMAT_RGBA_8888; switch (create_info->imageFormat) { @@ -680,10 +676,10 @@ VkResult CreateSwapchainKHR_Bottom(VkDevice device, } VKAPI_ATTR -void DestroySwapchainKHR_Bottom(VkDevice device, - VkSwapchainKHR swapchain_handle, - const VkAllocationCallbacks* allocator) { - const DriverDispatchTable& dispatch = GetDriverDispatch(device); +void DestroySwapchainKHR(VkDevice device, + VkSwapchainKHR swapchain_handle, + const VkAllocationCallbacks* allocator) { + const auto& dispatch = GetData(device).driver; Swapchain* swapchain = SwapchainFromHandle(swapchain_handle); const std::shared_ptr<ANativeWindow>& window = swapchain->surface.window; @@ -701,16 +697,16 @@ void DestroySwapchainKHR_Bottom(VkDevice device, } if (!allocator) - allocator = GetAllocator(device); + allocator = &GetData(device).allocator; swapchain->~Swapchain(); allocator->pfnFree(allocator->pUserData, swapchain); } VKAPI_ATTR -VkResult GetSwapchainImagesKHR_Bottom(VkDevice, - VkSwapchainKHR swapchain_handle, - uint32_t* count, - VkImage* images) { +VkResult GetSwapchainImagesKHR(VkDevice, + VkSwapchainKHR swapchain_handle, + uint32_t* count, + VkImage* images) { Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle); VkResult result = VK_SUCCESS; if (images) { @@ -727,12 +723,12 @@ VkResult GetSwapchainImagesKHR_Bottom(VkDevice, } VKAPI_ATTR -VkResult AcquireNextImageKHR_Bottom(VkDevice device, - VkSwapchainKHR swapchain_handle, - uint64_t timeout, - VkSemaphore semaphore, - VkFence vk_fence, - uint32_t* image_index) { +VkResult AcquireNextImageKHR(VkDevice device, + VkSwapchainKHR swapchain_handle, + uint64_t timeout, + VkSemaphore semaphore, + VkFence vk_fence, + uint32_t* image_index) { Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle); ANativeWindow* window = swapchain.surface.window.get(); VkResult result; @@ -776,7 +772,7 @@ VkResult AcquireNextImageKHR_Bottom(VkDevice device, } } - result = GetDriverDispatch(device).AcquireImageANDROID( + result = GetData(device).driver.AcquireImageANDROID( device, swapchain.images[idx].image, fence_clone, semaphore, vk_fence); if (result != VK_SUCCESS) { // NOTE: we're relying on AcquireImageANDROID to close fence_clone, @@ -797,14 +793,13 @@ VkResult AcquireNextImageKHR_Bottom(VkDevice device, } VKAPI_ATTR -VkResult QueuePresentKHR_Bottom(VkQueue queue, - const VkPresentInfoKHR* present_info) { +VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { ALOGV_IF(present_info->sType != VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, "vkQueuePresentKHR: invalid VkPresentInfoKHR structure type %d", present_info->sType); ALOGV_IF(present_info->pNext, "VkPresentInfo::pNext != NULL"); - const DriverDispatchTable& dispatch = GetDriverDispatch(queue); + const auto& dispatch = GetData(queue).driver; VkResult final_result = VK_SUCCESS; for (uint32_t sc = 0; sc < present_info->swapchainCount; sc++) { Swapchain& swapchain = @@ -857,4 +852,5 @@ VkResult QueuePresentKHR_Bottom(VkQueue queue, return final_result; } +} // namespace driver } // namespace vulkan diff --git a/vulkan/libvulkan/swapchain.h b/vulkan/libvulkan/swapchain.h new file mode 100644 index 0000000000..2c60c496c4 --- /dev/null +++ b/vulkan/libvulkan/swapchain.h @@ -0,0 +1,42 @@ +/* + * Copyright 2015 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. + */ + +#ifndef LIBVULKAN_SWAPCHAIN_H +#define LIBVULKAN_SWAPCHAIN_H 1 + +#include <vulkan/vulkan.h> + +namespace vulkan { +namespace driver { + +// clang-format off +VKAPI_ATTR VkResult CreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); +VKAPI_ATTR void DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* allocator); +VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice pdev, uint32_t queue_family, VkSurfaceKHR surface, VkBool32* pSupported); +VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice pdev, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* capabilities); +VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice pdev, VkSurfaceKHR surface, uint32_t* count, VkSurfaceFormatKHR* formats); +VKAPI_ATTR VkResult GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice pdev, VkSurfaceKHR surface, uint32_t* count, VkPresentModeKHR* modes); +VKAPI_ATTR VkResult CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* create_info, const VkAllocationCallbacks* allocator, VkSwapchainKHR* swapchain_handle); +VKAPI_ATTR void DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain_handle, const VkAllocationCallbacks* allocator); +VKAPI_ATTR VkResult GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain_handle, uint32_t* count, VkImage* images); +VKAPI_ATTR VkResult AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain_handle, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* image_index); +VKAPI_ATTR VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info); +// clang-format on + +} // namespace driver +} // namespace vulkan + +#endif // LIBVULKAN_SWAPCHAIN_H |