From d92eeaf1c112027010f2f63cf6cac14312ea9e54 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sun, 7 Oct 2018 17:58:52 -0700 Subject: Some improvements to Vulkan CommandPoolManager --- .../include/CommandPoolManager.h | 6 ++- .../src/CommandPoolManager.cpp | 45 +++++++++++++++++++++- .../src/RenderDeviceVkImpl.cpp | 40 +------------------ 3 files changed, 48 insertions(+), 43 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/CommandPoolManager.h b/Graphics/GraphicsEngineVulkan/include/CommandPoolManager.h index 04ba603f..d7bf771e 100644 --- a/Graphics/GraphicsEngineVulkan/include/CommandPoolManager.h +++ b/Graphics/GraphicsEngineVulkan/include/CommandPoolManager.h @@ -52,8 +52,7 @@ public: // Allocates Vulkan command pool. VulkanUtilities::CommandPoolWrapper AllocateCommandPool(const char *DebugName = nullptr); - // Returns command pool to the list of available pools. The GPU must have finished using the pool - void FreeCommandPool(VulkanUtilities::CommandPoolWrapper&& CmdPool); + void SafeReleaseCommandPool(VulkanUtilities::CommandPoolWrapper&& CmdPool, Uint32 CmdQueueIndex, Uint64 FenceValue); void DestroyPools(); @@ -62,6 +61,9 @@ public: #endif private: + // Returns command pool to the list of available pools. The GPU must have finished using the pool + void FreeCommandPool(VulkanUtilities::CommandPoolWrapper&& CmdPool); + RenderDeviceVkImpl& m_DeviceVkImpl; const std::string m_Name; const uint32_t m_QueueFamilyIndex; diff --git a/Graphics/GraphicsEngineVulkan/src/CommandPoolManager.cpp b/Graphics/GraphicsEngineVulkan/src/CommandPoolManager.cpp index a02c0545..2702172d 100644 --- a/Graphics/GraphicsEngineVulkan/src/CommandPoolManager.cpp +++ b/Graphics/GraphicsEngineVulkan/src/CommandPoolManager.cpp @@ -71,6 +71,47 @@ VulkanUtilities::CommandPoolWrapper CommandPoolManager::AllocateCommandPool(cons return std::move(CmdPool); } +void CommandPoolManager::SafeReleaseCommandPool(VulkanUtilities::CommandPoolWrapper&& CmdPool, Uint32 CmdQueueIndex, Uint64 FenceValue) +{ + class CommandPoolDeleter + { + public: + CommandPoolDeleter(CommandPoolManager& _CmdPoolMgr, VulkanUtilities::CommandPoolWrapper&& _Pool) : + CmdPoolMgr(&_CmdPoolMgr), + Pool (std::move(_Pool)) + { + VERIFY_EXPR(Pool != VK_NULL_HANDLE); + } + + CommandPoolDeleter (const CommandPoolDeleter&) = delete; + CommandPoolDeleter& operator = (const CommandPoolDeleter&) = delete; + CommandPoolDeleter& operator = ( CommandPoolDeleter&&) = delete; + + CommandPoolDeleter(CommandPoolDeleter&& rhs) : + CmdPoolMgr(rhs.CmdPoolMgr), + Pool (std::move(rhs.Pool)) + { + rhs.CmdPoolMgr = nullptr; + } + + + ~CommandPoolDeleter() + { + if (CmdPoolMgr!=nullptr) + { + CmdPoolMgr->FreeCommandPool(std::move(Pool)); + } + } + private: + CommandPoolManager* CmdPoolMgr; + VulkanUtilities::CommandPoolWrapper Pool; + }; + + // Discard command pool directly to the release queue since we know exactly which queue it was submitted to + // as well as the associated FenceValue + m_DeviceVkImpl.GetReleaseQueue(CmdQueueIndex).DiscardResource(CommandPoolDeleter{*this, std::move(CmdPool)}, FenceValue); +} + void CommandPoolManager::FreeCommandPool(VulkanUtilities::CommandPoolWrapper&& CmdPool) { std::lock_guard LockGuard(m_Mutex); @@ -83,14 +124,14 @@ void CommandPoolManager::FreeCommandPool(VulkanUtilities::CommandPoolWrapper&& C void CommandPoolManager::DestroyPools() { std::lock_guard LockGuard(m_Mutex); - DEV_CHECK_ERR(m_AllocatedPoolCounter == 0, m_AllocatedPoolCounter, " command pools have not been returned to the manager."); + DEV_CHECK_ERR(m_AllocatedPoolCounter == 0, m_AllocatedPoolCounter, " pool(s) have not been freed. This will cause a crash if the references to these pools are still in release queues when CommandPoolManager::FreeCommandPool() is called for destroyed CommandPoolManager object."); LOG_INFO_MESSAGE(m_Name, " allocated descriptor pool count: ", m_CmdPools.size() ); m_CmdPools.clear(); } CommandPoolManager::~CommandPoolManager() { - VERIFY(m_CmdPools.empty(), "Command pools have not been destroyed"); + DEV_CHECK_ERR(m_CmdPools.empty() && m_AllocatedPoolCounter == 0, "Command pools have not been destroyed"); } } diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index cc82f4b2..a85670fb 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -227,47 +227,9 @@ void RenderDeviceVkImpl::ExecuteAndDisposeTransientCmdBuff(Uint32 QueueIndex, Vk [&](ICommandQueueVk* pCmdQueueVk) { FenceValue = pCmdQueueVk->Submit(SubmitInfo); - - class CommandPoolDeleter - { - public: - CommandPoolDeleter(CommandPoolManager& _CmdPoolMgr, VulkanUtilities::CommandPoolWrapper&& _Pool) : - CmdPoolMgr(&_CmdPoolMgr), - Pool (std::move(_Pool)) - { - VERIFY_EXPR(Pool != VK_NULL_HANDLE); - } - - CommandPoolDeleter (const CommandPoolDeleter&) = delete; - CommandPoolDeleter& operator = (const CommandPoolDeleter&) = delete; - CommandPoolDeleter& operator = ( CommandPoolDeleter&&) = delete; - - CommandPoolDeleter(CommandPoolDeleter&& rhs) : - CmdPoolMgr(rhs.CmdPoolMgr), - Pool (std::move(rhs.Pool)) - { - rhs.CmdPoolMgr = nullptr; - } - - - ~CommandPoolDeleter() - { - if (CmdPoolMgr!=nullptr) - { - CmdPoolMgr->FreeCommandPool(std::move(Pool)); - } - } - private: - CommandPoolManager* CmdPoolMgr; - VulkanUtilities::CommandPoolWrapper Pool; - }; - - // Discard command pool directly to the release queue since we know exactly which queue it was submitted to - // as well as the associated FenceValue - m_CommandQueues[QueueIndex].ReleaseQueue.DiscardResource(CommandPoolDeleter{m_TransientCmdPoolMgr, std::move(CmdPool)}, FenceValue); } ); - + m_TransientCmdPoolMgr.SafeReleaseCommandPool(std::move(CmdPool), QueueIndex, FenceValue); } void RenderDeviceVkImpl::SubmitCommandBuffer(Uint32 QueueIndex, -- cgit v1.2.3