From c8cd45aaf43c5d044d8433d38c8332b1679eeadb Mon Sep 17 00:00:00 2001 From: Greg Daniel Date: Thu, 12 Jul 2018 10:02:37 -0400 Subject: Generate GrVkInterface when we make the GrVkGpu. Also add a GetProc function to the GrVkBackendContext which will be used to create the GrVkInterface. This change (and updating clients to use it), will allow us to move GrVkInterface out of public which is needed to fix vulkan header issues. Bug: skia: Change-Id: Id8067943ae27cec8cad29fd31b05f0b8387412d4 Reviewed-on: https://skia-review.googlesource.com/140783 Commit-Queue: Greg Daniel Reviewed-by: Brian Salomon --- tools/gpu/vk/VkTestContext.cpp | 89 ++++++++++++++++++++++++++++-------- tools/gpu/vk/VkTestContext.h | 2 - tools/gpu/vk/VkTestUtils.cpp | 17 ++----- tools/sk_app/VulkanWindowContext.cpp | 3 +- tools/sk_app/VulkanWindowContext.h | 48 ++++++++----------- 5 files changed, 94 insertions(+), 65 deletions(-) (limited to 'tools') diff --git a/tools/gpu/vk/VkTestContext.cpp b/tools/gpu/vk/VkTestContext.cpp index 32a1205107..97508b2de4 100644 --- a/tools/gpu/vk/VkTestContext.cpp +++ b/tools/gpu/vk/VkTestContext.cpp @@ -15,6 +15,11 @@ #include "vk/GrVkUtil.h" namespace { + +#define ACQUIRE_VK_PROC(name, device) \ + f##name = reinterpret_cast(getProc("vk" #name, nullptr, device)); \ + SkASSERT(f##name); + /** * Implements sk_gpu_test::FenceSync for Vulkan. It creates a single command * buffer with USAGE_SIMULTANEOUS with no content . On every insertFence request @@ -22,18 +27,30 @@ namespace { */ class VkFenceSync : public sk_gpu_test::FenceSync { public: - VkFenceSync(sk_sp vk, VkDevice device, VkQueue queue, + VkFenceSync(GrVkGetProc getProc, VkDevice device, VkQueue queue, uint32_t queueFamilyIndex) - : fVk(std::move(vk)) - , fDevice(device) + : fDevice(device) , fQueue(queue) { + ACQUIRE_VK_PROC(CreateCommandPool, device); + ACQUIRE_VK_PROC(DestroyCommandPool, device); + ACQUIRE_VK_PROC(AllocateCommandBuffers, device); + ACQUIRE_VK_PROC(FreeCommandBuffers, device); + ACQUIRE_VK_PROC(BeginCommandBuffer, device); + ACQUIRE_VK_PROC(EndCommandBuffer, device); + ACQUIRE_VK_PROC(CreateFence, device); + ACQUIRE_VK_PROC(DestroyFence, device); + ACQUIRE_VK_PROC(WaitForFences, device); + ACQUIRE_VK_PROC(QueueSubmit, device); + + VkResult result; SkDEBUGCODE(fUnfinishedSyncs = 0;) VkCommandPoolCreateInfo createInfo; createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; createInfo.pNext = nullptr; createInfo.flags = 0; createInfo.queueFamilyIndex = queueFamilyIndex; - GR_VK_CALL_ERRCHECK(fVk, CreateCommandPool(fDevice, &createInfo, nullptr, &fCommandPool)); + result = fCreateCommandPool(fDevice, &createInfo, nullptr, &fCommandPool); + SkASSERT(VK_SUCCESS == result); VkCommandBufferAllocateInfo allocateInfo; allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; @@ -41,31 +58,39 @@ public: allocateInfo.commandBufferCount = 1; allocateInfo.commandPool = fCommandPool; allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - GR_VK_CALL_ERRCHECK(fVk, AllocateCommandBuffers(fDevice, &allocateInfo, &fCommandBuffer)); + result = fAllocateCommandBuffers(fDevice, &allocateInfo, &fCommandBuffer); + SkASSERT(VK_SUCCESS == result); VkCommandBufferBeginInfo beginInfo; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; beginInfo.pNext = nullptr; beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; beginInfo.pInheritanceInfo = nullptr; - GR_VK_CALL_ERRCHECK(fVk, BeginCommandBuffer(fCommandBuffer, &beginInfo)); - GR_VK_CALL_ERRCHECK(fVk, EndCommandBuffer(fCommandBuffer)); + result = fBeginCommandBuffer(fCommandBuffer, &beginInfo); + SkASSERT(VK_SUCCESS == result); + result = fEndCommandBuffer(fCommandBuffer); + SkASSERT(VK_SUCCESS == result); + } ~VkFenceSync() override { SkASSERT(!fUnfinishedSyncs); // If the above assertion is true then the command buffer should not be in flight. - GR_VK_CALL(fVk, FreeCommandBuffers(fDevice, fCommandPool, 1, &fCommandBuffer)); - GR_VK_CALL(fVk, DestroyCommandPool(fDevice, fCommandPool, nullptr)); + fFreeCommandBuffers(fDevice, fCommandPool, 1, &fCommandBuffer); + fDestroyCommandPool(fDevice, fCommandPool, nullptr); } sk_gpu_test::PlatformFence SK_WARN_UNUSED_RESULT insertFence() const override { + VkResult result; + VkFence fence; VkFenceCreateInfo info; info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; info.pNext = nullptr; info.flags = 0; - GR_VK_CALL_ERRCHECK(fVk, CreateFence(fDevice, &info, nullptr, &fence)); + result = fCreateFence(fDevice, &info, nullptr, &fence); + SkASSERT(VK_SUCCESS == result); + VkSubmitInfo submitInfo; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.pNext = nullptr; @@ -76,7 +101,9 @@ public: submitInfo.pCommandBuffers = &fCommandBuffer; submitInfo.signalSemaphoreCount = 0; submitInfo.pSignalSemaphores = nullptr; - GR_VK_CALL_ERRCHECK(fVk, QueueSubmit(fQueue, 1, &submitInfo, fence)); + result = fQueueSubmit(fQueue, 1, &submitInfo, fence); + SkASSERT(VK_SUCCESS == result); + SkDEBUGCODE(++fUnfinishedSyncs;) return (sk_gpu_test::PlatformFence)fence; } @@ -84,22 +111,33 @@ public: bool waitFence(sk_gpu_test::PlatformFence opaqueFence) const override { VkFence fence = (VkFence)opaqueFence; static constexpr uint64_t kForever = ~((uint64_t)0); - auto result = GR_VK_CALL(fVk, WaitForFences(fDevice, 1, &fence, true, kForever)); + auto result = fWaitForFences(fDevice, 1, &fence, true, kForever); return result != VK_TIMEOUT; } void deleteFence(sk_gpu_test::PlatformFence opaqueFence) const override { VkFence fence = (VkFence)opaqueFence; - GR_VK_CALL(fVk, DestroyFence(fDevice, fence, nullptr)); + fDestroyFence(fDevice, fence, nullptr); SkDEBUGCODE(--fUnfinishedSyncs;) } private: - sk_sp fVk; VkDevice fDevice; VkQueue fQueue; VkCommandPool fCommandPool; VkCommandBuffer fCommandBuffer; + + PFN_vkCreateCommandPool fCreateCommandPool = nullptr; + PFN_vkDestroyCommandPool fDestroyCommandPool = nullptr; + PFN_vkAllocateCommandBuffers fAllocateCommandBuffers = nullptr; + PFN_vkFreeCommandBuffers fFreeCommandBuffers = nullptr; + PFN_vkBeginCommandBuffer fBeginCommandBuffer = nullptr; + PFN_vkEndCommandBuffer fEndCommandBuffer = nullptr; + PFN_vkCreateFence fCreateFence = nullptr; + PFN_vkDestroyFence fDestroyFence = nullptr; + PFN_vkWaitForFences fWaitForFences = nullptr; + PFN_vkQueueSubmit fQueueSubmit = nullptr; + SkDEBUGCODE(mutable int fUnfinishedSyncs;) typedef sk_gpu_test::FenceSync INHERITED; }; @@ -146,19 +184,30 @@ public: } protected: +#define ACQUIRE_VK_PROC_LOCAL(name, inst) \ + PFN_vk##name grVk##name = \ + reinterpret_cast(fVk.fGetProc("vk" #name, inst, nullptr)); \ + if (grVk##name == nullptr) { \ + SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \ + return; \ + } + void teardown() override { INHERITED::teardown(); fVk.fMemoryAllocator.reset(); if (fOwnsContext) { - GR_VK_CALL(this->vk(), DeviceWaitIdle(fVk.fDevice)); - GR_VK_CALL(this->vk(), DestroyDevice(fVk.fDevice, nullptr)); + ACQUIRE_VK_PROC_LOCAL(DeviceWaitIdle, fVk.fInstance); + ACQUIRE_VK_PROC_LOCAL(DestroyDevice, fVk.fInstance); + ACQUIRE_VK_PROC_LOCAL(DestroyInstance, fVk.fInstance); + grVkDeviceWaitIdle(fVk.fDevice); + grVkDestroyDevice(fVk.fDevice, nullptr); #ifdef SK_ENABLE_VK_LAYERS if (fDebugCallback != VK_NULL_HANDLE) { - GR_VK_CALL(this->vk(), DestroyDebugReportCallbackEXT(fVk.fInstance, fDebugCallback, - nullptr)); + ACQUIRE_VK_PROC_LOCAL(DestroyDebugReportCallbackEXT, fVk.fInstance); + grVkDestroyDebugReportCallbackEXT(fVk.fInstance, fDebugCallback, nullptr); } #endif - GR_VK_CALL(this->vk(), DestroyInstance(fVk.fInstance, nullptr)); + grVkDestroyInstance(fVk.fInstance, nullptr); } } @@ -166,7 +215,7 @@ private: VkTestContextImpl(const GrVkBackendContext& backendContext, bool ownsContext, VkDebugReportCallbackEXT debugCallback) : VkTestContext(backendContext, ownsContext, debugCallback) { - fFenceSync.reset(new VkFenceSync(fVk.fInterface, fVk.fDevice, fVk.fQueue, + fFenceSync.reset(new VkFenceSync(fVk.fGetProc, fVk.fDevice, fVk.fQueue, fVk.fGraphicsQueueIndex)); } diff --git a/tools/gpu/vk/VkTestContext.h b/tools/gpu/vk/VkTestContext.h index 920f53534e..f3274c55cf 100644 --- a/tools/gpu/vk/VkTestContext.h +++ b/tools/gpu/vk/VkTestContext.h @@ -23,8 +23,6 @@ public: return fVk; } - const GrVkInterface* vk() const { return fVk.fInterface.get(); } - protected: VkTestContext(const GrVkBackendContext& vk, bool ownsContext, VkDebugReportCallbackEXT debugCallback) diff --git a/tools/gpu/vk/VkTestUtils.cpp b/tools/gpu/vk/VkTestUtils.cpp index e6ddda2fce..017d767dc5 100644 --- a/tools/gpu/vk/VkTestUtils.cpp +++ b/tools/gpu/vk/VkTestUtils.cpp @@ -138,8 +138,8 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro VkDebugReportCallbackEXT* debugCallback, uint32_t* presentQueueIndexPtr, CanPresentFn canPresent) { - auto getProc = [&getInstanceProc, &getDeviceProc](const char* proc_name, - VkInstance instance, VkDevice device) { + auto getProc = [getInstanceProc, getDeviceProc](const char* proc_name, + VkInstance instance, VkDevice device) { if (device != VK_NULL_HANDLE) { return getDeviceProc(device, proc_name); } @@ -406,16 +406,6 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro return false; } - auto interface = - sk_make_sp(getProc, inst, device, extensionFlags); - if (!interface->validate(extensionFlags)) { - SkDebugf("Vulkan interface validation failed\n"); - grVkDeviceWaitIdle(device); - grVkDestroyDevice(device, nullptr); - destroy_instance(getProc, inst, debugCallback, hasDebugExtension); - return false; - } - VkQueue queue; grVkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue); @@ -427,7 +417,8 @@ bool CreateVkBackendContext(const GrVkInterface::GetInstanceProc& getInstancePro ctx->fMinAPIVersion = kGrVkMinimumVersion; ctx->fExtensions = extensionFlags; ctx->fFeatures = featureFlags; - ctx->fInterface.reset(interface.release()); + ctx->fInterface = nullptr; + ctx->fGetProc = getProc; ctx->fOwnsInstanceAndDevice = false; return true; diff --git a/tools/sk_app/VulkanWindowContext.cpp b/tools/sk_app/VulkanWindowContext.cpp index 0d1b268d8c..6d39890dff 100644 --- a/tools/sk_app/VulkanWindowContext.cpp +++ b/tools/sk_app/VulkanWindowContext.cpp @@ -66,7 +66,8 @@ void VulkanWindowContext::initializeContext() { fDevice = backendContext.fDevice; fGraphicsQueueIndex = backendContext.fGraphicsQueueIndex; fGraphicsQueue = backendContext.fQueue; - fInterface = backendContext.fInterface; + fInterface.reset(new GrVkInterface(backendContext.fGetProc, fInstance, fDevice, + backendContext.fExtensions)); GET_PROC(DestroyInstance); GET_PROC(DestroySurfaceKHR); diff --git a/tools/sk_app/VulkanWindowContext.h b/tools/sk_app/VulkanWindowContext.h index 3d9687b674..2e01e291b7 100644 --- a/tools/sk_app/VulkanWindowContext.h +++ b/tools/sk_app/VulkanWindowContext.h @@ -70,42 +70,32 @@ private: VkDevice fDevice = VK_NULL_HANDLE; VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE; - // simple wrapper class that exists only to initialize a pointer to NULL - template class VkPtr { - public: - VkPtr() : fPtr(NULL) {} - VkPtr operator=(FNPTR_TYPE ptr) { fPtr = ptr; return *this; } - operator FNPTR_TYPE() const { return fPtr; } - private: - FNPTR_TYPE fPtr; - }; - // Create functions CreateVkSurfaceFn fCreateVkSurfaceFn; CanPresentFn fCanPresentFn; // Vulkan GetProcAddr functions - VkPtr fGetInstanceProcAddr; - VkPtr fGetDeviceProcAddr; + PFN_vkGetInstanceProcAddr fGetInstanceProcAddr = nullptr; + PFN_vkGetDeviceProcAddr fGetDeviceProcAddr = nullptr; // WSI interface functions - VkPtr fDestroySurfaceKHR; - VkPtr fGetPhysicalDeviceSurfaceSupportKHR; - VkPtr fGetPhysicalDeviceSurfaceCapabilitiesKHR; - VkPtr fGetPhysicalDeviceSurfaceFormatsKHR; - VkPtr fGetPhysicalDeviceSurfacePresentModesKHR; - - VkPtr fCreateSwapchainKHR; - VkPtr fDestroySwapchainKHR; - VkPtr fGetSwapchainImagesKHR; - VkPtr fAcquireNextImageKHR; - VkPtr fQueuePresentKHR; - - VkPtr fDestroyInstance; - VkPtr fDeviceWaitIdle; - VkPtr fQueueWaitIdle; - VkPtr fDestroyDevice; - VkPtr fGetDeviceQueue; + PFN_vkDestroySurfaceKHR fDestroySurfaceKHR = nullptr; + PFN_vkGetPhysicalDeviceSurfaceSupportKHR fGetPhysicalDeviceSurfaceSupportKHR = nullptr; + PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fGetPhysicalDeviceSurfaceCapabilitiesKHR =nullptr; + PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fGetPhysicalDeviceSurfaceFormatsKHR = nullptr; + PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fGetPhysicalDeviceSurfacePresentModesKHR =nullptr; + + PFN_vkCreateSwapchainKHR fCreateSwapchainKHR = nullptr; + PFN_vkDestroySwapchainKHR fDestroySwapchainKHR = nullptr; + PFN_vkGetSwapchainImagesKHR fGetSwapchainImagesKHR = nullptr; + PFN_vkAcquireNextImageKHR fAcquireNextImageKHR = nullptr; + PFN_vkQueuePresentKHR fQueuePresentKHR = nullptr; + + PFN_vkDestroyInstance fDestroyInstance = nullptr; + PFN_vkDeviceWaitIdle fDeviceWaitIdle = nullptr; + PFN_vkQueueWaitIdle fQueueWaitIdle = nullptr; + PFN_vkDestroyDevice fDestroyDevice = nullptr; + PFN_vkGetDeviceQueue fGetDeviceQueue = nullptr; sk_sp fInterface; -- cgit v1.2.3