From 9d51816145b008b7b4b091a8c90faf30ba0394e4 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 24 Mar 2016 14:55:27 +0800 Subject: vulkan: move driver::Debuggable Move it from loader.cpp to driver.cpp. No functional change. Change-Id: I455e798d6001f9719d378ae0295f2b4b181b0c09 --- vulkan/libvulkan/driver.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 vulkan/libvulkan/driver.cpp (limited to 'vulkan/libvulkan/driver.cpp') diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp new file mode 100644 index 0000000000..26c192374d --- /dev/null +++ b/vulkan/libvulkan/driver.cpp @@ -0,0 +1,29 @@ +/* + * 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 + +#include "driver.h" + +namespace vulkan { +namespace driver { + +bool Debuggable() { + return (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) >= 0); +} + +} // namespace driver +} // namespace vulkan -- cgit v1.2.3-59-g8ed1b From 136b8eb38e98d96009799eee59d4ea0088544b54 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 24 Mar 2016 15:01:52 +0800 Subject: vulkan: move driver::OpenHAL Move it from loader.cpp to driver.cpp. HAL loading is now done in driver.cpp while HAL extension queries are still done in loader.cpp. Change-Id: I15d7ead98497adacb1bd798522f057ff6bf16909 --- vulkan/libvulkan/driver.cpp | 39 +++++++++++++++++++++++++++++++++++++++ vulkan/libvulkan/loader.cpp | 44 +++++++++++++------------------------------- vulkan/libvulkan/loader.h | 4 ++++ 3 files changed, 56 insertions(+), 31 deletions(-) (limited to 'vulkan/libvulkan/driver.cpp') diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index 26c192374d..09811a036a 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -17,13 +17,52 @@ #include #include "driver.h" +#include "loader.h" namespace vulkan { namespace driver { +namespace { + +hwvulkan_device_t* g_hwdevice = nullptr; + +} // 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(&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(&device)); + if (result != 0) { + ALOGE("failed to open vulkan driver: %s (%d)", strerror(-result), + result); + return false; + } + + if (!InitLoader(device)) { + device->common.close(&device->common); + return false; + } + + g_hwdevice = device; + + return true; +} + } // namespace driver } // namespace vulkan diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp index 9a3a3f854c..2c63b0643c 100644 --- a/vulkan/libvulkan/loader.cpp +++ b/vulkan/libvulkan/loader.cpp @@ -178,34 +178,14 @@ const VkAllocationCallbacks kDefaultAllocCallbacks = { 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(&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(&g_hwdevice)); - if (result != 0) { - ALOGE("failed to open vulkan driver: %s (%d)", strerror(-result), - result); - module = nullptr; - return; - } - +bool LoadVulkanHAL() { 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; + return false; } VkExtensionProperties* extensions = static_cast( alloca(count * sizeof(VkExtensionProperties))); @@ -213,10 +193,7 @@ void LoadVulkanHAL() { nullptr, &count, extensions)) != VK_SUCCESS) { ALOGE("driver EnumerateInstanceExtensionProperties failed: %d", vkresult); - g_hwdevice->common.close(&g_hwdevice->common); - g_hwdevice = nullptr; - module = nullptr; - return; + return false; } ALOGV_IF(count > 0, "Driver-supported instance extensions:"); for (uint32_t i = 0; i < count; i++) { @@ -230,6 +207,8 @@ void LoadVulkanHAL() { // Ignore driver attempts to support loader extensions g_driver_instance_extensions.reset(kKHR_surface); g_driver_instance_extensions.reset(kKHR_android_surface); + + return true; } // ----------------------------------------------------------------------------- @@ -986,15 +965,18 @@ DebugReportCallbackList& GetDebugReportCallbacks(VkInstance instance) { return GetDispatchParent(instance).debug_report_callbacks; } -namespace driver { - -bool OpenHAL() { - if (!g_hwdevice) - LoadVulkanHAL(); +bool InitLoader(hwvulkan_device_t* dev) { + if (!g_hwdevice) { + g_hwdevice = dev; + if (!LoadVulkanHAL()) + g_hwdevice = nullptr; + } return (g_hwdevice != nullptr); } +namespace driver { + const VkAllocationCallbacks& GetDefaultAllocator() { return kDefaultAllocCallbacks; } diff --git a/vulkan/libvulkan/loader.h b/vulkan/libvulkan/loader.h index 0ec08b294a..255b6c517d 100644 --- a/vulkan/libvulkan/loader.h +++ b/vulkan/libvulkan/loader.h @@ -21,6 +21,8 @@ #include "dispatch_gen.h" #include "debug_report.h" +struct hwvulkan_device_t; + namespace vulkan { enum InstanceExtension { @@ -50,6 +52,8 @@ bool LoadDriverDispatchTable(VkInstance instance, // ----------------------------------------------------------------------------- // loader.cpp +bool InitLoader(hwvulkan_device_t* dev); + // clang-format off VKAPI_ATTR VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, const VkAllocationCallbacks* allocator, VkInstance* vkinstance); VKAPI_ATTR PFN_vkVoidFunction GetInstanceProcAddr_Bottom(VkInstance, const char* name); -- cgit v1.2.3-59-g8ed1b From dbb7e9c8f950ad344eee22cc50acc67253f9f4b1 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 24 Mar 2016 15:09:38 +0800 Subject: vulkan: move driver::GetDefaultAllocator Move it from loader.cpp to driver.cpp. No functional change. Change-Id: I8c9bb5315c29ff69bfd971ac8e1264fb8329a811 --- vulkan/libvulkan/driver.cpp | 79 +++++++++++++++++++++++++++++++++++++++++++++ vulkan/libvulkan/loader.cpp | 79 +-------------------------------------------- 2 files changed, 80 insertions(+), 78 deletions(-) (limited to 'vulkan/libvulkan/driver.cpp') diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index 09811a036a..4acc867201 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -14,11 +14,31 @@ * limitations under the License. */ +#include +#include +#include +#include #include #include "driver.h" #include "loader.h" +// #define ENABLE_ALLOC_CALLSTACKS 1 +#if ENABLE_ALLOC_CALLSTACKS +#include +#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 { @@ -26,6 +46,54 @@ namespace { 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); +} + } // anonymous namespace bool Debuggable() { @@ -64,5 +132,16 @@ bool OpenHAL() { return true; } +const VkAllocationCallbacks& GetDefaultAllocator() { + static const VkAllocationCallbacks kDefaultAllocCallbacks = { + .pUserData = nullptr, + .pfnAllocation = DefaultAllocate, + .pfnReallocation = DefaultReallocate, + .pfnFree = DefaultFree, + }; + + return kDefaultAllocCallbacks; +} + } // namespace driver } // namespace vulkan diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp index 2c63b0643c..2d48fda688 100644 --- a/vulkan/libvulkan/loader.cpp +++ b/vulkan/libvulkan/loader.cpp @@ -39,22 +39,6 @@ #include #include -// #define ENABLE_ALLOC_CALLSTACKS 1 -#if ENABLE_ALLOC_CALLSTACKS -#include -#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; @@ -115,63 +99,6 @@ using Vector = std::vector>; typedef std::basic_string, CallbackAllocator> 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 @@ -359,7 +286,7 @@ VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, VkResult result; if (!allocator) - allocator = &kDefaultAllocCallbacks; + allocator = &driver::GetDefaultAllocator(); void* instance_mem = allocator->pfnAllocation( allocator->pUserData, sizeof(Instance), alignof(Instance), @@ -977,10 +904,6 @@ bool InitLoader(hwvulkan_device_t* dev) { namespace driver { -const VkAllocationCallbacks& GetDefaultAllocator() { - return kDefaultAllocCallbacks; -} - PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) { return GetInstanceProcAddr_Bottom(instance, pName); } -- cgit v1.2.3-59-g8ed1b From eb7db124e46da9a9210cf868353f5ea79502ffec Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 24 Mar 2016 09:11:06 +0800 Subject: vulkan: rework driver::Get*ProcAddr Introduce driver::ProcHook which is a struct to describe an intercepted function. Given a function name, GetProcHook returns a ProcHook if the function is intercepted. NULL otherwise. A ProcHook has three function pointers. ProcHook::proc points to the real intercepting function. ProcHook::disabled_proc points to a no-op function that logs an error. ProcHook::checked_proc points to a trampoline that calls either ProcHook::proc or ProcHook::disabled_proc. For core functions, driver::Get*ProcAddr simply return ProcHook::proc. For extension functions, driver::Get*ProcAddr return ProcHook::proc when the extension is known to be enabled. They return ProcHook::disabled_proc when the extension is known to be disabled. Finally, they return ProcHook::checked_proc when they do not know if the extension is enabled or not. All ProcHooks as well as their disabled_proc/checked_proc are generated in driver_gen.cpp. This allows us to get rid of all hand-written "_Disabled" functions, all no-op "_Bottom" functions, and special cases for VK_ANDROID_native_buffer. The reworked driver::Get*ProcAddr also detects more applications' errors and logs them. Change-Id: I8e6f476f450688b5547fd75243c66cb603c516b5 --- vulkan/libvulkan/Android.mk | 1 + vulkan/libvulkan/code-generator.tmpl | 390 +++++++++++++++++++++++++++++++++++ vulkan/libvulkan/dispatch.tmpl | 39 ---- vulkan/libvulkan/dispatch_gen.cpp | 66 ------ vulkan/libvulkan/driver.cpp | 62 ++++++ vulkan/libvulkan/driver.h | 22 ++ vulkan/libvulkan/driver_gen.cpp | 376 +++++++++++++++++++++++++++++++++ vulkan/libvulkan/driver_gen.h | 61 ++++++ vulkan/libvulkan/loader.cpp | 348 +++++++------------------------ vulkan/libvulkan/loader.h | 23 --- 10 files changed, 982 insertions(+), 406 deletions(-) create mode 100644 vulkan/libvulkan/driver_gen.cpp create mode 100644 vulkan/libvulkan/driver_gen.h (limited to 'vulkan/libvulkan/driver.cpp') diff --git a/vulkan/libvulkan/Android.mk b/vulkan/libvulkan/Android.mk index 665d45eac3..62d12797b1 100644 --- a/vulkan/libvulkan/Android.mk +++ b/vulkan/libvulkan/Android.mk @@ -44,6 +44,7 @@ LOCAL_SRC_FILES := \ debug_report.cpp \ dispatch_gen.cpp \ driver.cpp \ + driver_gen.cpp \ layers_extensions.cpp \ loader.cpp \ swapchain.cpp \ diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl index 7ebe983dba..f7083c3146 100644 --- a/vulkan/libvulkan/code-generator.tmpl +++ b/vulkan/libvulkan/code-generator.tmpl @@ -21,6 +21,8 @@ {{Macro "DefineGlobals" $}} {{$ | Macro "api_gen.h" | Format (Global "clang-format") | Write "api_gen.h" }} {{$ | Macro "api_gen.cpp" | Format (Global "clang-format") | Write "api_gen.cpp"}} +{{$ | Macro "driver_gen.h" | Format (Global "clang-format") | Write "driver_gen.h"}} +{{$ | Macro "driver_gen.cpp" | Format (Global "clang-format") | Write "driver_gen.cpp"}} {{/* ------------------------------------------------------------------------------- @@ -146,6 +148,110 @@ bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) { ¶{{end}} +{{/* +------------------------------------------------------------------------------- + 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 +#include +¶ +namespace vulkan {« +namespace driver {« +¶ +{{Macro "driver.C++.DefineProcHookType"}} +¶ +const ProcHook* GetProcHook(const char* name); +ProcHook::Extension GetProcHookExtension(const char* name); +¶ +»} // namespace driver +»} // namespace vulkan +¶ +#endif // LIBVULKAN_DRIVER_TABLE_H +¶{{end}} + + +{{/* +------------------------------------------------------------------------------- + driver_gen.cpp +------------------------------------------------------------------------------- +*/}} +{{define "driver_gen.cpp"}} +{{Macro "Copyright"}} +¶ +// WARNING: This file is generated. See ../README.md for instructions. +¶ +#include +#include +#include +¶ +#include "driver.h" +#include "loader.h" +¶ +namespace vulkan {« +namespace driver {« +¶ +namespace {« +¶ +// clang-format off +¶ +{{range $f := AllCommands $}} + {{Macro "driver.C++.DefineProcHookStubs" $f}} +{{end}} +// clang-format on +¶ +const ProcHook g_proc_hooks[] = { + // clang-format off + {{range $f := SortBy (AllCommands $) "FunctionName"}} + {{if (Macro "driver.IsIntercepted" $f)}} + {{ if (Macro "IsGloballyDispatched" $f)}} + {{Macro "driver.C++.DefineGlobalProcHook" $f}} + {{else if (Macro "IsInstanceDispatched" $f)}} + {{Macro "driver.C++.DefineInstanceProcHook" $f}} + {{else if (Macro "IsDeviceDispatched" $f)}} + {{Macro "driver.C++.DefineDeviceProcHook" $f}} + {{end}} + {{end}} + {{end}} + // clang-format on +}; +¶ +»} // anonymous +¶ +const ProcHook* GetProcHook(const char* name) { + const auto& begin = g_proc_hooks; + const auto& end = g_proc_hooks + + sizeof(g_proc_hooks) / sizeof(g_proc_hooks[0]); + const auto hook = std::lower_bound(begin, end, name, + [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; }); + return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr; +} +¶ +ProcHook::Extension GetProcHookExtension(const char* name) { + {{$exts := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}} + // clang-format off + {{range $e := $exts}} + if (strcmp(name, "{{$e}}") == 0) return ProcHook::{{TrimPrefix "VK_" $e}}; + {{end}} + // clang-format on + return ProcHook::EXTENSION_UNKNOWN; +} +¶ +»} // namespace driver +»} // namespace vulkan +¶ +// clang-format on +¶{{end}} + + {{/* ------------------------------------------------------------------------------ Emits a declaration of a dispatch table entry. @@ -385,6 +491,277 @@ bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) { {{end}} +{{/* +------------------------------------------------------------------------------ + Emits a list of extensions intercepted by vulkan::driver. +------------------------------------------------------------------------------ +*/}} +{{define "driver.InterceptedExtensions"}} +VK_ANDROID_native_buffer +VK_EXT_debug_report +VK_KHR_android_surface +VK_KHR_surface +VK_KHR_swapchain +{{end}} + + +{{/* +------------------------------------------------------------------------------ + Emits true if an extension is intercepted by vulkan::driver. +------------------------------------------------------------------------------ +*/}} +{{define "driver.IsExtensionIntercepted"}} + {{$ext_name := index $.Arguments 0}} + {{$filters := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}} + + {{range $f := $filters}} + {{if eq $ext_name $f}}true{{end}} + {{end}} +{{end}} + + +{{/* +------------------------------------------------------------------------------ + Emits true if a function is intercepted by vulkan::driver. +------------------------------------------------------------------------------ +*/}} +{{define "driver.IsIntercepted"}} + {{AssertType $ "Function"}} + + {{if (Macro "IsFunctionSupported" $)}} + {{/* Create functions of dispatchable objects */}} + {{ if eq $.Name "vkCreateInstance"}}true + {{else if eq $.Name "vkCreateDevice"}}true + {{else if eq $.Name "vkGetDeviceQueue"}}true + {{else if eq $.Name "vkAllocateCommandBuffers"}}true + + {{/* Destroy functions of dispatchable objects */}} + {{else if eq $.Name "vkDestroyInstance"}}true + {{else if eq $.Name "vkDestroyDevice"}}true + + {{/* Enumeration of extensions */}} + {{else if eq $.Name "vkEnumerateInstanceExtensionProperties"}}true + {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true + + {{/* We cache physical devices in loader.cpp */}} + {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true + + {{else if eq $.Name "vkGetInstanceProcAddr"}}true + {{else if eq $.Name "vkGetDeviceProcAddr"}}true + + {{end}} + + {{$ext := GetAnnotation $ "extension"}} + {{if $ext}} + {{Macro "driver.IsExtensionIntercepted" $ext}} + {{end}} + + {{end}} +{{end}} + + +{{/* +------------------------------------------------------------------------------ + Emits true if a function needs ProcHook stubs. +------------------------------------------------------------------------------ +*/}} +{{define "driver.NeedProcHookStubs"}} + {{AssertType $ "Function"}} + + {{if (Macro "driver.IsIntercepted" $)}} + {{$ext := GetAnnotation $ "extension"}} + {{if $ext}} + {{if not (Macro "IsExtensionInternal" $ext)}}true{{end}} + {{end}} + {{end}} +{{end}} + + +{{/* +------------------------------------------------------------------------------- + Emits definition of struct ProcHook. +------------------------------------------------------------------------------- +*/}} +{{define "driver.C++.DefineProcHookType"}} + struct ProcHook { + enum Type { + GLOBAL, + INSTANCE, + DEVICE, + }; + + enum Extension { + {{$exts := Strings (Macro "driver.InterceptedExtensions") | SplitOn "\n"}} + {{range $e := $exts}} + {{TrimPrefix "VK_" $e}}, + {{end}} + ¶ + EXTENSION_CORE, // valid bit + EXTENSION_COUNT, + EXTENSION_UNKNOWN, + }; + ¶ + const char* name; + Type type; + Extension extension; + ¶ + PFN_vkVoidFunction proc; + PFN_vkVoidFunction disabled_proc; // nullptr for global hooks + PFN_vkVoidFunction checked_proc; // nullptr for global/instance hooks + }; +{{end}} + + +{{/* +------------------------------------------------------------------------------- + Emits definitions of stub functions for ProcHook. +------------------------------------------------------------------------------- +*/}} +{{define "driver.C++.DefineProcHookStubs"}} + {{AssertType $ "Function"}} + + {{if (Macro "driver.NeedProcHookStubs" $)}} + {{$ext := GetAnnotation $ "extension"}} + {{$ext_name := index $ext.Arguments 0}} + + {{$base := (Macro "BaseName" $)}} + {{$unnamed_params := (ForEach $.CallParameters "ParameterType" | JoinWith ", ")}} + + VKAPI_ATTR {{Node "Type" $.Return}} disabled{{$base}}({{$unnamed_params}}) { + ALOGE("{{$ext_name}} not enabled. {{$.Name}} not executed."); + {{if not (IsVoid $.Return.Type)}}return VK_SUCCESS;{{end}} + } + {{if (Macro "IsDeviceDispatched" $)}} + ¶ + VKAPI_ATTR {{Node "Type" $.Return}} checked{{$base}}({{Macro "Parameters" $}}) { + {{if not (IsVoid $.Return.Type)}}return §{{end}} + + {{$p0 := index $.CallParameters 0}} + {{$ext_hook := Strings ("ProcHook::") (Macro "BaseName" $ext)}} + (GetData({{$p0.Name}}).hook_extensions[{{$ext_hook}}]) ? § + {{$base}}_Bottom({{Macro "Arguments" $}}) : § + disabled{{$base}}({{Macro "Arguments" $}}); + } + {{end}} + ¶ + {{end}} +{{end}} + + +{{/* +------------------------------------------------------------------------------- + Emits definition of a global ProcHook. +------------------------------------------------------------------------------- +*/}} +{{define "driver.C++.DefineGlobalProcHook"}} + {{AssertType $ "Function"}} + + {{$base := (Macro "BaseName" $)}} + + {{$ext := GetAnnotation $ "extension"}} + {{if $ext}} + {{Error "invalid global extension"}} + {{end}} + + { + "{{$.Name}}", + ProcHook::GLOBAL, + ProcHook::EXTENSION_CORE, + {{if eq $.Name "vkEnumerateInstanceExtensionProperties"}} + reinterpret_cast({{$base}}), + {{else}} + reinterpret_cast({{$base}}_Bottom), + {{end}} + nullptr, + nullptr, + }, +{{end}} + + +{{/* +------------------------------------------------------------------------------- + Emits definition of an instance ProcHook. +------------------------------------------------------------------------------- +*/}} +{{define "driver.C++.DefineInstanceProcHook"}} + {{AssertType $ "Function"}} + + {{$base := (Macro "BaseName" $)}} + + { + "{{$.Name}}", + ProcHook::INSTANCE, + + {{$ext := GetAnnotation $ "extension"}} + {{if $ext}} + ProcHook::{{Macro "BaseName" $ext}}, + + {{if (Macro "IsExtensionInternal" $ext)}} + nullptr, + nullptr, + nullptr, + {{else}} + reinterpret_cast({{$base}}_Bottom), + reinterpret_cast(disabled{{$base}}), + nullptr, + {{end}} + {{else}} + ProcHook::EXTENSION_CORE, + + {{if eq $.Name "vkGetInstanceProcAddr"}} + reinterpret_cast({{$base}}), + {{else}} + reinterpret_cast({{$base}}_Bottom), + {{end}} + nullptr, + nullptr, + {{end}} + }, +{{end}} + + +{{/* +------------------------------------------------------------------------------- + Emits definition of a device ProcHook. +------------------------------------------------------------------------------- +*/}} +{{define "driver.C++.DefineDeviceProcHook"}} + {{AssertType $ "Function"}} + + {{$base := (Macro "BaseName" $)}} + + { + "{{$.Name}}", + ProcHook::DEVICE, + + {{$ext := GetAnnotation $ "extension"}} + {{if $ext}} + ProcHook::{{Macro "BaseName" $ext}}, + + {{if (Macro "IsExtensionInternal" $ext)}} + nullptr, + nullptr, + nullptr, + {{else}} + reinterpret_cast({{$base}}_Bottom), + reinterpret_cast(disabled{{$base}}), + reinterpret_cast(checked{{$base}}), + {{end}} + {{else}} + ProcHook::EXTENSION_CORE, + + {{if eq $.Name "vkGetDeviceProcAddr"}} + reinterpret_cast({{$base}}), + {{else}} + reinterpret_cast({{$base}}_Bottom), + {{end}} + nullptr, + nullptr, + {{end}} + }, +{{end}} + + {{/* ------------------------------------------------------------------------------- Emits a function/extension name without the "vk"/"VK_" prefix. @@ -517,3 +894,16 @@ bool InitDispatchTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) { {{else if eq $ext "VK_KHR_android_surface"}}true {{end}} {{end}} + + +{{/* +------------------------------------------------------------------------------ + Reports whether an extension is internal to the loader and drivers, + so the loader should not enumerate it. +------------------------------------------------------------------------------ +*/}} +{{define "IsExtensionInternal"}} + {{$ext := index $.Arguments 0}} + {{ if eq $ext "VK_ANDROID_native_buffer"}}true + {{end}} +{{end}} diff --git a/vulkan/libvulkan/dispatch.tmpl b/vulkan/libvulkan/dispatch.tmpl index 67ead4a055..fd778790bf 100644 --- a/vulkan/libvulkan/dispatch.tmpl +++ b/vulkan/libvulkan/dispatch.tmpl @@ -118,47 +118,8 @@ struct DriverDispatchTable {« ¶ using namespace vulkan; ¶ -namespace { -¶ -struct NameProc { - const char* name; - PFN_vkVoidFunction proc; -}; -¶ -PFN_vkVoidFunction Lookup(const char* name, const NameProc* begin, const NameProc* end) { - const auto& entry = std::lower_bound( - begin, end, name, - [](const NameProc& e, const char* n) { return strcmp(e.name, n) < 0; }); - if (entry == end || strcmp(entry->name, name) != 0) - return nullptr; - return entry->proc; -} -¶ -template -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(§ - static_cast<{{Macro "FunctionPtrName" $f}}>(§ - {{Macro "BaseName" $f}}_Bottom))}, - {{end}} - {{end}} - // clang-format on -»}; -¶ -} // anonymous namespace -¶ namespace vulkan { ¶ -PFN_vkVoidFunction GetLoaderBottomProcAddr(const char* name) { - return Lookup(name, kLoaderBottomProcs); -} -¶ bool LoadDriverDispatchTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc_addr, const InstanceExtensionSet& extensions, diff --git a/vulkan/libvulkan/dispatch_gen.cpp b/vulkan/libvulkan/dispatch_gen.cpp index eacf1a1094..fa199bd25c 100644 --- a/vulkan/libvulkan/dispatch_gen.cpp +++ b/vulkan/libvulkan/dispatch_gen.cpp @@ -24,74 +24,8 @@ using namespace vulkan; -namespace { - -struct NameProc { - const char* name; - PFN_vkVoidFunction proc; -}; - -PFN_vkVoidFunction Lookup(const char* name, - const NameProc* begin, - const NameProc* end) { - const auto& entry = std::lower_bound( - begin, end, name, - [](const NameProc& e, const char* n) { return strcmp(e.name, n) < 0; }); - if (entry == end || strcmp(entry->name, name) != 0) - return nullptr; - return entry->proc; -} - -template -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(static_cast(AcquireNextImageKHR_Bottom))}, - {"vkAllocateCommandBuffers", reinterpret_cast(static_cast(AllocateCommandBuffers_Bottom))}, - {"vkCreateAndroidSurfaceKHR", reinterpret_cast(static_cast(CreateAndroidSurfaceKHR_Bottom))}, - {"vkCreateDebugReportCallbackEXT", reinterpret_cast(static_cast(CreateDebugReportCallbackEXT_Bottom))}, - {"vkCreateDevice", reinterpret_cast(static_cast(CreateDevice_Bottom))}, - {"vkCreateInstance", reinterpret_cast(static_cast(CreateInstance_Bottom))}, - {"vkCreateSwapchainKHR", reinterpret_cast(static_cast(CreateSwapchainKHR_Bottom))}, - {"vkDebugReportMessageEXT", reinterpret_cast(static_cast(DebugReportMessageEXT_Bottom))}, - {"vkDestroyDebugReportCallbackEXT", reinterpret_cast(static_cast(DestroyDebugReportCallbackEXT_Bottom))}, - {"vkDestroyDevice", reinterpret_cast(static_cast(DestroyDevice_Bottom))}, - {"vkDestroyInstance", reinterpret_cast(static_cast(DestroyInstance_Bottom))}, - {"vkDestroySurfaceKHR", reinterpret_cast(static_cast(DestroySurfaceKHR_Bottom))}, - {"vkDestroySwapchainKHR", reinterpret_cast(static_cast(DestroySwapchainKHR_Bottom))}, - {"vkEnumerateDeviceExtensionProperties", reinterpret_cast(static_cast(EnumerateDeviceExtensionProperties_Bottom))}, - {"vkEnumerateDeviceLayerProperties", reinterpret_cast(static_cast(EnumerateDeviceLayerProperties_Bottom))}, - {"vkEnumeratePhysicalDevices", reinterpret_cast(static_cast(EnumeratePhysicalDevices_Bottom))}, - {"vkGetDeviceProcAddr", reinterpret_cast(static_cast(GetDeviceProcAddr_Bottom))}, - {"vkGetDeviceQueue", reinterpret_cast(static_cast(GetDeviceQueue_Bottom))}, - {"vkGetInstanceProcAddr", reinterpret_cast(static_cast(GetInstanceProcAddr_Bottom))}, - {"vkGetPhysicalDeviceFeatures", reinterpret_cast(static_cast(GetPhysicalDeviceFeatures_Bottom))}, - {"vkGetPhysicalDeviceFormatProperties", reinterpret_cast(static_cast(GetPhysicalDeviceFormatProperties_Bottom))}, - {"vkGetPhysicalDeviceImageFormatProperties", reinterpret_cast(static_cast(GetPhysicalDeviceImageFormatProperties_Bottom))}, - {"vkGetPhysicalDeviceMemoryProperties", reinterpret_cast(static_cast(GetPhysicalDeviceMemoryProperties_Bottom))}, - {"vkGetPhysicalDeviceProperties", reinterpret_cast(static_cast(GetPhysicalDeviceProperties_Bottom))}, - {"vkGetPhysicalDeviceQueueFamilyProperties", reinterpret_cast(static_cast(GetPhysicalDeviceQueueFamilyProperties_Bottom))}, - {"vkGetPhysicalDeviceSparseImageFormatProperties", reinterpret_cast(static_cast(GetPhysicalDeviceSparseImageFormatProperties_Bottom))}, - {"vkGetPhysicalDeviceSurfaceCapabilitiesKHR", reinterpret_cast(static_cast(GetPhysicalDeviceSurfaceCapabilitiesKHR_Bottom))}, - {"vkGetPhysicalDeviceSurfaceFormatsKHR", reinterpret_cast(static_cast(GetPhysicalDeviceSurfaceFormatsKHR_Bottom))}, - {"vkGetPhysicalDeviceSurfacePresentModesKHR", reinterpret_cast(static_cast(GetPhysicalDeviceSurfacePresentModesKHR_Bottom))}, - {"vkGetPhysicalDeviceSurfaceSupportKHR", reinterpret_cast(static_cast(GetPhysicalDeviceSurfaceSupportKHR_Bottom))}, - {"vkGetSwapchainImagesKHR", reinterpret_cast(static_cast(GetSwapchainImagesKHR_Bottom))}, - {"vkQueuePresentKHR", reinterpret_cast(static_cast(QueuePresentKHR_Bottom))}, - // clang-format on -}; - -} // anonymous namespace - namespace vulkan { -PFN_vkVoidFunction GetLoaderBottomProcAddr(const char* name) { - return Lookup(name, kLoaderBottomProcs); -} - bool LoadDriverDispatchTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc_addr, const InstanceExtensionSet& extensions, diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index 4acc867201..68ae5c8314 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -143,5 +143,67 @@ const VkAllocationCallbacks& GetDefaultAllocator() { return kDefaultAllocCallbacks; } +PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) { + const ProcHook* hook = GetProcHook(pName); + if (!hook) + return g_hwdevice->GetInstanceProcAddr(instance, pName); + + if (!instance) { + if (hook->type == ProcHook::GLOBAL) + return hook->proc; + + ALOGE( + "Invalid use of vkGetInstanceProcAddr to query %s without an " + "instance", + pName); + + // Some naughty layers expect + // + // vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateDevice"); + // + // to work. + return (strcmp(pName, "vkCreateDevice") == 0) ? hook->proc : nullptr; + } + + PFN_vkVoidFunction proc; + + switch (hook->type) { + case ProcHook::INSTANCE: + proc = (GetData(instance).hook_extensions[hook->extension]) + ? hook->proc + : hook->disabled_proc; + break; + case ProcHook::DEVICE: + proc = (hook->extension == ProcHook::EXTENSION_CORE) + ? hook->proc + : hook->checked_proc; + break; + default: + ALOGE( + "Invalid use of vkGetInstanceProcAddr to query %s with an " + "instance", + pName); + proc = nullptr; + break; + } + + return proc; +} + +PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) { + const ProcHook* hook = GetProcHook(pName); + if (!hook) + return GetData(device).get_device_proc_addr(device, pName); + + if (hook->type != ProcHook::DEVICE) { + ALOGE("Invalid use of vkGetDeviceProcAddr to query %s", pName); + return nullptr; + } + + return (GetData(device).hook_extensions[hook->extension]) + ? hook->proc + : hook->disabled_proc; +} + } // namespace driver } // namespace vulkan diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h index de9d1c65a0..28b0ce6cde 100644 --- a/vulkan/libvulkan/driver.h +++ b/vulkan/libvulkan/driver.h @@ -18,6 +18,7 @@ #define LIBVULKAN_DRIVER_H 1 #include +#include #include #include @@ -25,6 +26,7 @@ #include #include "api_gen.h" +#include "driver_gen.h" namespace vulkan { @@ -61,15 +63,35 @@ struct DeviceData { namespace driver { struct InstanceData { + InstanceData(const VkAllocationCallbacks& alloc) + : opaque_api_data(), allocator(alloc) { + hook_extensions.set(ProcHook::EXTENSION_CORE); + hal_extensions.set(ProcHook::EXTENSION_CORE); + } + api::InstanceData opaque_api_data; const VkAllocationCallbacks allocator; + + std::bitset hook_extensions; + std::bitset hal_extensions; }; struct DeviceData { + DeviceData(const VkAllocationCallbacks& alloc) + : opaque_api_data(), allocator(alloc), get_device_proc_addr(nullptr) { + hook_extensions.set(ProcHook::EXTENSION_CORE); + hal_extensions.set(ProcHook::EXTENSION_CORE); + } + api::DeviceData opaque_api_data; const VkAllocationCallbacks allocator; + + std::bitset hook_extensions; + std::bitset hal_extensions; + + PFN_vkGetDeviceProcAddr get_device_proc_addr; }; bool Debuggable(); diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp new file mode 100644 index 0000000000..d725df5a62 --- /dev/null +++ b/vulkan/libvulkan/driver_gen.cpp @@ -0,0 +1,376 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// WARNING: This file is generated. See ../README.md for instructions. + +#include +#include +#include + +#include "driver.h" +#include "loader.h" + +namespace vulkan { +namespace driver { + +namespace { + +// clang-format off + +VKAPI_ATTR void disabledDestroySurfaceKHR(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks*) { + ALOGE("VK_KHR_surface not enabled. vkDestroySurfaceKHR not executed."); +} + +VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice, uint32_t, VkSurfaceKHR, VkBool32*) { + ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceSupportKHR not executed."); + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice, VkSurfaceKHR, VkSurfaceCapabilitiesKHR*) { + ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceCapabilitiesKHR not executed."); + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice, VkSurfaceKHR, uint32_t*, VkSurfaceFormatKHR*) { + ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceFormatsKHR not executed."); + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult disabledGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice, VkSurfaceKHR, uint32_t*, VkPresentModeKHR*) { + ALOGE("VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfacePresentModesKHR not executed."); + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult disabledCreateSwapchainKHR(VkDevice, const VkSwapchainCreateInfoKHR*, const VkAllocationCallbacks*, VkSwapchainKHR*) { + ALOGE("VK_KHR_swapchain not enabled. vkCreateSwapchainKHR not executed."); + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult checkedCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain) { + return (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) ? CreateSwapchainKHR_Bottom(device, pCreateInfo, pAllocator, pSwapchain) : disabledCreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain); +} + +VKAPI_ATTR void disabledDestroySwapchainKHR(VkDevice, VkSwapchainKHR, const VkAllocationCallbacks*) { + ALOGE("VK_KHR_swapchain not enabled. vkDestroySwapchainKHR not executed."); +} + +VKAPI_ATTR void checkedDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator) { + (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) ? DestroySwapchainKHR_Bottom(device, swapchain, pAllocator) : disabledDestroySwapchainKHR(device, swapchain, pAllocator); +} + +VKAPI_ATTR VkResult disabledGetSwapchainImagesKHR(VkDevice, VkSwapchainKHR, uint32_t*, VkImage*) { + ALOGE("VK_KHR_swapchain not enabled. vkGetSwapchainImagesKHR not executed."); + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult checkedGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages) { + return (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) ? GetSwapchainImagesKHR_Bottom(device, swapchain, pSwapchainImageCount, pSwapchainImages) : disabledGetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages); +} + +VKAPI_ATTR VkResult disabledAcquireNextImageKHR(VkDevice, VkSwapchainKHR, uint64_t, VkSemaphore, VkFence, uint32_t*) { + ALOGE("VK_KHR_swapchain not enabled. vkAcquireNextImageKHR not executed."); + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult checkedAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex) { + return (GetData(device).hook_extensions[ProcHook::KHR_swapchain]) ? AcquireNextImageKHR_Bottom(device, swapchain, timeout, semaphore, fence, pImageIndex) : disabledAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex); +} + +VKAPI_ATTR VkResult disabledQueuePresentKHR(VkQueue, const VkPresentInfoKHR*) { + ALOGE("VK_KHR_swapchain not enabled. vkQueuePresentKHR not executed."); + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult checkedQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPresentInfo) { + return (GetData(queue).hook_extensions[ProcHook::KHR_swapchain]) ? QueuePresentKHR_Bottom(queue, pPresentInfo) : disabledQueuePresentKHR(queue, pPresentInfo); +} + +VKAPI_ATTR VkResult disabledCreateAndroidSurfaceKHR(VkInstance, const VkAndroidSurfaceCreateInfoKHR*, const VkAllocationCallbacks*, VkSurfaceKHR*) { + ALOGE("VK_KHR_android_surface not enabled. vkCreateAndroidSurfaceKHR not executed."); + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult disabledCreateDebugReportCallbackEXT(VkInstance, const VkDebugReportCallbackCreateInfoEXT*, const VkAllocationCallbacks*, VkDebugReportCallbackEXT*) { + ALOGE("VK_EXT_debug_report not enabled. vkCreateDebugReportCallbackEXT not executed."); + return VK_SUCCESS; +} + +VKAPI_ATTR void disabledDestroyDebugReportCallbackEXT(VkInstance, VkDebugReportCallbackEXT, const VkAllocationCallbacks*) { + ALOGE("VK_EXT_debug_report not enabled. vkDestroyDebugReportCallbackEXT not executed."); +} + +VKAPI_ATTR void disabledDebugReportMessageEXT(VkInstance, VkDebugReportFlagsEXT, VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t, const char*, const char*) { + ALOGE("VK_EXT_debug_report not enabled. vkDebugReportMessageEXT not executed."); +} + +// clang-format on + +const ProcHook g_proc_hooks[] = { + // clang-format off + { + "vkAcquireImageANDROID", + ProcHook::DEVICE, + ProcHook::ANDROID_native_buffer, + nullptr, + nullptr, + nullptr, + }, + { + "vkAcquireNextImageKHR", + ProcHook::DEVICE, + ProcHook::KHR_swapchain, + reinterpret_cast(AcquireNextImageKHR_Bottom), + reinterpret_cast(disabledAcquireNextImageKHR), + reinterpret_cast(checkedAcquireNextImageKHR), + }, + { + "vkAllocateCommandBuffers", + ProcHook::DEVICE, + ProcHook::EXTENSION_CORE, + reinterpret_cast(AllocateCommandBuffers_Bottom), + nullptr, + nullptr, + }, + { + "vkCreateAndroidSurfaceKHR", + ProcHook::INSTANCE, + ProcHook::KHR_android_surface, + reinterpret_cast(CreateAndroidSurfaceKHR_Bottom), + reinterpret_cast(disabledCreateAndroidSurfaceKHR), + nullptr, + }, + { + "vkCreateDebugReportCallbackEXT", + ProcHook::INSTANCE, + ProcHook::EXT_debug_report, + reinterpret_cast(CreateDebugReportCallbackEXT_Bottom), + reinterpret_cast(disabledCreateDebugReportCallbackEXT), + nullptr, + }, + { + "vkCreateDevice", + ProcHook::INSTANCE, + ProcHook::EXTENSION_CORE, + reinterpret_cast(CreateDevice_Bottom), + nullptr, + nullptr, + }, + { + "vkCreateInstance", + ProcHook::GLOBAL, + ProcHook::EXTENSION_CORE, + reinterpret_cast(CreateInstance_Bottom), + nullptr, + nullptr, + }, + { + "vkCreateSwapchainKHR", + ProcHook::DEVICE, + ProcHook::KHR_swapchain, + reinterpret_cast(CreateSwapchainKHR_Bottom), + reinterpret_cast(disabledCreateSwapchainKHR), + reinterpret_cast(checkedCreateSwapchainKHR), + }, + { + "vkDebugReportMessageEXT", + ProcHook::INSTANCE, + ProcHook::EXT_debug_report, + reinterpret_cast(DebugReportMessageEXT_Bottom), + reinterpret_cast(disabledDebugReportMessageEXT), + nullptr, + }, + { + "vkDestroyDebugReportCallbackEXT", + ProcHook::INSTANCE, + ProcHook::EXT_debug_report, + reinterpret_cast(DestroyDebugReportCallbackEXT_Bottom), + reinterpret_cast(disabledDestroyDebugReportCallbackEXT), + nullptr, + }, + { + "vkDestroyDevice", + ProcHook::DEVICE, + ProcHook::EXTENSION_CORE, + reinterpret_cast(DestroyDevice_Bottom), + nullptr, + nullptr, + }, + { + "vkDestroyInstance", + ProcHook::INSTANCE, + ProcHook::EXTENSION_CORE, + reinterpret_cast(DestroyInstance_Bottom), + nullptr, + nullptr, + }, + { + "vkDestroySurfaceKHR", + ProcHook::INSTANCE, + ProcHook::KHR_surface, + reinterpret_cast(DestroySurfaceKHR_Bottom), + reinterpret_cast(disabledDestroySurfaceKHR), + nullptr, + }, + { + "vkDestroySwapchainKHR", + ProcHook::DEVICE, + ProcHook::KHR_swapchain, + reinterpret_cast(DestroySwapchainKHR_Bottom), + reinterpret_cast(disabledDestroySwapchainKHR), + reinterpret_cast(checkedDestroySwapchainKHR), + }, + { + "vkEnumerateDeviceExtensionProperties", + ProcHook::INSTANCE, + ProcHook::EXTENSION_CORE, + reinterpret_cast(EnumerateDeviceExtensionProperties_Bottom), + nullptr, + nullptr, + }, + { + "vkEnumerateInstanceExtensionProperties", + ProcHook::GLOBAL, + ProcHook::EXTENSION_CORE, + reinterpret_cast(EnumerateInstanceExtensionProperties), + nullptr, + nullptr, + }, + { + "vkEnumeratePhysicalDevices", + ProcHook::INSTANCE, + ProcHook::EXTENSION_CORE, + reinterpret_cast(EnumeratePhysicalDevices_Bottom), + nullptr, + nullptr, + }, + { + "vkGetDeviceProcAddr", + ProcHook::DEVICE, + ProcHook::EXTENSION_CORE, + reinterpret_cast(GetDeviceProcAddr), + nullptr, + nullptr, + }, + { + "vkGetDeviceQueue", + ProcHook::DEVICE, + ProcHook::EXTENSION_CORE, + reinterpret_cast(GetDeviceQueue_Bottom), + nullptr, + nullptr, + }, + { + "vkGetInstanceProcAddr", + ProcHook::INSTANCE, + ProcHook::EXTENSION_CORE, + reinterpret_cast(GetInstanceProcAddr), + nullptr, + nullptr, + }, + { + "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", + ProcHook::INSTANCE, + ProcHook::KHR_surface, + reinterpret_cast(GetPhysicalDeviceSurfaceCapabilitiesKHR_Bottom), + reinterpret_cast(disabledGetPhysicalDeviceSurfaceCapabilitiesKHR), + nullptr, + }, + { + "vkGetPhysicalDeviceSurfaceFormatsKHR", + ProcHook::INSTANCE, + ProcHook::KHR_surface, + reinterpret_cast(GetPhysicalDeviceSurfaceFormatsKHR_Bottom), + reinterpret_cast(disabledGetPhysicalDeviceSurfaceFormatsKHR), + nullptr, + }, + { + "vkGetPhysicalDeviceSurfacePresentModesKHR", + ProcHook::INSTANCE, + ProcHook::KHR_surface, + reinterpret_cast(GetPhysicalDeviceSurfacePresentModesKHR_Bottom), + reinterpret_cast(disabledGetPhysicalDeviceSurfacePresentModesKHR), + nullptr, + }, + { + "vkGetPhysicalDeviceSurfaceSupportKHR", + ProcHook::INSTANCE, + ProcHook::KHR_surface, + reinterpret_cast(GetPhysicalDeviceSurfaceSupportKHR_Bottom), + reinterpret_cast(disabledGetPhysicalDeviceSurfaceSupportKHR), + nullptr, + }, + { + "vkGetSwapchainGrallocUsageANDROID", + ProcHook::DEVICE, + ProcHook::ANDROID_native_buffer, + nullptr, + nullptr, + nullptr, + }, + { + "vkGetSwapchainImagesKHR", + ProcHook::DEVICE, + ProcHook::KHR_swapchain, + reinterpret_cast(GetSwapchainImagesKHR_Bottom), + reinterpret_cast(disabledGetSwapchainImagesKHR), + reinterpret_cast(checkedGetSwapchainImagesKHR), + }, + { + "vkQueuePresentKHR", + ProcHook::DEVICE, + ProcHook::KHR_swapchain, + reinterpret_cast(QueuePresentKHR_Bottom), + reinterpret_cast(disabledQueuePresentKHR), + reinterpret_cast(checkedQueuePresentKHR), + }, + { + "vkQueueSignalReleaseImageANDROID", + ProcHook::DEVICE, + ProcHook::ANDROID_native_buffer, + nullptr, + nullptr, + nullptr, + }, + // clang-format on +}; + +} // anonymous + +const ProcHook* GetProcHook(const char* name) { + const auto& begin = g_proc_hooks; + const auto& end = + g_proc_hooks + sizeof(g_proc_hooks) / sizeof(g_proc_hooks[0]); + const auto hook = std::lower_bound( + begin, end, name, + [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; }); + return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr; +} + +ProcHook::Extension GetProcHookExtension(const char* name) { + // clang-format off + if (strcmp(name, "VK_ANDROID_native_buffer") == 0) return ProcHook::ANDROID_native_buffer; + if (strcmp(name, "VK_EXT_debug_report") == 0) return ProcHook::EXT_debug_report; + if (strcmp(name, "VK_KHR_android_surface") == 0) return ProcHook::KHR_android_surface; + if (strcmp(name, "VK_KHR_surface") == 0) return ProcHook::KHR_surface; + if (strcmp(name, "VK_KHR_swapchain") == 0) return ProcHook::KHR_swapchain; + // clang-format on + return ProcHook::EXTENSION_UNKNOWN; +} + +} // namespace driver +} // namespace vulkan + +// clang-format on diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h new file mode 100644 index 0000000000..63dadcbdb3 --- /dev/null +++ b/vulkan/libvulkan/driver_gen.h @@ -0,0 +1,61 @@ +/* + * Copyright 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// WARNING: This file is generated. See ../README.md for instructions. + +#ifndef LIBVULKAN_DRIVER_GEN_H +#define LIBVULKAN_DRIVER_GEN_H + +#include +#include + +namespace vulkan { +namespace driver { + +struct ProcHook { + enum Type { + GLOBAL, + INSTANCE, + DEVICE, + }; + enum Extension { + ANDROID_native_buffer, + EXT_debug_report, + KHR_android_surface, + KHR_surface, + KHR_swapchain, + + EXTENSION_CORE, // valid bit + EXTENSION_COUNT, + EXTENSION_UNKNOWN, + }; + + const char* name; + Type type; + Extension extension; + + PFN_vkVoidFunction proc; + PFN_vkVoidFunction disabled_proc; // nullptr for global hooks + PFN_vkVoidFunction checked_proc; // nullptr for global/instance hooks +}; + +const ProcHook* GetProcHook(const char* name); +ProcHook::Extension GetProcHookExtension(const char* name); + +} // namespace driver +} // namespace vulkan + +#endif // LIBVULKAN_DRIVER_TABLE_H diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp index 2d48fda688..8c68efa70a 100644 --- a/vulkan/libvulkan/loader.cpp +++ b/vulkan/libvulkan/loader.cpp @@ -142,7 +142,7 @@ bool LoadVulkanHAL() { struct Instance { Instance(const VkAllocationCallbacks* alloc_callbacks) - : base{{}, *alloc_callbacks}, + : base(*alloc_callbacks), alloc(&base.allocator), num_physical_devices(0) { memset(physical_devices, 0, sizeof(physical_devices)); @@ -169,15 +169,13 @@ struct Instance { }; struct Device { - Device(Instance* instance_) - : base{{}, *instance_->alloc}, instance(instance_) { + Device(Instance* instance_) : base(*instance_->alloc), instance(instance_) { enabled_extensions.reset(); } driver::DeviceData base; Instance* instance; - PFN_vkGetDeviceProcAddr get_device_proc_addr; DeviceExtensionSet enabled_extensions; }; @@ -272,6 +270,32 @@ void DestroyInstance(Instance* instance, allocator->pfnFree(allocator->pUserData, instance); } +driver::ProcHook::Extension InstanceExtensionToProcHookExtension( + InstanceExtension id) { + switch (id) { + case kKHR_surface: + return driver::ProcHook::KHR_surface; + case kKHR_android_surface: + return driver::ProcHook::KHR_android_surface; + case kEXT_debug_report: + return driver::ProcHook::EXT_debug_report; + default: + return driver::ProcHook::EXTENSION_UNKNOWN; + } +} + +driver::ProcHook::Extension DeviceExtensionToProcHookExtension( + DeviceExtension id) { + switch (id) { + case kKHR_swapchain: + return driver::ProcHook::KHR_swapchain; + case kANDROID_native_buffer: + return driver::ProcHook::ANDROID_native_buffer; + default: + return driver::ProcHook::EXTENSION_UNKNOWN; + } +} + } // anonymous namespace namespace vulkan { @@ -297,6 +321,7 @@ VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, // Check that all enabled extensions are supported uint32_t num_driver_extensions = 0; + bool enable_kEXT_debug_report = false; for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) { const char* name = create_info->ppEnabledExtensionNames[i]; InstanceExtension id = InstanceExtensionFromName(name); @@ -312,11 +337,27 @@ VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, } // The loader natively supports debug report. if (id == kEXT_debug_report) { + enable_kEXT_debug_report = true; continue; } } } + auto& hal_exts = instance.base.hal_extensions; + for (size_t i = 0; i < instance.enabled_extensions.size(); i++) { + if (instance.enabled_extensions[i]) { + auto bit = InstanceExtensionToProcHookExtension( + static_cast(i)); + if (bit != driver::ProcHook::EXTENSION_UNKNOWN) + hal_exts.set(bit); + } + } + + auto& hook_exts = instance.base.hook_extensions; + hook_exts = hal_exts; + if (enable_kEXT_debug_report) + hook_exts.set(driver::ProcHook::EXT_debug_report); + VkInstanceCreateInfo driver_create_info = *create_info; driver_create_info.pNext = StripCreateExtensions(create_info->pNext); driver_create_info.enabledLayerCount = 0; @@ -430,111 +471,6 @@ VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, return VK_SUCCESS; } -VkResult CreateAndroidSurfaceKHR_Disabled(VkInstance, - const VkAndroidSurfaceCreateInfoKHR*, - const VkAllocationCallbacks*, - VkSurfaceKHR*) { - ALOGE( - "VK_KHR_android_surface not enabled. vkCreateAndroidSurfaceKHR not " - "executed."); - - return VK_SUCCESS; -} - -void DestroySurfaceKHR_Disabled(VkInstance, - VkSurfaceKHR, - const VkAllocationCallbacks*) { - ALOGE("VK_KHR_surface not enabled. vkDestroySurfaceKHR not executed."); -} - -VkResult GetPhysicalDeviceSurfaceSupportKHR_Disabled(VkPhysicalDevice, - uint32_t, - VkSurfaceKHR, - VkBool32*) { - ALOGE( - "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceSupportKHR not " - "executed."); - - return VK_SUCCESS; -} - -VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR_Disabled( - VkPhysicalDevice, - VkSurfaceKHR, - VkSurfaceCapabilitiesKHR*) { - ALOGE( - "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceapabilitiesKHR " - "not executed."); - - return VK_SUCCESS; -} - -VkResult GetPhysicalDeviceSurfaceFormatsKHR_Disabled(VkPhysicalDevice, - VkSurfaceKHR, - uint32_t*, - VkSurfaceFormatKHR*) { - ALOGE( - "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfaceFormatsKHR not " - "executed."); - - return VK_SUCCESS; -} - -VkResult GetPhysicalDeviceSurfacePresentModesKHR_Disabled(VkPhysicalDevice, - VkSurfaceKHR, - uint32_t*, - VkPresentModeKHR*) { - ALOGE( - "VK_KHR_surface not enabled. vkGetPhysicalDeviceSurfacePresentModesKHR " - "not executed."); - - return VK_SUCCESS; -} - -PFN_vkVoidFunction GetInstanceProcAddr_Bottom(VkInstance vkinstance, - const char* name) { - PFN_vkVoidFunction pfn; - - if (vkinstance) { - Instance& instance = GetDispatchParent(vkinstance); - if (!instance.enabled_extensions[kKHR_android_surface]) { - // KHR_android_surface is not enabled, use error stubs instead - if (strcmp(name, "vkCreateAndroidSurfaceKHR") == 0) { - return reinterpret_cast( - 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( - DestroySurfaceKHR_Disabled); - } - if (strcmp(name, "vkGetPhysicalDeviceSurfaceSupportKHR") == 0) { - return reinterpret_cast( - GetPhysicalDeviceSurfaceSupportKHR_Disabled); - } - if (strcmp(name, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR") == - 0) { - return reinterpret_cast( - GetPhysicalDeviceSurfaceCapabilitiesKHR_Disabled); - } - if (strcmp(name, "vkGetPhysicalDeviceSurfaceFormatsKHR") == 0) { - return reinterpret_cast( - GetPhysicalDeviceSurfaceFormatsKHR_Disabled); - } - if (strcmp(name, "vkGetPhysicalDeviceSurfacePresentModesKHR") == - 0) { - return reinterpret_cast( - GetPhysicalDeviceSurfacePresentModesKHR_Disabled); - } - } - } - if ((pfn = GetLoaderBottomProcAddr(name))) - return pfn; - return g_hwdevice->GetInstanceProcAddr(vkinstance, name); -} - VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance, uint32_t* pdev_count, VkPhysicalDevice* pdevs) { @@ -549,69 +485,6 @@ VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance, return VK_SUCCESS; } -void GetPhysicalDeviceProperties_Bottom( - VkPhysicalDevice pdev, - VkPhysicalDeviceProperties* properties) { - GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceProperties( - pdev, properties); -} - -void GetPhysicalDeviceFeatures_Bottom(VkPhysicalDevice pdev, - VkPhysicalDeviceFeatures* features) { - GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFeatures(pdev, - features); -} - -void GetPhysicalDeviceMemoryProperties_Bottom( - VkPhysicalDevice pdev, - VkPhysicalDeviceMemoryProperties* properties) { - GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceMemoryProperties( - pdev, properties); -} - -void GetPhysicalDeviceQueueFamilyProperties_Bottom( - VkPhysicalDevice pdev, - uint32_t* pCount, - VkQueueFamilyProperties* properties) { - GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceQueueFamilyProperties( - pdev, pCount, properties); -} - -void GetPhysicalDeviceFormatProperties_Bottom(VkPhysicalDevice pdev, - VkFormat format, - VkFormatProperties* properties) { - GetDispatchParent(pdev).drv.dispatch.GetPhysicalDeviceFormatProperties( - pdev, format, properties); -} - -VkResult GetPhysicalDeviceImageFormatProperties_Bottom( - VkPhysicalDevice pdev, - VkFormat format, - VkImageType type, - VkImageTiling tiling, - VkImageUsageFlags usage, - VkImageCreateFlags flags, - VkImageFormatProperties* properties) { - return GetDispatchParent(pdev) - .drv.dispatch.GetPhysicalDeviceImageFormatProperties( - pdev, format, type, tiling, usage, flags, properties); -} - -void GetPhysicalDeviceSparseImageFormatProperties_Bottom( - VkPhysicalDevice pdev, - VkFormat format, - VkImageType type, - VkSampleCountFlagBits samples, - VkImageUsageFlags usage, - VkImageTiling tiling, - uint32_t* properties_count, - VkSparseImageFormatProperties* properties) { - GetDispatchParent(pdev) - .drv.dispatch.GetPhysicalDeviceSparseImageFormatProperties( - pdev, format, type, samples, usage, tiling, properties_count, - properties); -} - VKAPI_ATTR VkResult EnumerateDeviceExtensionProperties_Bottom( VkPhysicalDevice pdev, @@ -646,16 +519,6 @@ VkResult EnumerateDeviceExtensionProperties_Bottom( return *properties_count < num_extensions ? VK_INCOMPLETE : VK_SUCCESS; } -// This is a no-op, the Top function returns the aggregate layer property -// data. This is to keep the dispatch generator happy. -VKAPI_ATTR -VkResult EnumerateDeviceLayerProperties_Bottom( - VkPhysicalDevice /*pdev*/, - uint32_t* /*properties_count*/, - VkLayerProperties* /*properties*/) { - return VK_SUCCESS; -} - VKAPI_ATTR VkResult CreateDevice_Bottom(VkPhysicalDevice gpu, const VkDeviceCreateInfo* create_info, @@ -710,6 +573,26 @@ VkResult CreateDevice_Bottom(VkPhysicalDevice gpu, } } + // Unlike instance->enabled_extensions, device->enabled_extensions maps to + // hook extensions. + auto& hook_exts = device->base.hook_extensions; + for (size_t i = 0; i < device->enabled_extensions.size(); i++) { + if (device->enabled_extensions[i]) { + auto bit = DeviceExtensionToProcHookExtension( + static_cast(i)); + if (bit != driver::ProcHook::EXTENSION_UNKNOWN) + hook_exts.set(bit); + } + } + + auto& hal_exts = device->base.hal_extensions; + hal_exts = hook_exts; + // map VK_KHR_swapchain to VK_ANDROID_native_buffer + if (hal_exts[driver::ProcHook::KHR_swapchain]) { + hal_exts.reset(driver::ProcHook::KHR_swapchain); + hal_exts.set(driver::ProcHook::ANDROID_native_buffer); + } + driver_create_info.enabledExtensionCount = num_driver_extensions; driver_create_info.ppEnabledExtensionNames = driver_extensions; VkDevice drv_device; @@ -725,9 +608,11 @@ VkResult CreateDevice_Bottom(VkPhysicalDevice gpu, return VK_ERROR_INITIALIZATION_FAILED; } - device->get_device_proc_addr = reinterpret_cast( - instance.drv.dispatch.GetDeviceProcAddr(drv_device, - "vkGetDeviceProcAddr")); + device->base.get_device_proc_addr = + reinterpret_cast( + instance.drv.dispatch.GetDeviceProcAddr(drv_device, + "vkGetDeviceProcAddr")); + *device_out = drv_device; return VK_SUCCESS; } @@ -745,91 +630,6 @@ void DestroyInstance_Bottom(VkInstance vkinstance, DestroyInstance(&instance, allocator, vkinstance); } -VkResult CreateSwapchainKHR_Disabled(VkDevice, - const VkSwapchainCreateInfoKHR*, - const VkAllocationCallbacks*, - VkSwapchainKHR*) { - ALOGE("VK_KHR_swapchain not enabled. vkCreateSwapchainKHR not executed."); - - return VK_SUCCESS; -} - -void DestroySwapchainKHR_Disabled(VkDevice, - VkSwapchainKHR, - const VkAllocationCallbacks*) { - ALOGE("VK_KHR_swapchain not enabled. vkDestroySwapchainKHR not executed."); -} - -VkResult GetSwapchainImagesKHR_Disabled(VkDevice, - VkSwapchainKHR, - uint32_t*, - VkImage*) { - ALOGE( - "VK_KHR_swapchain not enabled. vkGetSwapchainImagesKHR not executed."); - - return VK_SUCCESS; -} - -VkResult AcquireNextImageKHR_Disabled(VkDevice, - VkSwapchainKHR, - uint64_t, - VkSemaphore, - VkFence, - uint32_t*) { - ALOGE("VK_KHR_swapchain not enabled. vkAcquireNextImageKHR not executed."); - - return VK_SUCCESS; -} - -VkResult QueuePresentKHR_Disabled(VkQueue, const VkPresentInfoKHR*) { - ALOGE("VK_KHR_swapchain not enabled. vkQueuePresentKHR not executed."); - - return VK_SUCCESS; -} - -PFN_vkVoidFunction GetDeviceProcAddr_Bottom(VkDevice vkdevice, - const char* name) { - if (strcmp(name, "vkCreateDevice") == 0) { - return reinterpret_cast(CreateDevice_Bottom); - } - - Device& device = GetDispatchParent(vkdevice); - if (!device.enabled_extensions[kKHR_swapchain]) { - if (strcmp(name, "vkCreateSwapchainKHR") == 0) { - return reinterpret_cast( - CreateSwapchainKHR_Disabled); - } - if (strcmp(name, "vkDestroySwapchainKHR") == 0) { - return reinterpret_cast( - DestroySwapchainKHR_Disabled); - } - if (strcmp(name, "vkGetSwapchainImagesKHR") == 0) { - return reinterpret_cast( - GetSwapchainImagesKHR_Disabled); - } - if (strcmp(name, "vkAcquireNextSwapchainImageKHR") == 0) { - return reinterpret_cast( - AcquireNextImageKHR_Disabled); - } - if (strcmp(name, "vkQueuePresentKHR") == 0) { - return reinterpret_cast( - QueuePresentKHR_Disabled); - } - } - - // VK_ANDROID_native_buffer should be hidden from applications and layers. - // TODO(jessehall): Generate this as part of GetLoaderBottomProcAddr. - PFN_vkVoidFunction pfn; - if (strcmp(name, "vkGetSwapchainGrallocUsageANDROID") == 0 || - strcmp(name, "vkAcquireImageANDROID") == 0 || - strcmp(name, "vkQueueSignalReleaseImageANDROID") == 0) { - return nullptr; - } - if ((pfn = GetLoaderBottomProcAddr(name))) - return pfn; - return GetDispatchParent(vkdevice).get_device_proc_addr(vkdevice, name); -} - void DestroyDevice_Bottom(VkDevice vkdevice, const VkAllocationCallbacks*) { DestroyDevice(&GetDispatchParent(vkdevice), vkdevice); } @@ -904,14 +704,6 @@ bool InitLoader(hwvulkan_device_t* dev) { namespace driver { -PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) { - return GetInstanceProcAddr_Bottom(instance, pName); -} - -PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) { - return GetDeviceProcAddr_Bottom(device, pName); -} - VkResult EnumerateInstanceExtensionProperties( const char* pLayerName, uint32_t* pPropertyCount, diff --git a/vulkan/libvulkan/loader.h b/vulkan/libvulkan/loader.h index 255b6c517d..15b773d713 100644 --- a/vulkan/libvulkan/loader.h +++ b/vulkan/libvulkan/loader.h @@ -43,7 +43,6 @@ typedef std::bitset DeviceExtensionSet; // ----------------------------------------------------------------------------- // dispatch_gen.cpp -PFN_vkVoidFunction GetLoaderBottomProcAddr(const char* name); bool LoadDriverDispatchTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc_addr, const InstanceExtensionSet& extensions, @@ -56,20 +55,10 @@ bool InitLoader(hwvulkan_device_t* dev); // clang-format off VKAPI_ATTR VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, const VkAllocationCallbacks* allocator, VkInstance* vkinstance); -VKAPI_ATTR PFN_vkVoidFunction GetInstanceProcAddr_Bottom(VkInstance, const char* name); VKAPI_ATTR VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance, uint32_t* pdev_count, VkPhysicalDevice* pdevs); -VKAPI_ATTR void GetPhysicalDeviceProperties_Bottom(VkPhysicalDevice pdev, VkPhysicalDeviceProperties* properties); -VKAPI_ATTR void GetPhysicalDeviceFeatures_Bottom(VkPhysicalDevice pdev, VkPhysicalDeviceFeatures* features); -VKAPI_ATTR void GetPhysicalDeviceMemoryProperties_Bottom(VkPhysicalDevice pdev, VkPhysicalDeviceMemoryProperties* properties); -VKAPI_ATTR void GetPhysicalDeviceQueueFamilyProperties_Bottom(VkPhysicalDevice pdev, uint32_t* properties_count, VkQueueFamilyProperties* properties); -VKAPI_ATTR void GetPhysicalDeviceFormatProperties_Bottom(VkPhysicalDevice pdev, VkFormat format, VkFormatProperties* properties); -VKAPI_ATTR VkResult GetPhysicalDeviceImageFormatProperties_Bottom(VkPhysicalDevice pdev, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* properties); -VKAPI_ATTR void GetPhysicalDeviceSparseImageFormatProperties_Bottom(VkPhysicalDevice pdev, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* properties_count, VkSparseImageFormatProperties* properties); VKAPI_ATTR VkResult EnumerateDeviceExtensionProperties_Bottom(VkPhysicalDevice pdev, const char* layer_name, uint32_t* properties_count, VkExtensionProperties* properties); -VKAPI_ATTR VkResult EnumerateDeviceLayerProperties_Bottom(VkPhysicalDevice pdev, uint32_t* properties_count, VkLayerProperties* properties); VKAPI_ATTR VkResult CreateDevice_Bottom(VkPhysicalDevice pdev, const VkDeviceCreateInfo* create_info, const VkAllocationCallbacks* allocator, VkDevice* device_out); VKAPI_ATTR void DestroyInstance_Bottom(VkInstance vkinstance, const VkAllocationCallbacks* allocator); -VKAPI_ATTR PFN_vkVoidFunction GetDeviceProcAddr_Bottom(VkDevice vkdevice, const char* name); VKAPI_ATTR void DestroyDevice_Bottom(VkDevice device, const VkAllocationCallbacks* pAllocator); VKAPI_ATTR void GetDeviceQueue_Bottom(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue); VKAPI_ATTR VkResult AllocateCommandBuffers_Bottom(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers); @@ -98,18 +87,6 @@ VKAPI_ATTR void DestroySwapchainKHR_Bottom(VkDevice device, VkSwapchainKHR swapc VKAPI_ATTR VkResult GetSwapchainImagesKHR_Bottom(VkDevice device, VkSwapchainKHR swapchain_handle, uint32_t* count, VkImage* images); VKAPI_ATTR VkResult AcquireNextImageKHR_Bottom(VkDevice device, VkSwapchainKHR swapchain_handle, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* image_index); VKAPI_ATTR VkResult QueuePresentKHR_Bottom(VkQueue queue, const VkPresentInfoKHR* present_info); - -VKAPI_ATTR VkResult CreateAndroidSurfaceKHR_Disabled(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); -VKAPI_ATTR void DestroySurfaceKHR_Disabled(VkInstance, VkSurfaceKHR, const VkAllocationCallbacks*); -VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceSupportKHR_Disabled(VkPhysicalDevice, uint32_t, VkSurfaceKHR, VkBool32*); -VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR_Disabled(VkPhysicalDevice, VkSurfaceKHR, VkSurfaceCapabilitiesKHR*); -VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceFormatsKHR_Disabled(VkPhysicalDevice, VkSurfaceKHR, uint32_t*, VkSurfaceFormatKHR*); -VKAPI_ATTR VkResult GetPhysicalDeviceSurfacePresentModesKHR_Disabled(VkPhysicalDevice, VkSurfaceKHR, uint32_t*, VkPresentModeKHR*); -VKAPI_ATTR VkResult CreateSwapchainKHR_Disabled(VkDevice device, const VkSwapchainCreateInfoKHR* create_info, const VkAllocationCallbacks* allocator, VkSwapchainKHR* swapchain_handle); -VKAPI_ATTR void DestroySwapchainKHR_Disabled(VkDevice device, VkSwapchainKHR swapchain_handle, const VkAllocationCallbacks* allocator); -VKAPI_ATTR VkResult GetSwapchainImagesKHR_Disabled(VkDevice device, VkSwapchainKHR swapchain_handle, uint32_t* count, VkImage* images); -VKAPI_ATTR VkResult AcquireNextImageKHR_Disabled(VkDevice device, VkSwapchainKHR swapchain_handle, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* image_index); -VKAPI_ATTR VkResult QueuePresentKHR_Disabled(VkQueue queue, const VkPresentInfoKHR* present_info); // clang-format on // ----------------------------------------------------------------------------- -- cgit v1.2.3-59-g8ed1b From cc5e2765a9d56b03b69d0c3f25b94721f82d034e Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 24 Mar 2016 13:01:16 +0800 Subject: vulkan: rework DriverDispatchTable Generate {Instance,Device}DriverTable from code-generator.tmpl to replace dispatch.tmpl entirely. The new code avoids initializing VK_ANDROID_native_buffer entries when the extension is not enabled. The separation of instance and device driver tables also allows us to initialize the device driver table with vkGetDeviceProcAddr, which is expected to return more efficient function pointers on properly implemented HALs. CreateInstance_Bottom always has a potential resource leak when the HAL-created instance does not contain HWVULKAN_DISPATCH_MAGIC. CreateDevice_Bottom now has the same issue. Both of them will be fixed in following commits. Change-Id: If7800ef23098121f1fff643a2c5224c2c9be0711 --- vulkan/libvulkan/Android.mk | 1 - vulkan/libvulkan/code-generator.tmpl | 178 +++++++++++++++++-- vulkan/libvulkan/dispatch.tmpl | 326 ----------------------------------- vulkan/libvulkan/dispatch_gen.cpp | 160 ----------------- vulkan/libvulkan/dispatch_gen.h | 52 ------ vulkan/libvulkan/driver.cpp | 2 +- vulkan/libvulkan/driver.h | 12 +- vulkan/libvulkan/driver_gen.cpp | 55 ++++++ vulkan/libvulkan/driver_gen.h | 30 ++++ vulkan/libvulkan/loader.cpp | 74 ++++---- vulkan/libvulkan/loader.h | 17 +- vulkan/libvulkan/swapchain.cpp | 6 +- 12 files changed, 307 insertions(+), 606 deletions(-) delete mode 100644 vulkan/libvulkan/dispatch.tmpl delete mode 100644 vulkan/libvulkan/dispatch_gen.cpp delete mode 100644 vulkan/libvulkan/dispatch_gen.h (limited to 'vulkan/libvulkan/driver.cpp') diff --git a/vulkan/libvulkan/Android.mk b/vulkan/libvulkan/Android.mk index 62d12797b1..7b7e01f222 100644 --- a/vulkan/libvulkan/Android.mk +++ b/vulkan/libvulkan/Android.mk @@ -42,7 +42,6 @@ LOCAL_SRC_FILES := \ api.cpp \ api_gen.cpp \ debug_report.cpp \ - dispatch_gen.cpp \ driver.cpp \ driver_gen.cpp \ layers_extensions.cpp \ diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl index f7083c3146..23c27176d7 100644 --- a/vulkan/libvulkan/code-generator.tmpl +++ b/vulkan/libvulkan/code-generator.tmpl @@ -46,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 @@ -56,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 @@ -91,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); @@ -169,9 +171,32 @@ 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 ¶ @@ -245,6 +270,42 @@ ProcHook::Extension GetProcHookExtension(const char* name) { return ProcHook::EXTENSION_UNKNOWN; } ¶ +{{Macro "C++.DefineInitProcMacro" "driver"}} +¶ +{{Macro "driver.C++.DefineInitProcExtMacro"}} +¶ +bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc) +{ + auto& data = GetData(instance); + bool success = true; + ¶ + // clang-format off + {{range $f := AllCommands $}} + {{if (Macro "driver.IsInstanceDriverTableEntry" $f)}} + {{Macro "C++.InitProc" $f}} + {{end}} + {{end}} + // clang-format on + ¶ + return success; +} +¶ +bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc) +{ + auto& data = GetData(dev); + bool success = true; + ¶ + // clang-format off + {{range $f := AllCommands $}} + {{if (Macro "driver.IsDeviceDriverTableEntry" $f)}} + {{Macro "C++.InitProc" $f}} + {{end}} + {{end}} + // clang-format on + ¶ + return success; +} +¶ »} // namespace driver »} // namespace vulkan ¶ @@ -254,10 +315,10 @@ ProcHook::Extension GetProcHookExtension(const char* name) { {{/* ------------------------------------------------------------------------------ - Emits a declaration of a dispatch table entry. + Emits a declaration of a dispatch/driver table entry. ------------------------------------------------------------------------------ */}} -{{define "C++.DeclareDispatchTableEntry"}} +{{define "C++.DeclareTableEntry"}} {{AssertType $ "Function"}} {{Macro "FunctionPtrName" $}} {{Macro "BaseName" $}} @@ -266,10 +327,10 @@ ProcHook::Extension GetProcHookExtension(const char* name) { {{/* ------------------------------------------------------------------------------- - Emits macros to help initialize dispatch tables. + Emits INIT_PROC macro. ------------------------------------------------------------------------------- */}} -{{define "C++.DefineInitProcMacros"}} +{{define "C++.DefineInitProcMacro"}} #define UNLIKELY(expr) __builtin_expect((expr), 0) ¶ #define INIT_PROC(obj, proc) do { \ @@ -280,11 +341,6 @@ ProcHook::Extension GetProcHookExtension(const char* name) { 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}} @@ -367,6 +423,19 @@ ProcHook::Extension GetProcHookExtension(const char* name) { {{end}} +{{/* +------------------------------------------------------------------------------- + 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. @@ -612,6 +681,19 @@ VK_KHR_swapchain {{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. @@ -762,6 +844,78 @@ VK_KHR_swapchain {{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 + + {{/* 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. diff --git a/vulkan/libvulkan/dispatch.tmpl b/vulkan/libvulkan/dispatch.tmpl deleted file mode 100644 index fd778790bf..0000000000 --- a/vulkan/libvulkan/dispatch.tmpl +++ /dev/null @@ -1,326 +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 -#include -¶ -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 -#include -#include "loader.h" -¶ -#define UNLIKELY(expr) __builtin_expect((expr), 0) -¶ -using namespace vulkan; -¶ -namespace vulkan { -¶ -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(get_proc_addr(instance, "vkGetDeviceProcAddr")); - if (UNLIKELY(!dispatch.GetDeviceProcAddr)) { - ALOGE("missing driver proc: %s", "vkGetDeviceProcAddr"); - success = false; - } - dispatch.DestroyDevice = reinterpret_cast(get_proc_addr(instance, "vkDestroyDevice")); - if (UNLIKELY(!dispatch.DestroyDevice)) { - ALOGE("missing driver proc: %s", "vkDestroyDevice"); - success = false; - } - dispatch.GetDeviceQueue = reinterpret_cast(get_proc_addr(instance, "vkGetDeviceQueue")); - if (UNLIKELY(!dispatch.GetDeviceQueue)) { - ALOGE("missing driver proc: %s", "vkGetDeviceQueue"); - success = false; - } - dispatch.AllocateCommandBuffers = reinterpret_cast(get_proc_addr(instance, "vkAllocateCommandBuffers")); - if (UNLIKELY(!dispatch.AllocateCommandBuffers)) { - ALOGE("missing driver proc: %s", "vkAllocateCommandBuffers"); - success = false; - } - dispatch.CreateImage = reinterpret_cast(get_proc_addr(instance, "vkCreateImage")); - if (UNLIKELY(!dispatch.CreateImage)) { - ALOGE("missing driver proc: %s", "vkCreateImage"); - success = false; - } - dispatch.DestroyImage = reinterpret_cast(get_proc_addr(instance, "vkDestroyImage")); - if (UNLIKELY(!dispatch.DestroyImage)) { - ALOGE("missing driver proc: %s", "vkDestroyImage"); - success = false; - } - dispatch.GetSwapchainGrallocUsageANDROID = reinterpret_cast(get_proc_addr(instance, "vkGetSwapchainGrallocUsageANDROID")); - if (UNLIKELY(!dispatch.GetSwapchainGrallocUsageANDROID)) { - ALOGE("missing driver proc: %s", "vkGetSwapchainGrallocUsageANDROID"); - success = false; - } - dispatch.AcquireImageANDROID = reinterpret_cast(get_proc_addr(instance, "vkAcquireImageANDROID")); - if (UNLIKELY(!dispatch.AcquireImageANDROID)) { - ALOGE("missing driver proc: %s", "vkAcquireImageANDROID"); - success = false; - } - dispatch.QueueSignalReleaseImageANDROID = reinterpret_cast(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 fa199bd25c..0000000000 --- a/vulkan/libvulkan/dispatch_gen.cpp +++ /dev/null @@ -1,160 +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 -#include -#include "loader.h" - -#define UNLIKELY(expr) __builtin_expect((expr), 0) - -using namespace vulkan; - -namespace vulkan { - -bool LoadDriverDispatchTable(VkInstance instance, - PFN_vkGetInstanceProcAddr get_proc_addr, - const InstanceExtensionSet& extensions, - DriverDispatchTable& dispatch) { - bool success = true; - // clang-format off - dispatch.DestroyInstance = reinterpret_cast(get_proc_addr(instance, "vkDestroyInstance")); - if (UNLIKELY(!dispatch.DestroyInstance)) { - ALOGE("missing driver proc: %s", "vkDestroyInstance"); - success = false; - } - dispatch.EnumeratePhysicalDevices = reinterpret_cast(get_proc_addr(instance, "vkEnumeratePhysicalDevices")); - if (UNLIKELY(!dispatch.EnumeratePhysicalDevices)) { - ALOGE("missing driver proc: %s", "vkEnumeratePhysicalDevices"); - success = false; - } - dispatch.GetPhysicalDeviceProperties = reinterpret_cast(get_proc_addr(instance, "vkGetPhysicalDeviceProperties")); - if (UNLIKELY(!dispatch.GetPhysicalDeviceProperties)) { - ALOGE("missing driver proc: %s", "vkGetPhysicalDeviceProperties"); - success = false; - } - dispatch.GetPhysicalDeviceQueueFamilyProperties = reinterpret_cast(get_proc_addr(instance, "vkGetPhysicalDeviceQueueFamilyProperties")); - if (UNLIKELY(!dispatch.GetPhysicalDeviceQueueFamilyProperties)) { - ALOGE("missing driver proc: %s", "vkGetPhysicalDeviceQueueFamilyProperties"); - success = false; - } - dispatch.GetPhysicalDeviceMemoryProperties = reinterpret_cast(get_proc_addr(instance, "vkGetPhysicalDeviceMemoryProperties")); - if (UNLIKELY(!dispatch.GetPhysicalDeviceMemoryProperties)) { - ALOGE("missing driver proc: %s", "vkGetPhysicalDeviceMemoryProperties"); - success = false; - } - dispatch.GetPhysicalDeviceFeatures = reinterpret_cast(get_proc_addr(instance, "vkGetPhysicalDeviceFeatures")); - if (UNLIKELY(!dispatch.GetPhysicalDeviceFeatures)) { - ALOGE("missing driver proc: %s", "vkGetPhysicalDeviceFeatures"); - success = false; - } - dispatch.GetPhysicalDeviceFormatProperties = reinterpret_cast(get_proc_addr(instance, "vkGetPhysicalDeviceFormatProperties")); - if (UNLIKELY(!dispatch.GetPhysicalDeviceFormatProperties)) { - ALOGE("missing driver proc: %s", "vkGetPhysicalDeviceFormatProperties"); - success = false; - } - dispatch.GetPhysicalDeviceImageFormatProperties = reinterpret_cast(get_proc_addr(instance, "vkGetPhysicalDeviceImageFormatProperties")); - if (UNLIKELY(!dispatch.GetPhysicalDeviceImageFormatProperties)) { - ALOGE("missing driver proc: %s", "vkGetPhysicalDeviceImageFormatProperties"); - success = false; - } - dispatch.CreateDevice = reinterpret_cast(get_proc_addr(instance, "vkCreateDevice")); - if (UNLIKELY(!dispatch.CreateDevice)) { - ALOGE("missing driver proc: %s", "vkCreateDevice"); - success = false; - } - dispatch.EnumerateDeviceExtensionProperties = reinterpret_cast(get_proc_addr(instance, "vkEnumerateDeviceExtensionProperties")); - if (UNLIKELY(!dispatch.EnumerateDeviceExtensionProperties)) { - ALOGE("missing driver proc: %s", "vkEnumerateDeviceExtensionProperties"); - success = false; - } - dispatch.GetPhysicalDeviceSparseImageFormatProperties = reinterpret_cast(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(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(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(get_proc_addr(instance, "vkDebugReportMessageEXT")); - if (UNLIKELY(!dispatch.DebugReportMessageEXT)) { - ALOGE("missing driver proc: %s", "vkDebugReportMessageEXT"); - success = false; - } - } - dispatch.GetDeviceProcAddr = reinterpret_cast(get_proc_addr(instance, "vkGetDeviceProcAddr")); - if (UNLIKELY(!dispatch.GetDeviceProcAddr)) { - ALOGE("missing driver proc: %s", "vkGetDeviceProcAddr"); - success = false; - } - dispatch.DestroyDevice = reinterpret_cast(get_proc_addr(instance, "vkDestroyDevice")); - if (UNLIKELY(!dispatch.DestroyDevice)) { - ALOGE("missing driver proc: %s", "vkDestroyDevice"); - success = false; - } - dispatch.GetDeviceQueue = reinterpret_cast(get_proc_addr(instance, "vkGetDeviceQueue")); - if (UNLIKELY(!dispatch.GetDeviceQueue)) { - ALOGE("missing driver proc: %s", "vkGetDeviceQueue"); - success = false; - } - dispatch.AllocateCommandBuffers = reinterpret_cast(get_proc_addr(instance, "vkAllocateCommandBuffers")); - if (UNLIKELY(!dispatch.AllocateCommandBuffers)) { - ALOGE("missing driver proc: %s", "vkAllocateCommandBuffers"); - success = false; - } - dispatch.CreateImage = reinterpret_cast(get_proc_addr(instance, "vkCreateImage")); - if (UNLIKELY(!dispatch.CreateImage)) { - ALOGE("missing driver proc: %s", "vkCreateImage"); - success = false; - } - dispatch.DestroyImage = reinterpret_cast(get_proc_addr(instance, "vkDestroyImage")); - if (UNLIKELY(!dispatch.DestroyImage)) { - ALOGE("missing driver proc: %s", "vkDestroyImage"); - success = false; - } - dispatch.GetSwapchainGrallocUsageANDROID = reinterpret_cast(get_proc_addr(instance, "vkGetSwapchainGrallocUsageANDROID")); - if (UNLIKELY(!dispatch.GetSwapchainGrallocUsageANDROID)) { - ALOGE("missing driver proc: %s", "vkGetSwapchainGrallocUsageANDROID"); - success = false; - } - dispatch.AcquireImageANDROID = reinterpret_cast(get_proc_addr(instance, "vkAcquireImageANDROID")); - if (UNLIKELY(!dispatch.AcquireImageANDROID)) { - ALOGE("missing driver proc: %s", "vkAcquireImageANDROID"); - success = false; - } - dispatch.QueueSignalReleaseImageANDROID = reinterpret_cast(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/dispatch_gen.h b/vulkan/libvulkan/dispatch_gen.h deleted file mode 100644 index ca31caf553..0000000000 --- a/vulkan/libvulkan/dispatch_gen.h +++ /dev/null @@ -1,52 +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 -#include - -namespace vulkan { - -struct DriverDispatchTable { - // 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_vkCreateDevice CreateDevice; - PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties; - PFN_vkGetPhysicalDeviceSparseImageFormatProperties GetPhysicalDeviceSparseImageFormatProperties; - PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT; - PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT; - PFN_vkDebugReportMessageEXT DebugReportMessageEXT; - PFN_vkGetDeviceProcAddr GetDeviceProcAddr; - PFN_vkDestroyDevice DestroyDevice; - PFN_vkGetDeviceQueue GetDeviceQueue; - PFN_vkAllocateCommandBuffers AllocateCommandBuffers; - PFN_vkCreateImage CreateImage; - PFN_vkDestroyImage DestroyImage; - PFN_vkGetSwapchainGrallocUsageANDROID GetSwapchainGrallocUsageANDROID; - PFN_vkAcquireImageANDROID AcquireImageANDROID; - PFN_vkQueueSignalReleaseImageANDROID QueueSignalReleaseImageANDROID; - // clang-format on -}; - -} // namespace vulkan diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index 68ae5c8314..d517c72440 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -193,7 +193,7 @@ PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) { PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) { const ProcHook* hook = GetProcHook(pName); if (!hook) - return GetData(device).get_device_proc_addr(device, pName); + return GetData(device).driver.GetDeviceProcAddr(device, pName); if (hook->type != ProcHook::DEVICE) { ALOGE("Invalid use of vkGetDeviceProcAddr to query %s", pName); diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h index 28b0ce6cde..7af63fab29 100644 --- a/vulkan/libvulkan/driver.h +++ b/vulkan/libvulkan/driver.h @@ -64,7 +64,10 @@ namespace driver { struct InstanceData { InstanceData(const VkAllocationCallbacks& alloc) - : opaque_api_data(), allocator(alloc) { + : opaque_api_data(), + allocator(alloc), + driver(), + get_device_proc_addr(nullptr) { hook_extensions.set(ProcHook::EXTENSION_CORE); hal_extensions.set(ProcHook::EXTENSION_CORE); } @@ -75,11 +78,14 @@ struct InstanceData { std::bitset hook_extensions; std::bitset hal_extensions; + + InstanceDriverTable driver; + PFN_vkGetDeviceProcAddr get_device_proc_addr; }; struct DeviceData { DeviceData(const VkAllocationCallbacks& alloc) - : opaque_api_data(), allocator(alloc), get_device_proc_addr(nullptr) { + : opaque_api_data(), allocator(alloc), driver() { hook_extensions.set(ProcHook::EXTENSION_CORE); hal_extensions.set(ProcHook::EXTENSION_CORE); } @@ -91,7 +97,7 @@ struct DeviceData { std::bitset hook_extensions; std::bitset hal_extensions; - PFN_vkGetDeviceProcAddr get_device_proc_addr; + DeviceDriverTable driver; }; bool Debuggable(); diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp index d725df5a62..87987c884c 100644 --- a/vulkan/libvulkan/driver_gen.cpp +++ b/vulkan/libvulkan/driver_gen.cpp @@ -370,6 +370,61 @@ ProcHook::Extension GetProcHookExtension(const char* name) { return ProcHook::EXTENSION_UNKNOWN; } +#define UNLIKELY(expr) __builtin_expect((expr), 0) + +#define INIT_PROC(obj, proc) \ + do { \ + data.driver.proc = \ + reinterpret_cast(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, 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 diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h index 63dadcbdb3..4226a6374f 100644 --- a/vulkan/libvulkan/driver_gen.h +++ b/vulkan/libvulkan/driver_gen.h @@ -52,9 +52,39 @@ struct ProcHook { PFN_vkVoidFunction checked_proc; // nullptr for global/instance hooks }; +struct InstanceDriverTable { + // clang-format off + PFN_vkDestroyInstance DestroyInstance; + PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices; + PFN_vkGetInstanceProcAddr GetInstanceProcAddr; + PFN_vkCreateDevice CreateDevice; + PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties; + 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_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 diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp index 8c68efa70a..3e5ea22c10 100644 --- a/vulkan/libvulkan/loader.cpp +++ b/vulkan/libvulkan/loader.cpp @@ -147,7 +147,6 @@ struct Instance { num_physical_devices(0) { memset(physical_devices, 0, sizeof(physical_devices)); enabled_extensions.reset(); - memset(&drv.dispatch, 0, sizeof(drv.dispatch)); } ~Instance() {} @@ -162,10 +161,6 @@ struct Instance { DebugReportCallbackList debug_report_callbacks; InstanceExtensionSet enabled_extensions; - - struct { - DriverDispatchTable dispatch; - } drv; // may eventually be an array }; struct Device { @@ -226,8 +221,8 @@ typename HandleTraits::LoaderObjectType& GetDispatchParent( void DestroyDevice(Device* device, VkDevice vkdevice) { const auto& instance = *device->instance; - if (vkdevice != VK_NULL_HANDLE) - instance.drv.dispatch.DestroyDevice(vkdevice, instance.alloc); + if (vkdevice != VK_NULL_HANDLE && device->base.driver.DestroyDevice) + device->base.driver.DestroyDevice(vkdevice, instance.alloc); device->~Device(); instance.alloc->pfnFree(instance.alloc->pUserData, device); @@ -263,8 +258,8 @@ void* StripCreateExtensions(const void* pNext) { void DestroyInstance(Instance* instance, const VkAllocationCallbacks* allocator, VkInstance vkinstance) { - if (vkinstance != VK_NULL_HANDLE && instance->drv.dispatch.DestroyInstance) - instance->drv.dispatch.DestroyInstance(vkinstance, allocator); + if (vkinstance != VK_NULL_HANDLE && instance->base.driver.DestroyInstance) + instance->base.driver.DestroyInstance(vkinstance, allocator); instance->~Instance(); allocator->pfnFree(allocator->pUserData, instance); @@ -397,22 +392,30 @@ VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, return VK_ERROR_INITIALIZATION_FAILED; } - if (!LoadDriverDispatchTable(drv_instance, g_hwdevice->GetInstanceProcAddr, - instance.enabled_extensions, - instance.drv.dispatch)) { + if (!driver::InitDriverTable(drv_instance, + g_hwdevice->GetInstanceProcAddr)) { + DestroyInstance(&instance, allocator, drv_instance); + return VK_ERROR_INITIALIZATION_FAILED; + } + + instance.base.get_device_proc_addr = + reinterpret_cast( + g_hwdevice->GetInstanceProcAddr(drv_instance, + "vkGetDeviceProcAddr")); + if (!instance.base.get_device_proc_addr) { DestroyInstance(&instance, allocator, drv_instance); return VK_ERROR_INITIALIZATION_FAILED; } uint32_t num_physical_devices = 0; - result = instance.drv.dispatch.EnumeratePhysicalDevices( + result = instance.base.driver.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( + result = instance.base.driver.EnumeratePhysicalDevices( drv_instance, &num_physical_devices, instance.physical_devices); if (result != VK_SUCCESS) { DestroyInstance(&instance, allocator, drv_instance); @@ -428,7 +431,7 @@ VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, } uint32_t count; - if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties( + if ((result = instance.base.driver.EnumerateDeviceExtensionProperties( instance.physical_devices[i], nullptr, &count, nullptr)) != VK_SUCCESS) { ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i, @@ -442,7 +445,7 @@ VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, DestroyInstance(&instance, allocator, drv_instance); return VK_ERROR_OUT_OF_HOST_MEMORY; } - if ((result = instance.drv.dispatch.EnumerateDeviceExtensionProperties( + if ((result = instance.base.driver.EnumerateDeviceExtensionProperties( instance.physical_devices[i], nullptr, &count, extensions.data())) != VK_SUCCESS) { ALOGW("driver EnumerateDeviceExtensionProperties(%u) failed: %d", i, @@ -596,7 +599,7 @@ VkResult CreateDevice_Bottom(VkPhysicalDevice gpu, driver_create_info.enabledExtensionCount = num_driver_extensions; driver_create_info.ppEnabledExtensionNames = driver_extensions; VkDevice drv_device; - VkResult result = instance.drv.dispatch.CreateDevice( + VkResult result = instance.base.driver.CreateDevice( gpu, &driver_create_info, allocator, &drv_device); if (result != VK_SUCCESS) { DestroyDevice(device, VK_NULL_HANDLE); @@ -608,10 +611,11 @@ VkResult CreateDevice_Bottom(VkPhysicalDevice gpu, return VK_ERROR_INITIALIZATION_FAILED; } - device->base.get_device_proc_addr = - reinterpret_cast( - instance.drv.dispatch.GetDeviceProcAddr(drv_device, - "vkGetDeviceProcAddr")); + if (!driver::InitDriverTable(drv_device, + instance.base.get_device_proc_addr)) { + DestroyDevice(device, drv_device); + return VK_ERROR_INITIALIZATION_FAILED; + } *device_out = drv_device; return VK_SUCCESS; @@ -638,25 +642,23 @@ void GetDeviceQueue_Bottom(VkDevice vkdevice, uint32_t family, uint32_t index, VkQueue* queue_out) { - const auto& device = GetDispatchParent(vkdevice); - const auto& instance = *device.instance; + const auto& data = driver::GetData(vkdevice); - instance.drv.dispatch.GetDeviceQueue(vkdevice, family, index, queue_out); - driver::SetData(*queue_out, device.base); + data.driver.GetDeviceQueue(vkdevice, family, index, queue_out); + driver::SetData(*queue_out, data); } VkResult AllocateCommandBuffers_Bottom( VkDevice vkdevice, const VkCommandBufferAllocateInfo* alloc_info, VkCommandBuffer* cmdbufs) { - const auto& device = GetDispatchParent(vkdevice); - const auto& instance = *device.instance; + const auto& data = driver::GetData(vkdevice); - VkResult result = instance.drv.dispatch.AllocateCommandBuffers( - vkdevice, alloc_info, cmdbufs); + VkResult result = + data.driver.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); + driver::SetData(cmdbufs[i], data); } return result; @@ -676,16 +678,16 @@ VkInstance GetDriverInstance(VkInstance instance) { return instance; } -const DriverDispatchTable& GetDriverDispatch(VkInstance instance) { - return GetDispatchParent(instance).drv.dispatch; +const driver::InstanceDriverTable& GetDriverDispatch(VkInstance instance) { + return driver::GetData(instance).driver; } -const DriverDispatchTable& GetDriverDispatch(VkDevice device) { - return GetDispatchParent(device).instance->drv.dispatch; +const driver::DeviceDriverTable& GetDriverDispatch(VkDevice device) { + return driver::GetData(device).driver; } -const DriverDispatchTable& GetDriverDispatch(VkQueue queue) { - return GetDispatchParent(queue).instance->drv.dispatch; +const driver::DeviceDriverTable& GetDriverDispatch(VkQueue queue) { + return driver::GetData(queue).driver; } DebugReportCallbackList& GetDebugReportCallbacks(VkInstance instance) { diff --git a/vulkan/libvulkan/loader.h b/vulkan/libvulkan/loader.h index 15b773d713..a2c7e83a72 100644 --- a/vulkan/libvulkan/loader.h +++ b/vulkan/libvulkan/loader.h @@ -18,8 +18,9 @@ #define LIBVULKAN_LOADER_H 1 #include -#include "dispatch_gen.h" +#include #include "debug_report.h" +#include "driver.h" struct hwvulkan_device_t; @@ -40,14 +41,6 @@ enum DeviceExtension { }; typedef std::bitset DeviceExtensionSet; -// ----------------------------------------------------------------------------- -// dispatch_gen.cpp - -bool LoadDriverDispatchTable(VkInstance instance, - PFN_vkGetInstanceProcAddr get_proc_addr, - const InstanceExtensionSet& extensions, - DriverDispatchTable& dispatch); - // ----------------------------------------------------------------------------- // loader.cpp @@ -67,9 +60,9 @@ VKAPI_ATTR VkResult AllocateCommandBuffers_Bottom(VkDevice device, const VkComma 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); +const driver::InstanceDriverTable& GetDriverDispatch(VkInstance instance); +const driver::DeviceDriverTable& GetDriverDispatch(VkDevice device); +const driver::DeviceDriverTable& GetDriverDispatch(VkQueue queue); DebugReportCallbackList& GetDebugReportCallbacks(VkInstance instance); // ----------------------------------------------------------------------------- diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp index 7f944cf171..cc4ae3de48 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -436,7 +436,7 @@ VkResult CreateSwapchainKHR_Bottom(VkDevice device, // -- Configure the native window -- Surface& surface = *SurfaceFromHandle(create_info->surface); - const DriverDispatchTable& dispatch = GetDriverDispatch(device); + const auto& dispatch = GetDriverDispatch(device); int native_format = HAL_PIXEL_FORMAT_RGBA_8888; switch (create_info->imageFormat) { @@ -684,7 +684,7 @@ VKAPI_ATTR void DestroySwapchainKHR_Bottom(VkDevice device, VkSwapchainKHR swapchain_handle, const VkAllocationCallbacks* allocator) { - const DriverDispatchTable& dispatch = GetDriverDispatch(device); + const auto& dispatch = GetDriverDispatch(device); Swapchain* swapchain = SwapchainFromHandle(swapchain_handle); const std::shared_ptr& window = swapchain->surface.window; @@ -805,7 +805,7 @@ VkResult QueuePresentKHR_Bottom(VkQueue queue, present_info->sType); ALOGV_IF(present_info->pNext, "VkPresentInfo::pNext != NULL"); - const DriverDispatchTable& dispatch = GetDriverDispatch(queue); + const auto& dispatch = GetDriverDispatch(queue); VkResult final_result = VK_SUCCESS; for (uint32_t sc = 0; sc < present_info->swapchainCount; sc++) { Swapchain& swapchain = -- cgit v1.2.3-59-g8ed1b From ba0be41afe39dcbed0a712a32d1ab6c341797007 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 24 Mar 2016 16:24:40 +0800 Subject: vulkan: move GetDeviceQueue_Bottom Move it from loader.cpp to driver.cpp and rename it to driver::GetDeviceQueue. No functional change. Change-Id: Ide8ebe044e62b8ef6fc64ac03dcc1d920f5bf9a6 --- vulkan/libvulkan/code-generator.tmpl | 2 ++ vulkan/libvulkan/driver.cpp | 10 ++++++++++ vulkan/libvulkan/driver.h | 2 ++ vulkan/libvulkan/driver_gen.cpp | 2 +- vulkan/libvulkan/loader.cpp | 10 ---------- vulkan/libvulkan/loader.h | 1 - 6 files changed, 15 insertions(+), 12 deletions(-) (limited to 'vulkan/libvulkan/driver.cpp') diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl index 23c27176d7..4ec13a0cd5 100644 --- a/vulkan/libvulkan/code-generator.tmpl +++ b/vulkan/libvulkan/code-generator.tmpl @@ -834,6 +834,8 @@ VK_KHR_swapchain {{if eq $.Name "vkGetDeviceProcAddr"}} reinterpret_cast({{$base}}), + {{else if eq $.Name "vkGetDeviceQueue"}} + reinterpret_cast({{$base}}), {{else}} reinterpret_cast({{$base}}_Bottom), {{end}} diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index d517c72440..1641e31bc3 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -205,5 +205,15 @@ PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) { : hook->disabled_proc; } +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); +} + } // namespace driver } // namespace vulkan diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h index 7af63fab29..8569a52d0e 100644 --- a/vulkan/libvulkan/driver.h +++ b/vulkan/libvulkan/driver.h @@ -108,6 +108,8 @@ 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 void GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue); // clang-format on template diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp index 87987c884c..b6081f0047 100644 --- a/vulkan/libvulkan/driver_gen.cpp +++ b/vulkan/libvulkan/driver_gen.cpp @@ -268,7 +268,7 @@ const ProcHook g_proc_hooks[] = { "vkGetDeviceQueue", ProcHook::DEVICE, ProcHook::EXTENSION_CORE, - reinterpret_cast(GetDeviceQueue_Bottom), + reinterpret_cast(GetDeviceQueue), nullptr, nullptr, }, diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp index 3e5ea22c10..96eae53e3c 100644 --- a/vulkan/libvulkan/loader.cpp +++ b/vulkan/libvulkan/loader.cpp @@ -638,16 +638,6 @@ 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& data = driver::GetData(vkdevice); - - data.driver.GetDeviceQueue(vkdevice, family, index, queue_out); - driver::SetData(*queue_out, data); -} - VkResult AllocateCommandBuffers_Bottom( VkDevice vkdevice, const VkCommandBufferAllocateInfo* alloc_info, diff --git a/vulkan/libvulkan/loader.h b/vulkan/libvulkan/loader.h index a2c7e83a72..2183c29ad9 100644 --- a/vulkan/libvulkan/loader.h +++ b/vulkan/libvulkan/loader.h @@ -53,7 +53,6 @@ VKAPI_ATTR VkResult EnumerateDeviceExtensionProperties_Bottom(VkPhysicalDevice p 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 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 -- cgit v1.2.3-59-g8ed1b From 6a58a8a7813450038cb15575e3333b83f268c972 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 24 Mar 2016 16:29:51 +0800 Subject: vulkan: move AllocateCommandBuffers_Bottom Move it from loader.cpp to driver.cpp and rename it to driver::AllocateCommandBuffers. No functional change. Change-Id: I0abdca7dea128df0b313b90cfb5d5825566fc790 --- vulkan/libvulkan/code-generator.tmpl | 8 +++----- vulkan/libvulkan/driver.cpp | 16 ++++++++++++++++ vulkan/libvulkan/driver.h | 1 + vulkan/libvulkan/driver_gen.cpp | 2 +- vulkan/libvulkan/loader.cpp | 16 ---------------- vulkan/libvulkan/loader.h | 1 - 6 files changed, 21 insertions(+), 23 deletions(-) (limited to 'vulkan/libvulkan/driver.cpp') diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl index 4ec13a0cd5..f3e7dbfdfd 100644 --- a/vulkan/libvulkan/code-generator.tmpl +++ b/vulkan/libvulkan/code-generator.tmpl @@ -832,12 +832,10 @@ VK_KHR_swapchain {{else}} ProcHook::EXTENSION_CORE, - {{if eq $.Name "vkGetDeviceProcAddr"}} - reinterpret_cast({{$base}}), - {{else if eq $.Name "vkGetDeviceQueue"}} - reinterpret_cast({{$base}}), - {{else}} + {{if eq $.Name "vkDestroyDevice"}} reinterpret_cast({{$base}}_Bottom), + {{else}} + reinterpret_cast({{$base}}), {{end}} nullptr, nullptr, diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index 1641e31bc3..1301912dd6 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -215,5 +215,21 @@ void GetDeviceQueue(VkDevice device, 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 8569a52d0e..73020371af 100644 --- a/vulkan/libvulkan/driver.h +++ b/vulkan/libvulkan/driver.h @@ -110,6 +110,7 @@ VKAPI_ATTR PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pNa VKAPI_ATTR VkResult EnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties); 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 diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp index b6081f0047..dd203c7829 100644 --- a/vulkan/libvulkan/driver_gen.cpp +++ b/vulkan/libvulkan/driver_gen.cpp @@ -140,7 +140,7 @@ const ProcHook g_proc_hooks[] = { "vkAllocateCommandBuffers", ProcHook::DEVICE, ProcHook::EXTENSION_CORE, - reinterpret_cast(AllocateCommandBuffers_Bottom), + reinterpret_cast(AllocateCommandBuffers), nullptr, nullptr, }, diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp index 96eae53e3c..1212f96dd4 100644 --- a/vulkan/libvulkan/loader.cpp +++ b/vulkan/libvulkan/loader.cpp @@ -638,22 +638,6 @@ void DestroyDevice_Bottom(VkDevice vkdevice, const VkAllocationCallbacks*) { DestroyDevice(&GetDispatchParent(vkdevice), vkdevice); } -VkResult AllocateCommandBuffers_Bottom( - VkDevice vkdevice, - const VkCommandBufferAllocateInfo* alloc_info, - VkCommandBuffer* cmdbufs) { - const auto& data = driver::GetData(vkdevice); - - VkResult result = - data.driver.AllocateCommandBuffers(vkdevice, alloc_info, cmdbufs); - if (result == VK_SUCCESS) { - for (uint32_t i = 0; i < alloc_info->commandBufferCount; i++) - driver::SetData(cmdbufs[i], data); - } - - return result; -} - // ----------------------------------------------------------------------------- const VkAllocationCallbacks* GetAllocator(VkInstance vkinstance) { diff --git a/vulkan/libvulkan/loader.h b/vulkan/libvulkan/loader.h index 2183c29ad9..823c4467ff 100644 --- a/vulkan/libvulkan/loader.h +++ b/vulkan/libvulkan/loader.h @@ -53,7 +53,6 @@ VKAPI_ATTR VkResult EnumerateDeviceExtensionProperties_Bottom(VkPhysicalDevice p 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 void DestroyDevice_Bottom(VkDevice device, const VkAllocationCallbacks* pAllocator); -VKAPI_ATTR VkResult AllocateCommandBuffers_Bottom(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers); // clang-format on const VkAllocationCallbacks* GetAllocator(VkInstance instance); -- cgit v1.2.3-59-g8ed1b From 4901db70b12801cf1966937a58eb7566bfdeb4ce Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 24 Mar 2016 16:38:58 +0800 Subject: vulkan: rework {Create,Destroy}Device_Bottom The reworked driver::CreateDevice will - use the providied pAllocator, - call HAL's EnumerateDeviceExtensionProperties and filter out extensions unknown to HAL, if there is any extension enabled. We do not expect or enumerate any HAL layer yet as that requires some works to layers_extensions.cpp. Change-Id: I3ba4019d18dfed994d7037d95825bf54096f2a5d --- vulkan/libvulkan/code-generator.tmpl | 17 +- vulkan/libvulkan/driver.cpp | 352 +++++++++++++++++++++++++++++++++++ vulkan/libvulkan/driver.h | 3 + vulkan/libvulkan/driver_gen.cpp | 5 +- vulkan/libvulkan/driver_gen.h | 1 + vulkan/libvulkan/loader.cpp | 138 +------------- vulkan/libvulkan/loader.h | 2 - 7 files changed, 368 insertions(+), 150 deletions(-) (limited to 'vulkan/libvulkan/driver.cpp') diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl index f3e7dbfdfd..3a6f0a97b5 100644 --- a/vulkan/libvulkan/code-generator.tmpl +++ b/vulkan/libvulkan/code-generator.tmpl @@ -792,6 +792,8 @@ VK_KHR_swapchain {{if eq $.Name "vkGetInstanceProcAddr"}} reinterpret_cast({{$base}}), + {{else if eq $.Name "vkCreateDevice"}} + reinterpret_cast({{$base}}), {{else}} reinterpret_cast({{$base}}_Bottom), {{end}} @@ -830,15 +832,10 @@ VK_KHR_swapchain reinterpret_cast(checked{{$base}}), {{end}} {{else}} - ProcHook::EXTENSION_CORE, - - {{if eq $.Name "vkDestroyDevice"}} - reinterpret_cast({{$base}}_Bottom), - {{else}} - reinterpret_cast({{$base}}), - {{end}} - nullptr, - nullptr, + ProcHook::EXTENSION_CORE, + reinterpret_cast({{$base}}), + nullptr, + nullptr, {{end}} }, {{end}} @@ -862,6 +859,8 @@ VK_KHR_swapchain {{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 diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index 1301912dd6..02e60b7f9a 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,281 @@ namespace driver { namespace { +class CreateInfoWrapper { + public: + CreateInfoWrapper(VkPhysicalDevice physical_dev, + const VkDeviceCreateInfo& create_info, + const VkAllocationCallbacks& allocator); + ~CreateInfoWrapper(); + + VkResult validate(); + + const std::bitset& get_hook_extensions() const; + const std::bitset& get_hal_extensions() 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 hook_extensions_; + std::bitset hal_extensions_; +}; + +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& +CreateInfoWrapper::get_hook_extensions() const { + return hook_extensions_; +} + +const std::bitset& +CreateInfoWrapper::get_hal_extensions() const { + return hal_extensions_; +} + +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(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(header->next); + + instance_info_.pNext = header; + } else { + header = reinterpret_cast(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(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(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(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*, @@ -94,6 +370,21 @@ VKAPI_ATTR void DefaultFree(void*, void* ptr) { free(ptr); } +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() { @@ -205,6 +496,67 @@ PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) { : hook->disabled_proc; } +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(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( + 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); +} + void GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h index 73020371af..b3678dc242 100644 --- a/vulkan/libvulkan/driver.h +++ b/vulkan/libvulkan/driver.h @@ -109,6 +109,9 @@ VKAPI_ATTR PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const cha 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 CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice); +VKAPI_ATTR void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator); + 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 diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp index dd203c7829..81299fc28f 100644 --- a/vulkan/libvulkan/driver_gen.cpp +++ b/vulkan/libvulkan/driver_gen.cpp @@ -164,7 +164,7 @@ const ProcHook g_proc_hooks[] = { "vkCreateDevice", ProcHook::INSTANCE, ProcHook::EXTENSION_CORE, - reinterpret_cast(CreateDevice_Bottom), + reinterpret_cast(CreateDevice), nullptr, nullptr, }, @@ -204,7 +204,7 @@ const ProcHook g_proc_hooks[] = { "vkDestroyDevice", ProcHook::DEVICE, ProcHook::EXTENSION_CORE, - reinterpret_cast(DestroyDevice_Bottom), + reinterpret_cast(DestroyDevice), nullptr, nullptr, }, @@ -397,6 +397,7 @@ bool InitDriverTable(VkInstance instance, PFN_vkGetInstanceProcAddr get_proc) { 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); diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h index 4226a6374f..1eb7d79096 100644 --- a/vulkan/libvulkan/driver_gen.h +++ b/vulkan/libvulkan/driver_gen.h @@ -58,6 +58,7 @@ struct InstanceDriverTable { PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices; PFN_vkGetInstanceProcAddr GetInstanceProcAddr; PFN_vkCreateDevice CreateDevice; + PFN_vkEnumerateDeviceLayerProperties EnumerateDeviceLayerProperties; PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties; PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT; PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT; diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp index 1212f96dd4..0313f7e87e 100644 --- a/vulkan/libvulkan/loader.cpp +++ b/vulkan/libvulkan/loader.cpp @@ -163,17 +163,6 @@ struct Instance { InstanceExtensionSet enabled_extensions; }; -struct Device { - Device(Instance* instance_) : base(*instance_->alloc), instance(instance_) { - enabled_extensions.reset(); - } - - driver::DeviceData base; - - Instance* instance; - DeviceExtensionSet enabled_extensions; -}; - template struct HandleTraits {}; template <> @@ -184,18 +173,6 @@ template <> struct HandleTraits { typedef Instance LoaderObjectType; }; -template <> -struct HandleTraits { - typedef Device LoaderObjectType; -}; -template <> -struct HandleTraits { - typedef Device LoaderObjectType; -}; -template <> -struct HandleTraits { - typedef Device LoaderObjectType; -}; template typename HandleTraits::LoaderObjectType& GetDispatchParent( @@ -218,16 +195,6 @@ typename HandleTraits::LoaderObjectType& GetDispatchParent( // ----------------------------------------------------------------------------- -void DestroyDevice(Device* device, VkDevice vkdevice) { - const auto& instance = *device->instance; - - if (vkdevice != VK_NULL_HANDLE && device->base.driver.DestroyDevice) - device->base.driver.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. @@ -522,105 +489,6 @@ VkResult EnumerateDeviceExtensionProperties_Bottom( return *properties_count < num_extensions ? VK_INCOMPLETE : 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( - 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; - } - } - } - - // Unlike instance->enabled_extensions, device->enabled_extensions maps to - // hook extensions. - auto& hook_exts = device->base.hook_extensions; - for (size_t i = 0; i < device->enabled_extensions.size(); i++) { - if (device->enabled_extensions[i]) { - auto bit = DeviceExtensionToProcHookExtension( - static_cast(i)); - if (bit != driver::ProcHook::EXTENSION_UNKNOWN) - hook_exts.set(bit); - } - } - - auto& hal_exts = device->base.hal_extensions; - hal_exts = hook_exts; - // map VK_KHR_swapchain to VK_ANDROID_native_buffer - if (hal_exts[driver::ProcHook::KHR_swapchain]) { - hal_exts.reset(driver::ProcHook::KHR_swapchain); - hal_exts.set(driver::ProcHook::ANDROID_native_buffer); - } - - driver_create_info.enabledExtensionCount = num_driver_extensions; - driver_create_info.ppEnabledExtensionNames = driver_extensions; - VkDevice drv_device; - VkResult result = instance.base.driver.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; - } - - if (!driver::InitDriverTable(drv_device, - instance.base.get_device_proc_addr)) { - DestroyDevice(device, drv_device); - return VK_ERROR_INITIALIZATION_FAILED; - } - - *device_out = drv_device; - return VK_SUCCESS; -} - void DestroyInstance_Bottom(VkInstance vkinstance, const VkAllocationCallbacks* allocator) { Instance& instance = GetDispatchParent(vkinstance); @@ -634,10 +502,6 @@ void DestroyInstance_Bottom(VkInstance vkinstance, DestroyInstance(&instance, allocator, vkinstance); } -void DestroyDevice_Bottom(VkDevice vkdevice, const VkAllocationCallbacks*) { - DestroyDevice(&GetDispatchParent(vkdevice), vkdevice); -} - // ----------------------------------------------------------------------------- const VkAllocationCallbacks* GetAllocator(VkInstance vkinstance) { @@ -645,7 +509,7 @@ const VkAllocationCallbacks* GetAllocator(VkInstance vkinstance) { } const VkAllocationCallbacks* GetAllocator(VkDevice vkdevice) { - return GetDispatchParent(vkdevice).instance->alloc; + return &driver::GetData(vkdevice).allocator; } VkInstance GetDriverInstance(VkInstance instance) { diff --git a/vulkan/libvulkan/loader.h b/vulkan/libvulkan/loader.h index 823c4467ff..8c8c8fc0c3 100644 --- a/vulkan/libvulkan/loader.h +++ b/vulkan/libvulkan/loader.h @@ -50,9 +50,7 @@ bool InitLoader(hwvulkan_device_t* dev); VKAPI_ATTR VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, const VkAllocationCallbacks* allocator, VkInstance* vkinstance); VKAPI_ATTR VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance, uint32_t* pdev_count, VkPhysicalDevice* pdevs); VKAPI_ATTR VkResult EnumerateDeviceExtensionProperties_Bottom(VkPhysicalDevice pdev, const char* layer_name, uint32_t* properties_count, VkExtensionProperties* 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 void DestroyDevice_Bottom(VkDevice device, const VkAllocationCallbacks* pAllocator); // clang-format on const VkAllocationCallbacks* GetAllocator(VkInstance instance); -- cgit v1.2.3-59-g8ed1b From 01cf305325f3789c573d7eff435e409f04677c66 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 24 Mar 2016 16:16:21 +0800 Subject: vulkan: rework EnumerateDeviceExtensionProperties_Bottom The reworked driver::EnumerateDeviceExtensionProperties will simply return all extensions enumerated by HAL, with VK_ANDROID_native_buffer replaced by VK_KHR_swapchain. This allows extensions unknown to the loader to be enumerated. Change-Id: Iceed8ee3f16a968d005ae3ba42f1bd1839c2ab9f --- vulkan/libvulkan/code-generator.tmpl | 10 +++++----- vulkan/libvulkan/driver.cpp | 31 +++++++++++++++++++++++++++++++ vulkan/libvulkan/driver.h | 2 ++ vulkan/libvulkan/driver_gen.cpp | 2 +- vulkan/libvulkan/loader.cpp | 34 ---------------------------------- vulkan/libvulkan/loader.h | 1 - 6 files changed, 39 insertions(+), 41 deletions(-) (limited to 'vulkan/libvulkan/driver.cpp') diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl index 3a6f0a97b5..e06ce121ae 100644 --- a/vulkan/libvulkan/code-generator.tmpl +++ b/vulkan/libvulkan/code-generator.tmpl @@ -790,12 +790,12 @@ VK_KHR_swapchain {{else}} ProcHook::EXTENSION_CORE, - {{if eq $.Name "vkGetInstanceProcAddr"}} - reinterpret_cast({{$base}}), - {{else if eq $.Name "vkCreateDevice"}} - reinterpret_cast({{$base}}), - {{else}} + {{if eq $.Name "vkDestroyInstance"}} reinterpret_cast({{$base}}_Bottom), + {{else if eq $.Name "vkEnumeratePhysicalDevices"}} + reinterpret_cast({{$base}}_Bottom), + {{else}} + reinterpret_cast({{$base}}), {{end}} nullptr, nullptr, diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index 02e60b7f9a..b20962fbeb 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -496,6 +496,37 @@ PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) { : hook->disabled_proc; } +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 CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h index b3678dc242..f8daa00a9b 100644 --- a/vulkan/libvulkan/driver.h +++ b/vulkan/libvulkan/driver.h @@ -109,6 +109,8 @@ VKAPI_ATTR PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const cha 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 CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice); VKAPI_ATTR void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator); diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp index 81299fc28f..e88299de5e 100644 --- a/vulkan/libvulkan/driver_gen.cpp +++ b/vulkan/libvulkan/driver_gen.cpp @@ -236,7 +236,7 @@ const ProcHook g_proc_hooks[] = { "vkEnumerateDeviceExtensionProperties", ProcHook::INSTANCE, ProcHook::EXTENSION_CORE, - reinterpret_cast(EnumerateDeviceExtensionProperties_Bottom), + reinterpret_cast(EnumerateDeviceExtensionProperties), nullptr, nullptr, }, diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp index 0313f7e87e..34ec77cd79 100644 --- a/vulkan/libvulkan/loader.cpp +++ b/vulkan/libvulkan/loader.cpp @@ -455,40 +455,6 @@ VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance, return VK_SUCCESS; } -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( - 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; -} - void DestroyInstance_Bottom(VkInstance vkinstance, const VkAllocationCallbacks* allocator) { Instance& instance = GetDispatchParent(vkinstance); diff --git a/vulkan/libvulkan/loader.h b/vulkan/libvulkan/loader.h index 8c8c8fc0c3..38bdaa415b 100644 --- a/vulkan/libvulkan/loader.h +++ b/vulkan/libvulkan/loader.h @@ -49,7 +49,6 @@ bool InitLoader(hwvulkan_device_t* dev); // clang-format off VKAPI_ATTR VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, const VkAllocationCallbacks* allocator, VkInstance* vkinstance); VKAPI_ATTR VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance, uint32_t* pdev_count, VkPhysicalDevice* pdevs); -VKAPI_ATTR VkResult EnumerateDeviceExtensionProperties_Bottom(VkPhysicalDevice pdev, const char* layer_name, uint32_t* properties_count, VkExtensionProperties* properties); VKAPI_ATTR void DestroyInstance_Bottom(VkInstance vkinstance, const VkAllocationCallbacks* allocator); // clang-format on -- cgit v1.2.3-59-g8ed1b From ff4a6c772aaf3ff0b71348647330031a059b1f51 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 24 Mar 2016 16:05:56 +0800 Subject: vulkan: rework CreateInstance_Bottom and related ones The reworked driver::CreateInstance will - call HAL's EnumerateInstanceExtensionProperties and filter out extensions unknown to HAL, if there is any extension enabled. We do not expect or enumerate any HAL layer yet as that requires some works to layers_extensions.cpp. The reworked driver::EnumerateInstanceExtensionProperties instead will return all extensions enumerated by HAL, after prepending VK_KHR_surface and VK_KHR_android_surface to them. This allows extensions unknown to the loader to be enumerated. Change-Id: I73b496582a773e06c7b79f0c5c166700737f2953 --- vulkan/libvulkan/code-generator.tmpl | 19 +- vulkan/libvulkan/driver.cpp | 162 +++++++++++- vulkan/libvulkan/driver.h | 6 + vulkan/libvulkan/driver_gen.cpp | 6 +- vulkan/libvulkan/loader.cpp | 499 +---------------------------------- vulkan/libvulkan/loader.h | 8 - 6 files changed, 171 insertions(+), 529 deletions(-) (limited to 'vulkan/libvulkan/driver.cpp') diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl index e06ce121ae..d5995a5f52 100644 --- a/vulkan/libvulkan/code-generator.tmpl +++ b/vulkan/libvulkan/code-generator.tmpl @@ -601,6 +601,7 @@ VK_KHR_swapchain {{/* 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 @@ -612,9 +613,6 @@ VK_KHR_swapchain {{else if eq $.Name "vkEnumerateInstanceExtensionProperties"}}true {{else if eq $.Name "vkEnumerateDeviceExtensionProperties"}}true - {{/* We cache physical devices in loader.cpp */}} - {{else if eq $.Name "vkEnumeratePhysicalDevices"}}true - {{else if eq $.Name "vkGetInstanceProcAddr"}}true {{else if eq $.Name "vkGetDeviceProcAddr"}}true @@ -749,11 +747,7 @@ VK_KHR_swapchain "{{$.Name}}", ProcHook::GLOBAL, ProcHook::EXTENSION_CORE, - {{if eq $.Name "vkEnumerateInstanceExtensionProperties"}} - reinterpret_cast({{$base}}), - {{else}} - reinterpret_cast({{$base}}_Bottom), - {{end}} + reinterpret_cast({{$base}}), nullptr, nullptr, }, @@ -789,14 +783,7 @@ VK_KHR_swapchain {{end}} {{else}} ProcHook::EXTENSION_CORE, - - {{if eq $.Name "vkDestroyInstance"}} - reinterpret_cast({{$base}}_Bottom), - {{else if eq $.Name "vkEnumeratePhysicalDevices"}} - reinterpret_cast({{$base}}_Bottom), - {{else}} - reinterpret_cast({{$base}}), - {{end}} + reinterpret_cast({{$base}}), nullptr, nullptr, {{end}} diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index b20962fbeb..f2f1d08656 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,9 @@ 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); @@ -57,6 +61,7 @@ class CreateInfoWrapper { const std::bitset& get_hook_extensions() const; const std::bitset& get_hal_extensions() const; + explicit operator const VkInstanceCreateInfo*() const; explicit operator const VkDeviceCreateInfo*() const; private: @@ -98,6 +103,18 @@ class CreateInfoWrapper { std::bitset 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) @@ -135,6 +152,10 @@ CreateInfoWrapper::get_hal_extensions() const { return hal_extensions_; } +CreateInfoWrapper::operator const VkInstanceCreateInfo*() const { + return &instance_info_; +} + CreateInfoWrapper::operator const VkDeviceCreateInfo*() const { return &dev_info_; } @@ -370,6 +391,22 @@ VKAPI_ATTR void DefaultFree(void*, void* 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), @@ -413,11 +450,6 @@ bool OpenHAL() { return false; } - if (!InitLoader(device)) { - device->common.close(&device->common); - return false; - } - g_hwdevice = device; return true; @@ -496,6 +528,42 @@ PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* pName) { : hook->disabled_proc; } +VkResult EnumerateInstanceExtensionProperties( + const char* pLayerName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties) { + static const std::array 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(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, @@ -527,6 +595,75 @@ VkResult EnumerateDeviceExtensionProperties( 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(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( + 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( + 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, @@ -588,6 +725,21 @@ void DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) { 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, diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h index f8daa00a9b..4cc3ee7df9 100644 --- a/vulkan/libvulkan/driver.h +++ b/vulkan/libvulkan/driver.h @@ -27,6 +27,7 @@ #include "api_gen.h" #include "driver_gen.h" +#include "debug_report.h" namespace vulkan { @@ -81,6 +82,8 @@ struct InstanceData { InstanceDriverTable driver; PFN_vkGetDeviceProcAddr get_device_proc_addr; + + DebugReportCallbackList debug_report_callbacks; }; struct DeviceData { @@ -111,9 +114,12 @@ VKAPI_ATTR VkResult EnumerateInstanceExtensionProperties(const char* pLayerName, 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 diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp index e88299de5e..a991f85578 100644 --- a/vulkan/libvulkan/driver_gen.cpp +++ b/vulkan/libvulkan/driver_gen.cpp @@ -172,7 +172,7 @@ const ProcHook g_proc_hooks[] = { "vkCreateInstance", ProcHook::GLOBAL, ProcHook::EXTENSION_CORE, - reinterpret_cast(CreateInstance_Bottom), + reinterpret_cast(CreateInstance), nullptr, nullptr, }, @@ -212,7 +212,7 @@ const ProcHook g_proc_hooks[] = { "vkDestroyInstance", ProcHook::INSTANCE, ProcHook::EXTENSION_CORE, - reinterpret_cast(DestroyInstance_Bottom), + reinterpret_cast(DestroyInstance), nullptr, nullptr, }, @@ -252,7 +252,7 @@ const ProcHook g_proc_hooks[] = { "vkEnumeratePhysicalDevices", ProcHook::INSTANCE, ProcHook::EXTENSION_CORE, - reinterpret_cast(EnumeratePhysicalDevices_Bottom), + reinterpret_cast(EnumeratePhysicalDevices), nullptr, nullptr, }, diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp index 34ec77cd79..57bfc81e46 100644 --- a/vulkan/libvulkan/loader.cpp +++ b/vulkan/libvulkan/loader.cpp @@ -14,464 +14,12 @@ * limitations under the License. */ -// module header #include "loader.h" -#include "driver.h" -// standard C headers -#include -#include -#include -#include -#include -#include -#include -// standard C++ headers -#include -#include -#include -#include -#include -#include -// platform/library headers -#include -#include -#include -#include -#include - -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 CallbackAllocator { - public: - typedef T value_type; - - CallbackAllocator(const VkAllocationCallbacks* alloc_input) - : alloc(alloc_input) {} - - template - CallbackAllocator(const CallbackAllocator& 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(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 -bool operator==(const CallbackAllocator& alloc1, - const CallbackAllocator& alloc2) { - return alloc1.alloc == alloc2.alloc; -} -template -bool operator!=(const CallbackAllocator& alloc1, - const CallbackAllocator& alloc2) { - return !(alloc1 == alloc2); -} - -template -using Vector = std::vector>; - -typedef std::basic_string, CallbackAllocator> - String; - -// ---------------------------------------------------------------------------- -// Global Data and Initialization - -hwvulkan_device_t* g_hwdevice = nullptr; -InstanceExtensionSet g_driver_instance_extensions; - -bool LoadVulkanHAL() { - VkResult vkresult; - uint32_t count; - if ((vkresult = g_hwdevice->EnumerateInstanceExtensionProperties( - nullptr, &count, nullptr)) != VK_SUCCESS) { - ALOGE("driver EnumerateInstanceExtensionProperties failed: %d", - vkresult); - return false; - } - VkExtensionProperties* extensions = static_cast( - alloca(count * sizeof(VkExtensionProperties))); - if ((vkresult = g_hwdevice->EnumerateInstanceExtensionProperties( - nullptr, &count, extensions)) != VK_SUCCESS) { - ALOGE("driver EnumerateInstanceExtensionProperties failed: %d", - vkresult); - return false; - } - 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); - - return true; -} - -// ----------------------------------------------------------------------------- - -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(); - } - - ~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; -}; - -template -struct HandleTraits {}; -template <> -struct HandleTraits { - typedef Instance LoaderObjectType; -}; -template <> -struct HandleTraits { - typedef Instance LoaderObjectType; -}; - -template -typename HandleTraits::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::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(&base); - uintptr_t object_addr = base_addr - kBaseOffset; - return *reinterpret_cast(object_addr); -} - -// ----------------------------------------------------------------------------- - -/* - * 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( - static_cast(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( - static_cast(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->base.driver.DestroyInstance) - instance->base.driver.DestroyInstance(vkinstance, allocator); - - instance->~Instance(); - allocator->pfnFree(allocator->pUserData, instance); -} - -driver::ProcHook::Extension InstanceExtensionToProcHookExtension( - InstanceExtension id) { - switch (id) { - case kKHR_surface: - return driver::ProcHook::KHR_surface; - case kKHR_android_surface: - return driver::ProcHook::KHR_android_surface; - case kEXT_debug_report: - return driver::ProcHook::EXT_debug_report; - default: - return driver::ProcHook::EXTENSION_UNKNOWN; - } -} - -driver::ProcHook::Extension DeviceExtensionToProcHookExtension( - DeviceExtension id) { - switch (id) { - case kKHR_swapchain: - return driver::ProcHook::KHR_swapchain; - case kANDROID_native_buffer: - return driver::ProcHook::ANDROID_native_buffer; - default: - return driver::ProcHook::EXTENSION_UNKNOWN; - } -} - -} // anonymous namespace namespace vulkan { -// ----------------------------------------------------------------------------- -// "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 = &driver::GetDefaultAllocator(); - - 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; - bool enable_kEXT_debug_report = false; - for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) { - const char* name = create_info->ppEnabledExtensionNames[i]; - InstanceExtension id = InstanceExtensionFromName(name); - 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) { - enable_kEXT_debug_report = true; - continue; - } - } - } - - auto& hal_exts = instance.base.hal_extensions; - for (size_t i = 0; i < instance.enabled_extensions.size(); i++) { - if (instance.enabled_extensions[i]) { - auto bit = InstanceExtensionToProcHookExtension( - static_cast(i)); - if (bit != driver::ProcHook::EXTENSION_UNKNOWN) - hal_exts.set(bit); - } - } - - auto& hook_exts = instance.base.hook_extensions; - hook_exts = hal_exts; - if (enable_kEXT_debug_report) - hook_exts.set(driver::ProcHook::EXT_debug_report); - - VkInstanceCreateInfo driver_create_info = *create_info; - driver_create_info.pNext = StripCreateExtensions(create_info->pNext); - driver_create_info.enabledLayerCount = 0; - 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( - 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 (!driver::InitDriverTable(drv_instance, - g_hwdevice->GetInstanceProcAddr)) { - DestroyInstance(&instance, allocator, drv_instance); - return VK_ERROR_INITIALIZATION_FAILED; - } - - instance.base.get_device_proc_addr = - reinterpret_cast( - g_hwdevice->GetInstanceProcAddr(drv_instance, - "vkGetDeviceProcAddr")); - if (!instance.base.get_device_proc_addr) { - DestroyInstance(&instance, allocator, drv_instance); - return VK_ERROR_INITIALIZATION_FAILED; - } - - uint32_t num_physical_devices = 0; - result = instance.base.driver.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.base.driver.EnumeratePhysicalDevices( - drv_instance, &num_physical_devices, instance.physical_devices); - if (result != VK_SUCCESS) { - DestroyInstance(&instance, allocator, drv_instance); - return VK_ERROR_INITIALIZATION_FAILED; - } - - Vector extensions( - Vector::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.base.driver.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.base.driver.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 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 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); -} - -// ----------------------------------------------------------------------------- - const VkAllocationCallbacks* GetAllocator(VkInstance vkinstance) { - return GetDispatchParent(vkinstance).alloc; + return &driver::GetData(vkinstance).allocator; } const VkAllocationCallbacks* GetAllocator(VkDevice vkdevice) { @@ -495,50 +43,7 @@ const driver::DeviceDriverTable& GetDriverDispatch(VkQueue queue) { } DebugReportCallbackList& GetDebugReportCallbacks(VkInstance instance) { - return GetDispatchParent(instance).debug_report_callbacks; -} - -bool InitLoader(hwvulkan_device_t* dev) { - if (!g_hwdevice) { - g_hwdevice = dev; - if (!LoadVulkanHAL()) - g_hwdevice = nullptr; - } - - return (g_hwdevice != nullptr); -} - -namespace driver { - -VkResult EnumerateInstanceExtensionProperties( - const char* pLayerName, - uint32_t* pPropertyCount, - VkExtensionProperties* pProperties) { - (void)pLayerName; - - VkExtensionProperties* available = static_cast( - 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; + return driver::GetData(instance).debug_report_callbacks; } -} // namespace driver - } // namespace vulkan diff --git a/vulkan/libvulkan/loader.h b/vulkan/libvulkan/loader.h index 38bdaa415b..a150dc52ae 100644 --- a/vulkan/libvulkan/loader.h +++ b/vulkan/libvulkan/loader.h @@ -44,14 +44,6 @@ typedef std::bitset DeviceExtensionSet; // ----------------------------------------------------------------------------- // loader.cpp -bool InitLoader(hwvulkan_device_t* dev); - -// clang-format off -VKAPI_ATTR VkResult CreateInstance_Bottom(const VkInstanceCreateInfo* create_info, const VkAllocationCallbacks* allocator, VkInstance* vkinstance); -VKAPI_ATTR VkResult EnumeratePhysicalDevices_Bottom(VkInstance vkinstance, uint32_t* pdev_count, VkPhysicalDevice* pdevs); -VKAPI_ATTR void DestroyInstance_Bottom(VkInstance vkinstance, const VkAllocationCallbacks* allocator); -// clang-format on - const VkAllocationCallbacks* GetAllocator(VkInstance instance); const VkAllocationCallbacks* GetAllocator(VkDevice device); VkInstance GetDriverInstance(VkInstance instance); -- cgit v1.2.3-59-g8ed1b From 4a6a91647c57abb5c06cde57c57afe944f8cefa4 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sat, 26 Mar 2016 07:17:34 +0800 Subject: vulkan: use driver::GetData everywhere Move away from the one-liners defined in loader.cpp. Change-Id: I73c39cbe21aa3b2079f67590bb40f0cd55563f84 --- vulkan/libvulkan/code-generator.tmpl | 1 - vulkan/libvulkan/debug_report.cpp | 46 +++++++++++++++++------------------- vulkan/libvulkan/driver.cpp | 1 - vulkan/libvulkan/driver.h | 1 + vulkan/libvulkan/driver_gen.cpp | 1 - vulkan/libvulkan/swapchain.cpp | 24 +++++++++---------- 6 files changed, 35 insertions(+), 39 deletions(-) (limited to 'vulkan/libvulkan/driver.cpp') diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl index 5b6c6d2271..afe0d8417c 100644 --- a/vulkan/libvulkan/code-generator.tmpl +++ b/vulkan/libvulkan/code-generator.tmpl @@ -219,7 +219,6 @@ bool InitDriverTable(VkDevice dev, PFN_vkGetDeviceProcAddr get_proc); #include ¶ #include "driver.h" -#include "loader.h" ¶ namespace vulkan {« namespace driver {« diff --git a/vulkan/libvulkan/debug_report.cpp b/vulkan/libvulkan/debug_report.cpp index 5055640947..c4a1174191 100644 --- a/vulkan/libvulkan/debug_report.cpp +++ b/vulkan/libvulkan/debug_report.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "loader.h" +#include "driver.h" namespace vulkan { namespace driver { @@ -26,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; } @@ -69,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); } @@ -101,7 +99,7 @@ VkResult CreateDebugReportCallbackEXT( 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); } @@ -109,8 +107,8 @@ 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(VkInstance instance, @@ -121,14 +119,14 @@ void DebugReportMessageEXT(VkInstance instance, 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); + 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 diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index f2f1d08656..007c54dd9d 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -23,7 +23,6 @@ #include #include "driver.h" -#include "loader.h" // #define ENABLE_ALLOC_CALLSTACKS 1 #if ENABLE_ALLOC_CALLSTACKS diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h index 4cc3ee7df9..22db93f577 100644 --- a/vulkan/libvulkan/driver.h +++ b/vulkan/libvulkan/driver.h @@ -28,6 +28,7 @@ #include "api_gen.h" #include "driver_gen.h" #include "debug_report.h" +#include "swapchain.h" namespace vulkan { diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp index 78a952abf3..8b816bac96 100644 --- a/vulkan/libvulkan/driver_gen.cpp +++ b/vulkan/libvulkan/driver_gen.cpp @@ -21,7 +21,6 @@ #include #include "driver.h" -#include "loader.h" namespace vulkan { namespace driver { diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp index 4aa1ed6508..bda6676285 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -21,7 +21,7 @@ #include #include -#include "loader.h" +#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 @@ -98,9 +98,9 @@ template std::shared_ptr InitSharedPtr(Host host, T* obj) { try { obj->common.incRef(&obj->common); - return std::shared_ptr( - obj, NativeBaseDeleter(), - VulkanAllocator(*GetAllocator(host), AllocScope::kScope)); + return std::shared_ptr(obj, NativeBaseDeleter(), + VulkanAllocator(GetData(host).allocator, + AllocScope::kScope)); } catch (std::bad_alloc&) { obj->common.decRef(&obj->common); return nullptr; @@ -231,7 +231,7 @@ VkResult CreateAndroidSurfaceKHR( 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); @@ -274,7 +274,7 @@ void DestroySurfaceKHR(VkInstance instance, 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); } @@ -411,7 +411,7 @@ VkResult CreateSwapchainKHR(VkDevice device, 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", @@ -432,7 +432,7 @@ VkResult CreateSwapchainKHR(VkDevice device, // -- Configure the native window -- Surface& surface = *SurfaceFromHandle(create_info->surface); - const auto& dispatch = GetDriverDispatch(device); + const auto& dispatch = GetData(device).driver; int native_format = HAL_PIXEL_FORMAT_RGBA_8888; switch (create_info->imageFormat) { @@ -680,7 +680,7 @@ VKAPI_ATTR void DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain_handle, const VkAllocationCallbacks* allocator) { - const auto& dispatch = GetDriverDispatch(device); + const auto& dispatch = GetData(device).driver; Swapchain* swapchain = SwapchainFromHandle(swapchain_handle); const std::shared_ptr& window = swapchain->surface.window; @@ -698,7 +698,7 @@ void DestroySwapchainKHR(VkDevice device, } if (!allocator) - allocator = GetAllocator(device); + allocator = &GetData(device).allocator; swapchain->~Swapchain(); allocator->pfnFree(allocator->pUserData, swapchain); } @@ -773,7 +773,7 @@ VkResult AcquireNextImageKHR(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, @@ -800,7 +800,7 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { present_info->sType); ALOGV_IF(present_info->pNext, "VkPresentInfo::pNext != NULL"); - const auto& 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 = -- cgit v1.2.3-59-g8ed1b