From 3251ed84052ced22d1e4c285524a835a82f7dd12 Mon Sep 17 00:00:00 2001 From: Michael Jurka Date: Wed, 5 Apr 2017 09:52:55 -0700 Subject: Refactor Vulkan support to support Fuchsia - Refactor runtime lookup of Vulkan functions - Support Magma surfaces - Add build flags to toggle Vulkan support BUG=skia: Change-Id: Ic71965c453507882521443006c4155c7481a9a3f Reviewed-on: https://skia-review.googlesource.com/9342 Commit-Queue: Greg Daniel Commit-Queue: Mike Klein Reviewed-by: Mike Klein Reviewed-by: Greg Daniel Reviewed-by: Michael Jurka Reviewed-by: Mike Klein --- .gitignore | 3 + BUILD.gn | 22 ++- include/gpu/vk/GrVkBackendContext.h | 8 +- include/gpu/vk/GrVkDefines.h | 18 ++- include/gpu/vk/GrVkInterface.h | 24 ++- src/gpu/vk/GrVkBackendContext.cpp | 83 +++++++--- src/gpu/vk/GrVkExtensions.cpp | 18 ++- src/gpu/vk/GrVkExtensions.h | 6 +- src/gpu/vk/GrVkGpu.cpp | 2 +- src/gpu/vk/GrVkInterface.cpp | 302 ++++++++++++++++++------------------ 10 files changed, 283 insertions(+), 203 deletions(-) diff --git a/.gitignore b/.gitignore index f29211134b..ec250f1494 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,6 @@ bin/gn bin/gn.exe bin/clang-format bin/clang-format.exe + +vulkan-out +gl-out \ No newline at end of file diff --git a/BUILD.gn b/BUILD.gn index 1801c32531..8bbd12a8b8 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -37,6 +37,7 @@ declare_args() { skia_enable_tools = is_skia_dev_build skia_enable_vulkan_debug_layers = is_skia_dev_build && is_debug skia_vulkan_sdk = getenv("VULKAN_SDK") + skia_link_with_vulkan = true } declare_args() { skia_use_dng_sdk = !is_fuchsia && skia_use_libjpeg_turbo && skia_use_zlib @@ -47,6 +48,11 @@ declare_args() { } else { skia_use_vulkan = skia_vulkan_sdk != "" } + if (is_win) { + skia_vulkan_headers_path = "$skia_vulkan_sdk/Include" + } else { + skia_vulkan_headers_path = "$skia_vulkan_sdk/include" + } } # Our tools require static linking (they use non-exported symbols). @@ -133,22 +139,26 @@ config("skia_private") { libs = [] lib_dirs = [] if (skia_use_vulkan) { + include_dirs += [ skia_vulkan_headers_path ] + if (skia_vulkan_sdk != "" && !is_android) { if (is_win) { - include_dirs += [ "$skia_vulkan_sdk/Include/" ] lib_dirs += [ "$skia_vulkan_sdk/Bin", "$skia_vulkan_sdk/Lib", ] } else { - include_dirs += [ "$skia_vulkan_sdk/include/" ] lib_dirs += [ "$skia_vulkan_sdk/lib/" ] } } - if (is_win) { - libs += [ "vulkan-1.lib" ] - } else { - libs += [ "vulkan" ] + + if (skia_link_with_vulkan) { + defines += [ "SK_LINK_WITH_VULKAN" ] + if (is_win) { + libs += [ "vulkan-1.lib" ] + } else { + libs += [ "vulkan" ] + } } } if (skia_enable_gpu) { diff --git a/include/gpu/vk/GrVkBackendContext.h b/include/gpu/vk/GrVkBackendContext.h index 5e51beea6b..5ae7b31656 100644 --- a/include/gpu/vk/GrVkBackendContext.h +++ b/include/gpu/vk/GrVkBackendContext.h @@ -11,8 +11,7 @@ #include "SkRefCnt.h" #include "vk/GrVkDefines.h" - -struct GrVkInterface; +#include "vk/GrVkInterface.h" enum GrVkExtensionFlags { kEXT_debug_report_GrVkExtensionFlag = 0x0001, @@ -51,10 +50,13 @@ struct GrVkBackendContext : public SkRefCnt { uint32_t queueFamilyIndex)>; // Helper function to create the default Vulkan objects needed by the GrVkGpu object + // If getProc is NULL, a default getProc will be constructed if we are statically linking + // against Vulkan. // If presentQueueIndex is non-NULL, will try to set up presentQueue as part of device // creation using the platform-specific canPresent() function. static const GrVkBackendContext* Create(uint32_t* presentQueueIndex = nullptr, - CanPresentFn = CanPresentFn()); + CanPresentFn = CanPresentFn(), + GrVkInterface::GetProc getProc = nullptr); ~GrVkBackendContext() override; }; diff --git a/include/gpu/vk/GrVkDefines.h b/include/gpu/vk/GrVkDefines.h index 9caf2d75e5..ff8f2131f6 100644 --- a/include/gpu/vk/GrVkDefines.h +++ b/include/gpu/vk/GrVkDefines.h @@ -10,11 +10,23 @@ #define GrVkDefines_DEFINED #if defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_WIN32) -# define VK_USE_PLATFORM_WIN32_KHR +# if !defined(VK_USE_PLATFORM_WIN32_KHR) +# define VK_USE_PLATFORM_WIN32_KHR +# endif #elif defined(SK_BUILD_FOR_ANDROID) -# define VK_USE_PLATFORM_ANDROID_KHR +# if !defined(VK_USE_PLATFORM_ANDROID_KHR) +# define VK_USE_PLATFORM_ANDROID_KHR +# endif #elif defined(SK_BUILD_FOR_UNIX) -# define VK_USE_PLATFORM_XCB_KHR +# if defined(__Fuchsia__) +# if !defined(VK_USE_PLATFORM_MAGMA_KHR) +# define VK_USE_PLATFORM_MAGMA_KHR +# endif +# else +# if !defined(VK_USE_PLATFORM_XCB_KHR) +# define VK_USE_PLATFORM_XCB_KHR +# endif +# endif #endif #if defined(Bool) || defined(Status) || defined(True) || defined(False) diff --git a/include/gpu/vk/GrVkInterface.h b/include/gpu/vk/GrVkInterface.h index 9dc033392c..dca47ffc4c 100644 --- a/include/gpu/vk/GrVkInterface.h +++ b/include/gpu/vk/GrVkInterface.h @@ -14,20 +14,6 @@ //////////////////////////////////////////////////////////////////////////////// -/** - * The default interface is returned by GrVkCreateInterface. This function's - * implementation is platform-specific. - */ - -struct GrVkInterface; - -/** - * Creates a GrVkInterface. - */ -const GrVkInterface* GrVkCreateInterface(VkInstance instance, VkDevice device, - uint32_t extensionFlags); - - /** * GrContext uses the following interface to make all calls into Vulkan. When a * GrContext is created it is given a GrVkInterface. All functions that should be @@ -49,7 +35,15 @@ private: typedef SkRefCnt INHERITED; public: - GrVkInterface(); + using GetProc = std::function; + GrVkInterface(GetProc getProc, + VkInstance instance, + VkDevice device, + uint32_t extensionFlags); // Validates that the GrVkInterface supports its advertised standard. This means the necessary // function pointers have been initialized for Vulkan version. diff --git a/src/gpu/vk/GrVkBackendContext.cpp b/src/gpu/vk/GrVkBackendContext.cpp index 5a9de04d39..3b53f83687 100644 --- a/src/gpu/vk/GrVkBackendContext.cpp +++ b/src/gpu/vk/GrVkBackendContext.cpp @@ -38,9 +38,32 @@ const uint32_t kGrVkMinimumVersion = VK_MAKE_VERSION(1, 0, 3); const uint32_t kGrVkMinimumVersion = VK_MAKE_VERSION(1, 0, 8); #endif +#define ACQUIRE_VK_PROC(name, instance, device) \ + PFN_vk##name grVk##name = \ + reinterpret_cast(getProc("vk" #name, instance, device)); \ + if (grVk##name == nullptr) { \ + SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \ + return nullptr; \ + } + // Create the base Vulkan objects needed by the GrVkGpu object const GrVkBackendContext* GrVkBackendContext::Create(uint32_t* presentQueueIndexPtr, - CanPresentFn canPresent) { + CanPresentFn canPresent, + GrVkInterface::GetProc getProc) { +#ifdef SK_LINK_WITH_VULKAN + if (getProc == nullptr) { + getProc = [](const char* proc_name, + VkInstance instance, VkDevice device) { + if (device != VK_NULL_HANDLE) { + return vkGetDeviceProcAddr(device, proc_name); + } + return vkGetInstanceProcAddr(instance, proc_name); + }; + } +#else + SkASSERT(getProc != nullptr); +#endif + VkPhysicalDevice physDev; VkDevice device; VkInstance inst; @@ -56,7 +79,7 @@ const GrVkBackendContext* GrVkBackendContext::Create(uint32_t* presentQueueIndex kGrVkMinimumVersion, // apiVersion }; - GrVkExtensions extensions; + GrVkExtensions extensions(getProc); extensions.initInstance(kGrVkMinimumVersion); SkTArray instanceLayerNames; @@ -92,7 +115,7 @@ const GrVkBackendContext* GrVkBackendContext::Create(uint32_t* presentQueueIndex instanceExtensionNames.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); extensionFlags |= kKHR_android_surface_GrVkExtensionFlag; } -#elif defined(SK_BUILD_FOR_UNIX) +#elif defined(SK_BUILD_FOR_UNIX) && !defined(__Fuchsia__) if (extensions.hasInstanceExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME)) { instanceExtensionNames.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); extensionFlags |= kKHR_xcb_surface_GrVkExtensionFlag; @@ -110,40 +133,50 @@ const GrVkBackendContext* GrVkBackendContext::Create(uint32_t* presentQueueIndex instanceExtensionNames.begin(), // ppEnabledExtensionNames }; - err = vkCreateInstance(&instance_create, nullptr, &inst); + ACQUIRE_VK_PROC(CreateInstance, VK_NULL_HANDLE, VK_NULL_HANDLE); + err = grVkCreateInstance(&instance_create, nullptr, &inst); if (err < 0) { SkDebugf("vkCreateInstance failed: %d\n", err); return nullptr; } + ACQUIRE_VK_PROC(DestroyInstance, inst, VK_NULL_HANDLE); + ACQUIRE_VK_PROC(EnumeratePhysicalDevices, inst, VK_NULL_HANDLE); + ACQUIRE_VK_PROC(GetPhysicalDeviceQueueFamilyProperties, inst, VK_NULL_HANDLE); + ACQUIRE_VK_PROC(GetPhysicalDeviceFeatures, inst, VK_NULL_HANDLE); + ACQUIRE_VK_PROC(CreateDevice, inst, VK_NULL_HANDLE); + ACQUIRE_VK_PROC(GetDeviceQueue, inst, VK_NULL_HANDLE); + ACQUIRE_VK_PROC(DeviceWaitIdle, inst, VK_NULL_HANDLE); + ACQUIRE_VK_PROC(DestroyDevice, inst, VK_NULL_HANDLE); + uint32_t gpuCount; - err = vkEnumeratePhysicalDevices(inst, &gpuCount, nullptr); + err = grVkEnumeratePhysicalDevices(inst, &gpuCount, nullptr); if (err) { SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err); - vkDestroyInstance(inst, nullptr); + grVkDestroyInstance(inst, nullptr); return nullptr; } SkASSERT(gpuCount > 0); // Just returning the first physical device instead of getting the whole array. // TODO: find best match for our needs gpuCount = 1; - err = vkEnumeratePhysicalDevices(inst, &gpuCount, &physDev); + err = grVkEnumeratePhysicalDevices(inst, &gpuCount, &physDev); if (err) { SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err); - vkDestroyInstance(inst, nullptr); + grVkDestroyInstance(inst, nullptr); return nullptr; } // query to get the initial queue props size uint32_t queueCount; - vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr); + grVkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr); SkASSERT(queueCount >= 1); SkAutoMalloc queuePropsAlloc(queueCount * sizeof(VkQueueFamilyProperties)); // now get the actual queue props VkQueueFamilyProperties* queueProps = (VkQueueFamilyProperties*)queuePropsAlloc.get(); - vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, queueProps); + grVkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, queueProps); // iterate to find the graphics queue uint32_t graphicsQueueIndex = queueCount; @@ -190,7 +223,7 @@ const GrVkBackendContext* GrVkBackendContext::Create(uint32_t* presentQueueIndex // query to get the physical device properties VkPhysicalDeviceFeatures deviceFeatures; - vkGetPhysicalDeviceFeatures(physDev, &deviceFeatures); + grVkGetPhysicalDeviceFeatures(physDev, &deviceFeatures); // this looks like it would slow things down, // and we can't depend on it on all platforms deviceFeatures.robustBufferAccess = VK_FALSE; @@ -242,15 +275,25 @@ const GrVkBackendContext* GrVkBackendContext::Create(uint32_t* presentQueueIndex &deviceFeatures // ppEnabledFeatures }; - err = vkCreateDevice(physDev, &deviceInfo, nullptr, &device); + err = grVkCreateDevice(physDev, &deviceInfo, nullptr, &device); if (err) { SkDebugf("CreateDevice failed: %d\n", err); - vkDestroyInstance(inst, nullptr); + grVkDestroyInstance(inst, nullptr); + return nullptr; + } + + auto interface = + sk_make_sp(getProc, inst, device, extensionFlags); + if (!interface->validate(extensionFlags)) { + SkDebugf("Vulkan interface validation failed\n"); + grVkDeviceWaitIdle(device); + grVkDestroyDevice(device, nullptr); + grVkDestroyInstance(inst, nullptr); return nullptr; } VkQueue queue; - vkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue); + grVkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue); GrVkBackendContext* ctx = new GrVkBackendContext(); ctx->fInstance = inst; @@ -261,15 +304,19 @@ const GrVkBackendContext* GrVkBackendContext::Create(uint32_t* presentQueueIndex ctx->fMinAPIVersion = kGrVkMinimumVersion; ctx->fExtensions = extensionFlags; ctx->fFeatures = featureFlags; - ctx->fInterface.reset(GrVkCreateInterface(inst, device, extensionFlags)); + ctx->fInterface.reset(interface.release()); return ctx; } GrVkBackendContext::~GrVkBackendContext() { - vkDeviceWaitIdle(fDevice); - vkDestroyDevice(fDevice, nullptr); + if (fInterface == nullptr) { + return; + } + + fInterface->fFunctions.fDeviceWaitIdle(fDevice); + fInterface->fFunctions.fDestroyDevice(fDevice, nullptr); fDevice = VK_NULL_HANDLE; - vkDestroyInstance(fInstance, nullptr); + fInterface->fFunctions.fDestroyInstance(fInstance, nullptr); fInstance = VK_NULL_HANDLE; } diff --git a/src/gpu/vk/GrVkExtensions.cpp b/src/gpu/vk/GrVkExtensions.cpp index 03b453090f..17737f1799 100644 --- a/src/gpu/vk/GrVkExtensions.cpp +++ b/src/gpu/vk/GrVkExtensions.cpp @@ -30,17 +30,21 @@ static int find_string(const SkTArray& strings, const char ext[]) { return idx; } -#define GET_PROC_LOCAL(inst, F) PFN_vk ## F F = (PFN_vk ## F) vkGetInstanceProcAddr(inst, "vk" #F) +#define GET_PROC_LOCAL(F, inst, device) PFN_vk ## F F = (PFN_vk ## F) fGetProc("vk" #F, inst, device) static uint32_t remove_patch_version(uint32_t specVersion) { return (specVersion >> 12) << 12; } bool GrVkExtensions::initInstance(uint32_t specVersion) { + if (fGetProc == nullptr) { + return false; + } + uint32_t nonPatchVersion = remove_patch_version(specVersion); - GET_PROC_LOCAL(nullptr, EnumerateInstanceExtensionProperties); - GET_PROC_LOCAL(nullptr, EnumerateInstanceLayerProperties); + GET_PROC_LOCAL(EnumerateInstanceExtensionProperties, VK_NULL_HANDLE, VK_NULL_HANDLE); + GET_PROC_LOCAL(EnumerateInstanceLayerProperties, VK_NULL_HANDLE, VK_NULL_HANDLE); SkTLessFunctionToFunctorAdaptor cmp; @@ -126,10 +130,14 @@ bool GrVkExtensions::initInstance(uint32_t specVersion) { } bool GrVkExtensions::initDevice(uint32_t specVersion, VkInstance inst, VkPhysicalDevice physDev) { + if (fGetProc == nullptr) { + return false; + } + uint32_t nonPatchVersion = remove_patch_version(specVersion); - GET_PROC_LOCAL(inst, EnumerateDeviceExtensionProperties); - GET_PROC_LOCAL(inst, EnumerateDeviceLayerProperties); + GET_PROC_LOCAL(EnumerateDeviceExtensionProperties, inst, VK_NULL_HANDLE); + GET_PROC_LOCAL(EnumerateDeviceLayerProperties, inst, VK_NULL_HANDLE); SkTLessFunctionToFunctorAdaptor cmp; diff --git a/src/gpu/vk/GrVkExtensions.h b/src/gpu/vk/GrVkExtensions.h index 2decd15bef..8de28f4d49 100644 --- a/src/gpu/vk/GrVkExtensions.h +++ b/src/gpu/vk/GrVkExtensions.h @@ -11,6 +11,7 @@ #include "../private/SkTArray.h" #include "SkString.h" #include "vk/GrVkDefines.h" +#include "vk/GrVkInterface.h" /** * This helper queries the Vulkan driver for available extensions and layers, remembers them, @@ -18,7 +19,9 @@ */ class SK_API GrVkExtensions { public: - GrVkExtensions() : fInstanceExtensionStrings(new SkTArray) + GrVkExtensions(GrVkInterface::GetProc getProc) + : fGetProc(getProc) + , fInstanceExtensionStrings(new SkTArray) , fDeviceExtensionStrings(new SkTArray) , fInstanceLayerStrings(new SkTArray) , fDeviceLayerStrings(new SkTArray) {} @@ -37,6 +40,7 @@ public: void print(const char* sep = "\n") const; private: + GrVkInterface::GetProc fGetProc; std::unique_ptr> fInstanceExtensionStrings; std::unique_ptr> fDeviceExtensionStrings; std::unique_ptr> fInstanceLayerStrings; diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index 77816e00f7..ed64590c74 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -1380,7 +1380,7 @@ inline bool can_copy_image(const GrSurface* dst, } } - // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src + // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src // as image usage flags. if (src->origin() == dst->origin() && GrBytesPerPixel(src->config()) == GrBytesPerPixel(dst->config())) { diff --git a/src/gpu/vk/GrVkInterface.cpp b/src/gpu/vk/GrVkInterface.cpp index 34f12b4fed..b08f7ba851 100644 --- a/src/gpu/vk/GrVkInterface.cpp +++ b/src/gpu/vk/GrVkInterface.cpp @@ -9,163 +9,163 @@ #include "vk/GrVkBackendContext.h" #include "vk/GrVkUtil.h" -GrVkInterface::GrVkInterface() { -} - -#define GET_PROC_GLOBAL(F) functions->f ## F = (PFN_vk ## F) vkGetInstanceProcAddr(NULL, "vk" #F) -#define GET_PROC(F) functions->f ## F = (PFN_vk ## F) vkGetInstanceProcAddr(instance, "vk" #F) -#define GET_PROC_LOCAL(inst, F) PFN_vk ## F F = (PFN_vk ## F) vkGetInstanceProcAddr(inst, "vk" #F) -#define GET_DEV_PROC(F) functions->f ## F = (PFN_vk ## F) vkGetDeviceProcAddr(device, "vk" #F) +#define ACQUIRE_PROC(name, instance, device) fFunctions.f##name = \ + reinterpret_cast(getProc("vk"#name, instance, device)); -const GrVkInterface* GrVkCreateInterface(VkInstance instance, VkDevice device, - uint32_t extensionFlags) { - - GrVkInterface* interface = new GrVkInterface(); - GrVkInterface::Functions* functions = &interface->fFunctions; +GrVkInterface::GrVkInterface(GetProc getProc, + VkInstance instance, + VkDevice device, + uint32_t extensionFlags) { + if (getProc == nullptr) { + return; + } + // Global/Loader Procs. + ACQUIRE_PROC(CreateInstance, VK_NULL_HANDLE, VK_NULL_HANDLE); + ACQUIRE_PROC(EnumerateInstanceExtensionProperties, VK_NULL_HANDLE, VK_NULL_HANDLE); + ACQUIRE_PROC(EnumerateInstanceLayerProperties, VK_NULL_HANDLE, VK_NULL_HANDLE); - GET_PROC_GLOBAL(CreateInstance); - GET_PROC_GLOBAL(EnumerateInstanceExtensionProperties); - GET_PROC_GLOBAL(EnumerateInstanceLayerProperties); - GET_PROC(DestroyInstance); - GET_PROC(EnumeratePhysicalDevices); - GET_PROC(GetPhysicalDeviceFeatures); - GET_PROC(GetPhysicalDeviceFormatProperties); - GET_PROC(GetPhysicalDeviceImageFormatProperties); - GET_PROC(GetPhysicalDeviceProperties); - GET_PROC(GetPhysicalDeviceQueueFamilyProperties); - GET_PROC(GetPhysicalDeviceMemoryProperties); - GET_PROC(CreateDevice); - GET_PROC(DestroyDevice); - GET_PROC(EnumerateDeviceExtensionProperties); - GET_PROC(EnumerateDeviceLayerProperties); - GET_DEV_PROC(GetDeviceQueue); - GET_DEV_PROC(QueueSubmit); - GET_DEV_PROC(QueueWaitIdle); - GET_DEV_PROC(DeviceWaitIdle); - GET_DEV_PROC(AllocateMemory); - GET_DEV_PROC(FreeMemory); - GET_DEV_PROC(MapMemory); - GET_DEV_PROC(UnmapMemory); - GET_DEV_PROC(FlushMappedMemoryRanges); - GET_DEV_PROC(InvalidateMappedMemoryRanges); - GET_DEV_PROC(GetDeviceMemoryCommitment); - GET_DEV_PROC(BindBufferMemory); - GET_DEV_PROC(BindImageMemory); - GET_DEV_PROC(GetBufferMemoryRequirements); - GET_DEV_PROC(GetImageMemoryRequirements); - GET_DEV_PROC(GetImageSparseMemoryRequirements); - GET_PROC(GetPhysicalDeviceSparseImageFormatProperties); - GET_DEV_PROC(QueueBindSparse); - GET_DEV_PROC(CreateFence); - GET_DEV_PROC(DestroyFence); - GET_DEV_PROC(ResetFences); - GET_DEV_PROC(GetFenceStatus); - GET_DEV_PROC(WaitForFences); - GET_DEV_PROC(CreateSemaphore); - GET_DEV_PROC(DestroySemaphore); - GET_DEV_PROC(CreateEvent); - GET_DEV_PROC(DestroyEvent); - GET_DEV_PROC(GetEventStatus); - GET_DEV_PROC(SetEvent); - GET_DEV_PROC(ResetEvent); - GET_DEV_PROC(CreateQueryPool); - GET_DEV_PROC(DestroyQueryPool); - GET_DEV_PROC(GetQueryPoolResults); - GET_DEV_PROC(CreateBuffer); - GET_DEV_PROC(DestroyBuffer); - GET_DEV_PROC(CreateBufferView); - GET_DEV_PROC(DestroyBufferView); - GET_DEV_PROC(CreateImage); - GET_DEV_PROC(DestroyImage); - GET_DEV_PROC(GetImageSubresourceLayout); - GET_DEV_PROC(CreateImageView); - GET_DEV_PROC(DestroyImageView); - GET_DEV_PROC(CreateShaderModule); - GET_DEV_PROC(DestroyShaderModule); - GET_DEV_PROC(CreatePipelineCache); - GET_DEV_PROC(DestroyPipelineCache); - GET_DEV_PROC(GetPipelineCacheData); - GET_DEV_PROC(MergePipelineCaches); - GET_DEV_PROC(CreateGraphicsPipelines); - GET_DEV_PROC(CreateComputePipelines); - GET_DEV_PROC(DestroyPipeline); - GET_DEV_PROC(CreatePipelineLayout); - GET_DEV_PROC(DestroyPipelineLayout); - GET_DEV_PROC(CreateSampler); - GET_DEV_PROC(DestroySampler); - GET_DEV_PROC(CreateDescriptorSetLayout); - GET_DEV_PROC(DestroyDescriptorSetLayout); - GET_DEV_PROC(CreateDescriptorPool); - GET_DEV_PROC(DestroyDescriptorPool); - GET_DEV_PROC(ResetDescriptorPool); - GET_DEV_PROC(AllocateDescriptorSets); - GET_DEV_PROC(FreeDescriptorSets); - GET_DEV_PROC(UpdateDescriptorSets); - GET_DEV_PROC(CreateFramebuffer); - GET_DEV_PROC(DestroyFramebuffer); - GET_DEV_PROC(CreateRenderPass); - GET_DEV_PROC(DestroyRenderPass); - GET_DEV_PROC(GetRenderAreaGranularity); - GET_DEV_PROC(CreateCommandPool); - GET_DEV_PROC(DestroyCommandPool); - GET_DEV_PROC(ResetCommandPool); - GET_DEV_PROC(AllocateCommandBuffers); - GET_DEV_PROC(FreeCommandBuffers); - GET_DEV_PROC(BeginCommandBuffer); - GET_DEV_PROC(EndCommandBuffer); - GET_DEV_PROC(ResetCommandBuffer); - GET_DEV_PROC(CmdBindPipeline); - GET_DEV_PROC(CmdSetViewport); - GET_DEV_PROC(CmdSetScissor); - GET_DEV_PROC(CmdSetLineWidth); - GET_DEV_PROC(CmdSetDepthBias); - GET_DEV_PROC(CmdSetBlendConstants); - GET_DEV_PROC(CmdSetDepthBounds); - GET_DEV_PROC(CmdSetStencilCompareMask); - GET_DEV_PROC(CmdSetStencilWriteMask); - GET_DEV_PROC(CmdSetStencilReference); - GET_DEV_PROC(CmdBindDescriptorSets); - GET_DEV_PROC(CmdBindIndexBuffer); - GET_DEV_PROC(CmdBindVertexBuffers); - GET_DEV_PROC(CmdDraw); - GET_DEV_PROC(CmdDrawIndexed); - GET_DEV_PROC(CmdDrawIndirect); - GET_DEV_PROC(CmdDrawIndexedIndirect); - GET_DEV_PROC(CmdDispatch); - GET_DEV_PROC(CmdDispatchIndirect); - GET_DEV_PROC(CmdCopyBuffer); - GET_DEV_PROC(CmdCopyImage); - GET_DEV_PROC(CmdBlitImage); - GET_DEV_PROC(CmdCopyBufferToImage); - GET_DEV_PROC(CmdCopyImageToBuffer); - GET_DEV_PROC(CmdUpdateBuffer); - GET_DEV_PROC(CmdFillBuffer); - GET_DEV_PROC(CmdClearColorImage); - GET_DEV_PROC(CmdClearDepthStencilImage); - GET_DEV_PROC(CmdClearAttachments); - GET_DEV_PROC(CmdResolveImage); - GET_DEV_PROC(CmdSetEvent); - GET_DEV_PROC(CmdResetEvent); - GET_DEV_PROC(CmdWaitEvents); - GET_DEV_PROC(CmdPipelineBarrier); - GET_DEV_PROC(CmdBeginQuery); - GET_DEV_PROC(CmdEndQuery); - GET_DEV_PROC(CmdResetQueryPool); - GET_DEV_PROC(CmdWriteTimestamp); - GET_DEV_PROC(CmdCopyQueryPoolResults); - GET_DEV_PROC(CmdPushConstants); - GET_DEV_PROC(CmdBeginRenderPass); - GET_DEV_PROC(CmdNextSubpass); - GET_DEV_PROC(CmdEndRenderPass); - GET_DEV_PROC(CmdExecuteCommands); + // Instance Procs. + ACQUIRE_PROC(EnumeratePhysicalDevices, instance, VK_NULL_HANDLE); + ACQUIRE_PROC(GetPhysicalDeviceFeatures, instance, VK_NULL_HANDLE); + ACQUIRE_PROC(GetPhysicalDeviceFormatProperties, instance, VK_NULL_HANDLE); + ACQUIRE_PROC(GetPhysicalDeviceImageFormatProperties, instance, VK_NULL_HANDLE); + ACQUIRE_PROC(GetPhysicalDeviceProperties, instance, VK_NULL_HANDLE); + ACQUIRE_PROC(GetPhysicalDeviceQueueFamilyProperties, instance, VK_NULL_HANDLE); + ACQUIRE_PROC(GetPhysicalDeviceMemoryProperties, instance, VK_NULL_HANDLE); + ACQUIRE_PROC(GetPhysicalDeviceSparseImageFormatProperties, instance, VK_NULL_HANDLE); + ACQUIRE_PROC(DestroyInstance, instance, VK_NULL_HANDLE); + ACQUIRE_PROC(CreateDevice, instance, VK_NULL_HANDLE); + ACQUIRE_PROC(DestroyDevice, instance, VK_NULL_HANDLE); + ACQUIRE_PROC(EnumerateDeviceExtensionProperties, instance, VK_NULL_HANDLE); + ACQUIRE_PROC(EnumerateDeviceLayerProperties, instance, VK_NULL_HANDLE); if (extensionFlags & kEXT_debug_report_GrVkExtensionFlag) { - GET_PROC(CreateDebugReportCallbackEXT); - GET_PROC(DebugReportMessageEXT); - GET_PROC(DestroyDebugReportCallbackEXT); + // Also instance Procs. + ACQUIRE_PROC(CreateDebugReportCallbackEXT, instance, VK_NULL_HANDLE); + ACQUIRE_PROC(DebugReportMessageEXT, instance, VK_NULL_HANDLE); + ACQUIRE_PROC(DestroyDebugReportCallbackEXT, instance, VK_NULL_HANDLE); } - return interface; + // Device Procs. + ACQUIRE_PROC(GetDeviceQueue, VK_NULL_HANDLE, device); + ACQUIRE_PROC(QueueSubmit, VK_NULL_HANDLE, device); + ACQUIRE_PROC(QueueWaitIdle, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DeviceWaitIdle, VK_NULL_HANDLE, device); + ACQUIRE_PROC(AllocateMemory, VK_NULL_HANDLE, device); + ACQUIRE_PROC(FreeMemory, VK_NULL_HANDLE, device); + ACQUIRE_PROC(MapMemory, VK_NULL_HANDLE, device); + ACQUIRE_PROC(UnmapMemory, VK_NULL_HANDLE, device); + ACQUIRE_PROC(FlushMappedMemoryRanges, VK_NULL_HANDLE, device); + ACQUIRE_PROC(InvalidateMappedMemoryRanges, VK_NULL_HANDLE, device); + ACQUIRE_PROC(GetDeviceMemoryCommitment, VK_NULL_HANDLE, device); + ACQUIRE_PROC(BindBufferMemory, VK_NULL_HANDLE, device); + ACQUIRE_PROC(BindImageMemory, VK_NULL_HANDLE, device); + ACQUIRE_PROC(GetBufferMemoryRequirements, VK_NULL_HANDLE, device); + ACQUIRE_PROC(GetImageMemoryRequirements, VK_NULL_HANDLE, device); + ACQUIRE_PROC(GetImageSparseMemoryRequirements, VK_NULL_HANDLE, device); + ACQUIRE_PROC(QueueBindSparse, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateFence, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyFence, VK_NULL_HANDLE, device); + ACQUIRE_PROC(ResetFences, VK_NULL_HANDLE, device); + ACQUIRE_PROC(GetFenceStatus, VK_NULL_HANDLE, device); + ACQUIRE_PROC(WaitForFences, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateSemaphore, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroySemaphore, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateEvent, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyEvent, VK_NULL_HANDLE, device); + ACQUIRE_PROC(GetEventStatus, VK_NULL_HANDLE, device); + ACQUIRE_PROC(SetEvent, VK_NULL_HANDLE, device); + ACQUIRE_PROC(ResetEvent, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateQueryPool, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyQueryPool, VK_NULL_HANDLE, device); + ACQUIRE_PROC(GetQueryPoolResults, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateBuffer, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyBuffer, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateBufferView, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyBufferView, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateImage, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyImage, VK_NULL_HANDLE, device); + ACQUIRE_PROC(GetImageSubresourceLayout, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateImageView, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyImageView, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateShaderModule, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyShaderModule, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreatePipelineCache, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyPipelineCache, VK_NULL_HANDLE, device); + ACQUIRE_PROC(GetPipelineCacheData, VK_NULL_HANDLE, device); + ACQUIRE_PROC(MergePipelineCaches, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateGraphicsPipelines, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateComputePipelines, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyPipeline, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreatePipelineLayout, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyPipelineLayout, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateSampler, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroySampler, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateDescriptorSetLayout, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyDescriptorSetLayout, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateDescriptorPool, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyDescriptorPool, VK_NULL_HANDLE, device); + ACQUIRE_PROC(ResetDescriptorPool, VK_NULL_HANDLE, device); + ACQUIRE_PROC(AllocateDescriptorSets, VK_NULL_HANDLE, device); + ACQUIRE_PROC(FreeDescriptorSets, VK_NULL_HANDLE, device); + ACQUIRE_PROC(UpdateDescriptorSets, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateFramebuffer, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyFramebuffer, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateRenderPass, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyRenderPass, VK_NULL_HANDLE, device); + ACQUIRE_PROC(GetRenderAreaGranularity, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CreateCommandPool, VK_NULL_HANDLE, device); + ACQUIRE_PROC(DestroyCommandPool, VK_NULL_HANDLE, device); + ACQUIRE_PROC(ResetCommandPool, VK_NULL_HANDLE, device); + ACQUIRE_PROC(AllocateCommandBuffers, VK_NULL_HANDLE, device); + ACQUIRE_PROC(FreeCommandBuffers, VK_NULL_HANDLE, device); + ACQUIRE_PROC(BeginCommandBuffer, VK_NULL_HANDLE, device); + ACQUIRE_PROC(EndCommandBuffer, VK_NULL_HANDLE, device); + ACQUIRE_PROC(ResetCommandBuffer, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdBindPipeline, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdSetViewport, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdSetScissor, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdSetLineWidth, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdSetDepthBias, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdSetBlendConstants, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdSetDepthBounds, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdSetStencilCompareMask, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdSetStencilWriteMask, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdSetStencilReference, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdBindDescriptorSets, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdBindIndexBuffer, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdBindVertexBuffers, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdDraw, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdDrawIndexed, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdDrawIndirect, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdDrawIndexedIndirect, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdDispatch, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdDispatchIndirect, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdCopyBuffer, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdCopyImage, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdBlitImage, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdCopyBufferToImage, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdCopyImageToBuffer, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdUpdateBuffer, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdFillBuffer, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdClearColorImage, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdClearDepthStencilImage, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdClearAttachments, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdResolveImage, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdSetEvent, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdResetEvent, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdWaitEvents, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdPipelineBarrier, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdBeginQuery, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdEndQuery, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdResetQueryPool, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdWriteTimestamp, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdCopyQueryPoolResults, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdPushConstants, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdBeginRenderPass, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdNextSubpass, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdEndRenderPass, VK_NULL_HANDLE, device); + ACQUIRE_PROC(CmdExecuteCommands, VK_NULL_HANDLE, device); } #ifdef SK_DEBUG -- cgit v1.2.3