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