From dd5ff104ec4af361e50d2adee4917463958d7ecf Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Fri, 26 Jan 2018 16:47:12 -0500 Subject: [PATCH] Vulkan: support fenced deletion of swapchain objects --- src/backend/vulkan/FencedDeleter.cpp | 31 ++++++++++++++++++++++++++++ src/backend/vulkan/FencedDeleter.h | 6 ++++++ 2 files changed, 37 insertions(+) diff --git a/src/backend/vulkan/FencedDeleter.cpp b/src/backend/vulkan/FencedDeleter.cpp index 0f6ebe32f8..f655adaf7f 100644 --- a/src/backend/vulkan/FencedDeleter.cpp +++ b/src/backend/vulkan/FencedDeleter.cpp @@ -30,7 +30,10 @@ namespace backend { namespace vulkan { ASSERT(mPipelinesToDelete.Empty()); ASSERT(mPipelineLayoutsToDelete.Empty()); ASSERT(mRenderPassesToDelete.Empty()); + ASSERT(mSemaphoresToDelete.Empty()); ASSERT(mShaderModulesToDelete.Empty()); + ASSERT(mSurfacesToDelete.Empty()); + ASSERT(mSwapChainsToDelete.Empty()); } void FencedDeleter::DeleteWhenUnused(VkBuffer buffer) { @@ -65,12 +68,25 @@ namespace backend { namespace vulkan { mRenderPassesToDelete.Enqueue(renderPass, mDevice->GetSerial()); } + void FencedDeleter::DeleteWhenUnused(VkSemaphore semaphore) { + mSemaphoresToDelete.Enqueue(semaphore, mDevice->GetSerial()); + } + void FencedDeleter::DeleteWhenUnused(VkShaderModule module) { mShaderModulesToDelete.Enqueue(module, mDevice->GetSerial()); } + void FencedDeleter::DeleteWhenUnused(VkSurfaceKHR surface) { + mSurfacesToDelete.Enqueue(surface, mDevice->GetSerial()); + } + + void FencedDeleter::DeleteWhenUnused(VkSwapchainKHR swapChain) { + mSwapChainsToDelete.Enqueue(swapChain, mDevice->GetSerial()); + } + void FencedDeleter::Tick(Serial completedSerial) { VkDevice vkDevice = mDevice->GetVkDevice(); + VkInstance instance = mDevice->GetInstance(); // Buffers and images must be deleted before memories because it is invalid to free memory // that still have resources bound to it. @@ -117,6 +133,21 @@ namespace backend { namespace vulkan { mDevice->fn.DestroyPipeline(vkDevice, pipeline, nullptr); } mPipelinesToDelete.ClearUpTo(completedSerial); + + // Vulkan swapchains must be destroyed before their corresponding VkSurface + for (VkSwapchainKHR swapChain : mSwapChainsToDelete.IterateUpTo(completedSerial)) { + mDevice->fn.DestroySwapchainKHR(vkDevice, swapChain, nullptr); + } + mSwapChainsToDelete.ClearUpTo(completedSerial); + for (VkSurfaceKHR surface : mSurfacesToDelete.IterateUpTo(completedSerial)) { + mDevice->fn.DestroySurfaceKHR(instance, surface, nullptr); + } + mSurfacesToDelete.ClearUpTo(completedSerial); + + for (VkSemaphore semaphore : mSemaphoresToDelete.IterateUpTo(completedSerial)) { + mDevice->fn.DestroySemaphore(vkDevice, semaphore, nullptr); + } + mSemaphoresToDelete.ClearUpTo(completedSerial); } }} // namespace backend::vulkan diff --git a/src/backend/vulkan/FencedDeleter.h b/src/backend/vulkan/FencedDeleter.h index da8610ccfb..b685664840 100644 --- a/src/backend/vulkan/FencedDeleter.h +++ b/src/backend/vulkan/FencedDeleter.h @@ -35,7 +35,10 @@ namespace backend { namespace vulkan { void DeleteWhenUnused(VkPipelineLayout layout); void DeleteWhenUnused(VkRenderPass renderPass); void DeleteWhenUnused(VkPipeline pipeline); + void DeleteWhenUnused(VkSemaphore semaphore); void DeleteWhenUnused(VkShaderModule module); + void DeleteWhenUnused(VkSurfaceKHR surface); + void DeleteWhenUnused(VkSwapchainKHR swapChain); void Tick(Serial completedSerial); @@ -49,7 +52,10 @@ namespace backend { namespace vulkan { SerialQueue mPipelinesToDelete; SerialQueue mPipelineLayoutsToDelete; SerialQueue mRenderPassesToDelete; + SerialQueue mSemaphoresToDelete; SerialQueue mShaderModulesToDelete; + SerialQueue mSurfacesToDelete; + SerialQueue mSwapChainsToDelete; }; }} // namespace backend::vulkan