diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-06-07 06:44:42 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-06-07 06:44:42 +0000 |
| commit | 0095c62420fdc1f7a966863b5ea1f06bfb001353 (patch) | |
| tree | a672183bb053cbaee2c7050b4a2c24580c73692f /Graphics/GraphicsEngineVulkan | |
| parent | Reworked dynamic upload heap to be managed by every context and to release re... (diff) | |
| download | DiligentCore-0095c62420fdc1f7a966863b5ea1f06bfb001353.tar.gz DiligentCore-0095c62420fdc1f7a966863b5ea1f06bfb001353.zip | |
Reworked dynamic descriptor pools to be owned by device contexts
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
9 files changed, 84 insertions, 132 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h b/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h index 907f369c..822768e0 100644 --- a/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h +++ b/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h @@ -96,12 +96,10 @@ class DescriptorPoolManager public: DescriptorPoolManager(std::shared_ptr<const VulkanUtilities::VulkanLogicalDevice> LogicalDevice, std::vector<VkDescriptorPoolSize> PoolSizes, - uint32_t MaxSets, - bool IsThreadSafe)noexcept: + uint32_t MaxSets)noexcept: m_LogicalDevice(std::move(LogicalDevice)), m_PoolSizes(std::move(PoolSizes)), - m_MaxSets(MaxSets), - m_IsThreadSafe(IsThreadSafe) + m_MaxSets(MaxSets) { CreateNewPool(); } @@ -111,7 +109,6 @@ public: DescriptorPoolManager(DescriptorPoolManager&& rhs)noexcept : m_PoolSizes(std::move(rhs.m_PoolSizes)), m_MaxSets(std::move(rhs.m_MaxSets)), - m_IsThreadSafe(std::move(rhs.m_IsThreadSafe)), //m_Mutex(std::move(rhs.m_Mutex)), mutex is not movable m_LogicalDevice(std::move(rhs.m_LogicalDevice)), m_DescriptorPools(std::move(rhs.m_DescriptorPools)), @@ -119,7 +116,7 @@ public: { } - DescriptorPoolManager(const DescriptorPoolManager&) = delete; + DescriptorPoolManager (const DescriptorPoolManager&) = delete; DescriptorPoolManager& operator = (const DescriptorPoolManager&) = delete; DescriptorPoolManager& operator = (DescriptorPoolManager&&) = delete; @@ -135,12 +132,13 @@ private: const std::vector<VkDescriptorPoolSize> m_PoolSizes; const uint32_t m_MaxSets; - const bool m_IsThreadSafe; std::mutex m_Mutex; std::shared_ptr<const VulkanUtilities::VulkanLogicalDevice> m_LogicalDevice; std::deque< std::unique_ptr<VulkanUtilities::VulkanDescriptorPool> > m_DescriptorPools; std::vector< std::pair<VkDescriptorSet, VulkanUtilities::VulkanDescriptorPool*> > m_ReleasedAllocations; + + // When adding new members, do not forget to update move ctor! }; } diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h index ccdc62ee..f2c1b0a5 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h @@ -35,6 +35,7 @@ #include "VulkanUtilities/VulkanUploadHeap.h" #include "VulkanDynamicHeap.h" #include "ResourceReleaseQueue.h" +#include "DescriptorPoolManager.h" #ifdef _DEBUG # define VERIFY_CONTEXT_BINDINGS @@ -139,6 +140,13 @@ public: void FinishFrame(Uint64 CompletedFenceValue); + DescriptorPoolAllocation AllocateDynamicDescriptorSet(VkDescriptorSetLayout SetLayout) + { + // Descriptor pools are externally synchronized, meaning that the application must not allocate + // and/or free descriptor sets from the same pool in multiple threads simultaneously (13.2.3) + return m_DynamicDescriptorPool.Allocate(SetLayout); + } + private: void CommitRenderPassAndFramebuffer(class PipelineStateVkImpl *pPipelineStateVk); void CommitVkVertexBuffers(); @@ -186,6 +194,7 @@ private: ResourceReleaseQueue<DynamicStaleResourceWrapper> m_ReleaseQueue; VulkanUtilities::VulkanUploadHeap m_UploadHeap; + DescriptorPoolManager m_DynamicDescriptorPool; // Number of the command buffer currently being recorded by the context and that will // be submitted next diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h index 7f26427f..b8bdddfc 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h +++ b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h @@ -78,8 +78,7 @@ public: // Allocates Vulkan descriptor set for dynamic resources and assigns the // set to the resource cache - void AllocateDynamicDescriptorSet(RenderDeviceVkImpl* pDevicVkImpl, - DeviceContextVkImpl* pCtxVkImpl, + void AllocateDynamicDescriptorSet(DeviceContextVkImpl* pCtxVkImpl, ShaderResourceCacheVk& ResourceCache)const; // Binds Vulkan descriptor sets to the command buffer in the cmd context diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h index 331e64bf..7aa33423 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h @@ -115,18 +115,12 @@ public: DescriptorPoolAllocation AllocateDescriptorSet(VkDescriptorSetLayout SetLayout) { - return m_DescriptorPools[0].Allocate(SetLayout); - } - DescriptorPoolAllocation AllocateDynamicDescriptorSet(VkDescriptorSetLayout SetLayout, Uint32 CtxId) - { - // Descriptor pools are externally synchronized, meaning that the application must not allocate - // and/or free descriptor sets from the same pool in multiple threads simultaneously (13.2.3) - return m_DescriptorPools[1 + CtxId].Allocate(SetLayout); + return m_MainDescriptorPool.Allocate(SetLayout); } std::shared_ptr<const VulkanUtilities::VulkanInstance> GetVulkanInstance()const{return m_VulkanInstance;} - const VulkanUtilities::VulkanPhysicalDevice &GetPhysicalDevice(){return *m_PhysicalDevice;} - const auto &GetLogicalDevice(){return *m_LogicalVkDevice;} + const VulkanUtilities::VulkanPhysicalDevice& GetPhysicalDevice(){return *m_PhysicalDevice;} + const VulkanUtilities::VulkanLogicalDevice& GetLogicalDevice(){return *m_LogicalVkDevice;} FramebufferCache& GetFramebufferCache(){return m_FramebufferCache;} VulkanUtilities::VulkanMemoryAllocation AllocateMemory(const VkMemoryRequirements& MemReqs, VkMemoryPropertyFlags MemoryProperties) @@ -136,7 +130,7 @@ public: private: virtual void TestTextureFormat( TEXTURE_FORMAT TexFormat )override final; - void ProcessReleaseQueue(Uint64 CompletedFenceValue); + void ProcessStaleResources(Uint64 SubmittedCmdBufferNumber, Uint64 SubmittedFenceValue, Uint64 CompletedFenceValue); // Submits command buffer for execution to the command queue // Returns the submitted command buffer number and the fence value that has been set to signal by GPU @@ -186,10 +180,7 @@ private: FramebufferCache m_FramebufferCache; - // [0] - Main descriptor pool - // [1] - Immediate context dynamic descriptor pool - // [2+] - Deferred context dynamic descriptor pool - std::vector<DescriptorPoolManager, STDAllocatorRawMem<DescriptorPoolManager> > m_DescriptorPools; + DescriptorPoolManager m_MainDescriptorPool; // These one-time command pools are used by buffer and texture constructors to // issue copy commands. Vulkan requires that every command pool is used by one thread diff --git a/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp b/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp index bca37fff..d6c22d8a 100644 --- a/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp @@ -60,9 +60,7 @@ DescriptorPoolAllocation DescriptorPoolManager::Allocate(VkDescriptorSetLayout S { // Descriptor pools are externally synchronized, meaning that the application must not allocate // and/or free descriptor sets from the same pool in multiple threads simultaneously (13.2.3) - std::unique_lock<std::mutex> Lock(m_Mutex, std::defer_lock); - if (m_IsThreadSafe) - Lock.lock(); + std::lock_guard<std::mutex> Lock(m_Mutex); // Try all pools starting from the frontmost for(auto it = m_DescriptorPools.begin(); it != m_DescriptorPools.end(); ++it) @@ -93,19 +91,13 @@ DescriptorPoolAllocation DescriptorPoolManager::Allocate(VkDescriptorSetLayout S void DescriptorPoolManager::FreeAllocation(VkDescriptorSet Set, VulkanUtilities::VulkanDescriptorPool& Pool) { - std::unique_lock<std::mutex> Lock(m_Mutex, std::defer_lock); - if (m_IsThreadSafe) - Lock.lock(); - + std::lock_guard<std::mutex> Lock(m_Mutex); m_ReleasedAllocations.emplace_back(std::make_pair(Set, &Pool)); } void DescriptorPoolManager::DisposeAllocations(uint64_t FenceValue) { - std::unique_lock<std::mutex> Lock(m_Mutex, std::defer_lock); - if (m_IsThreadSafe) - Lock.lock(); - + std::lock_guard<std::mutex> Lock(m_Mutex); for(auto &Allocation : m_ReleasedAllocations) { Allocation.second->DisposeDescriptorSet(Allocation.first, FenceValue); @@ -115,10 +107,7 @@ void DescriptorPoolManager::DisposeAllocations(uint64_t FenceValue) void DescriptorPoolManager::ReleaseStaleAllocations(uint64_t LastCompletedFence) { - std::unique_lock<std::mutex> Lock(m_Mutex, std::defer_lock); - if (m_IsThreadSafe) - Lock.lock(); - + std::lock_guard<std::mutex> Lock(m_Mutex); for(auto &Pool : m_DescriptorPools) Pool->ReleaseDiscardedSets(LastCompletedFence); } diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 8e54e049..84779d77 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -64,6 +64,25 @@ namespace Diligent bIsDeferred ? Attribs.DeferredCtxUploadHeapPageSize : Attribs.ImmediateCtxUploadHeapPageSize, bIsDeferred ? Attribs.DeferredCtxUploadHeapReserveSize : Attribs.ImmediateCtxUploadHeapReserveSize }, + // Descriptor pools must always be thread-safe as for a deferred context, Finish() may be called from another thread + m_DynamicDescriptorPool + { + pDeviceVkImpl->GetLogicalDevice().GetSharedPtr(), + std::vector<VkDescriptorPoolSize> + { + {VK_DESCRIPTOR_TYPE_SAMPLER, Attribs.DynamicDescriptorPoolSize.NumSeparateSamplerDescriptors}, + {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, Attribs.DynamicDescriptorPoolSize.NumCombinedSamplerDescriptors}, + {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, Attribs.DynamicDescriptorPoolSize.NumSampledImageDescriptors}, + {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, Attribs.DynamicDescriptorPoolSize.NumStorageImageDescriptors}, + {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, Attribs.DynamicDescriptorPoolSize.NumUniformTexelBufferDescriptors}, + {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, Attribs.DynamicDescriptorPoolSize.NumStorageTexelBufferDescriptors}, + {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, Attribs.DynamicDescriptorPoolSize.NumUniformBufferDescriptors }, + {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, Attribs.DynamicDescriptorPoolSize.NumStorageBufferDescriptors }, + //{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, Attribs.DynamicDescriptorPoolSize.NumUniformBufferDescriptors }, + //{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, Attribs.DynamicDescriptorPoolSize.NumStorageBufferDescriptors }, + }, + Attribs.DynamicDescriptorPoolSize.MaxDescriptorSets, + }, m_NextCmdBuffNumber(0) { #if 0 @@ -752,6 +771,7 @@ namespace Diligent { m_ReleaseQueue.Purge(CompletedFenceValue); m_UploadHeap.ShrinkMemory(); + m_DynamicDescriptorPool.ReleaseStaleAllocations(CompletedFenceValue); } void DeviceContextVkImpl::ReleaseStaleContextResources(Uint64 SubmittedCmdBufferNumber, Uint64 SubmittedFenceValue, Uint64 CompletedFenceValue) @@ -759,6 +779,8 @@ namespace Diligent m_ReleaseQueue.DiscardStaleResources(SubmittedCmdBufferNumber, SubmittedFenceValue); m_ReleaseQueue.Purge(CompletedFenceValue); m_UploadHeap.ShrinkMemory(); + m_DynamicDescriptorPool.DisposeAllocations(SubmittedFenceValue); + m_DynamicDescriptorPool.ReleaseStaleAllocations(CompletedFenceValue); } void DeviceContextVkImpl::Flush() diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp index c5bac746..e5d356f9 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp @@ -406,14 +406,13 @@ void PipelineLayout::InitResourceCache(RenderDeviceVkImpl *pDeviceVkImpl, Shader } } -void PipelineLayout::AllocateDynamicDescriptorSet(RenderDeviceVkImpl* pDevicVkImpl, - DeviceContextVkImpl* pCtxVkImpl, +void PipelineLayout::AllocateDynamicDescriptorSet(DeviceContextVkImpl* pCtxVkImpl, ShaderResourceCacheVk& ResourceCache)const { const auto &DynSet = m_LayoutMgr.GetDescriptorSet(SHADER_VARIABLE_TYPE_DYNAMIC); if (DynSet.SetIndex >= 0) { - auto DynamicSetAllocation = pDevicVkImpl->AllocateDynamicDescriptorSet(DynSet.VkLayout, pCtxVkImpl->GetContextId()); + auto DynamicSetAllocation = pCtxVkImpl->AllocateDynamicDescriptorSet(DynSet.VkLayout); auto &DynamicSetCache = ResourceCache.GetDescriptorSet(DynSet.SetIndex); DynamicSetCache.AssignDescriptorSetAllocation(std::move(DynamicSetAllocation)); } diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 3cdd2b62..8874b0b7 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -557,9 +557,8 @@ ShaderResourceCacheVk* PipelineStateVkImpl::CommitAndTransitionShaderResources(I #endif } - auto *pDeviceVkImpl = ValidatedCast<RenderDeviceVkImpl>(GetDevice()); // Allocate vulkan descriptor set for dynamic resources - m_PipelineLayout.AllocateDynamicDescriptorSet(pDeviceVkImpl, pCtxVkImpl, ResourceCache); + m_PipelineLayout.AllocateDynamicDescriptorSet(pCtxVkImpl, ResourceCache); // Commit all dynamic resource descriptors for(Uint32 s=0; s < m_NumShaders; ++s) { diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index 104089a7..6e98bd1b 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -66,27 +66,12 @@ RenderDeviceVkImpl :: RenderDeviceVkImpl(IReferenceCounters* m_EngineAttribs(CreationAttribs), m_FrameNumber(0), m_NextCmdBuffNumber(0), - /*m_CmdListManager(this), - m_ContextPool(STD_ALLOCATOR_RAW_MEM(ContextPoolElemType, GetRawAllocator(), "Allocator for vector<unique_ptr<CommandContext>>")), - m_AvailableContexts(STD_ALLOCATOR_RAW_MEM(CommandContext*, GetRawAllocator(), "Allocator for vector<CommandContext*>")),*/ - m_DescriptorPools(STD_ALLOCATOR_RAW_MEM(DescriptorPoolManager, GetRawAllocator(), "Allocator for vector<DescriptorPoolManager>")), m_FramebufferCache(*this), - m_TransientCmdPoolMgr(*m_LogicalVkDevice, pCmdQueue->GetQueueFamilyIndex(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT), - m_MemoryMgr("Global resource memory manager", *m_LogicalVkDevice, *m_PhysicalDevice, GetRawAllocator(), CreationAttribs.DeviceLocalMemoryPageSize, CreationAttribs.HostVisibleMemoryPageSize, CreationAttribs.DeviceLocalMemoryReserveSize, CreationAttribs.HostVisibleMemoryReserveSize), - m_ReleaseQueue(GetRawAllocator()) -{ - m_DeviceCaps.DevType = DeviceType::Vulkan; - m_DeviceCaps.MajorVersion = 1; - m_DeviceCaps.MinorVersion = 0; - m_DeviceCaps.bSeparableProgramSupported = True; - m_DeviceCaps.bMultithreadedResourceCreationSupported = True; - for(int fmt = 1; fmt < m_TextureFormatsInfo.size(); ++fmt) - m_TextureFormatsInfo[fmt].Supported = true; // We will test every format on a specific hardware device - - m_DescriptorPools.reserve(2 + NumDeferredContexts); - m_DescriptorPools.emplace_back( + m_MainDescriptorPool + { m_LogicalVkDevice, - std::vector<VkDescriptorPoolSize>{ + std::vector<VkDescriptorPoolSize> + { {VK_DESCRIPTOR_TYPE_SAMPLER, CreationAttribs.MainDescriptorPoolSize.NumSeparateSamplerDescriptors}, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, CreationAttribs.MainDescriptorPoolSize.NumCombinedSamplerDescriptors}, {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, CreationAttribs.MainDescriptorPoolSize.NumSampledImageDescriptors}, @@ -98,30 +83,19 @@ RenderDeviceVkImpl :: RenderDeviceVkImpl(IReferenceCounters* //{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, CreationAttribs.MainDescriptorPoolSize.NumUniformBufferDescriptors }, //{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, CreationAttribs.MainDescriptorPoolSize.NumStorageBufferDescriptors }, }, - CreationAttribs.MainDescriptorPoolSize.MaxDescriptorSets, - true // Thread-safe - ); - - for(Uint32 ctx = 0; ctx < 1 + NumDeferredContexts; ++ctx) - { - m_DescriptorPools.emplace_back( - m_LogicalVkDevice, - std::vector<VkDescriptorPoolSize>{ - {VK_DESCRIPTOR_TYPE_SAMPLER, CreationAttribs.DynamicDescriptorPoolSize.NumSeparateSamplerDescriptors}, - {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, CreationAttribs.DynamicDescriptorPoolSize.NumCombinedSamplerDescriptors}, - {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, CreationAttribs.DynamicDescriptorPoolSize.NumSampledImageDescriptors}, - {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, CreationAttribs.DynamicDescriptorPoolSize.NumStorageImageDescriptors}, - {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, CreationAttribs.DynamicDescriptorPoolSize.NumUniformTexelBufferDescriptors}, - {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, CreationAttribs.DynamicDescriptorPoolSize.NumStorageTexelBufferDescriptors}, - {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, CreationAttribs.DynamicDescriptorPoolSize.NumUniformBufferDescriptors }, - {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, CreationAttribs.DynamicDescriptorPoolSize.NumStorageBufferDescriptors }, - //{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, CreationAttribs.DynamicDescriptorPoolSize.NumUniformBufferDescriptors }, - //{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, CreationAttribs.DynamicDescriptorPoolSize.NumStorageBufferDescriptors }, - }, - CreationAttribs.DynamicDescriptorPoolSize.MaxDescriptorSets, - false // Dynamic descriptor pools need not to be thread-safe - ); - } + CreationAttribs.MainDescriptorPoolSize.MaxDescriptorSets + }, + m_TransientCmdPoolMgr(*m_LogicalVkDevice, pCmdQueue->GetQueueFamilyIndex(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT), + m_MemoryMgr("Global resource memory manager", *m_LogicalVkDevice, *m_PhysicalDevice, GetRawAllocator(), CreationAttribs.DeviceLocalMemoryPageSize, CreationAttribs.HostVisibleMemoryPageSize, CreationAttribs.DeviceLocalMemoryReserveSize, CreationAttribs.HostVisibleMemoryReserveSize), + m_ReleaseQueue(GetRawAllocator()) +{ + m_DeviceCaps.DevType = DeviceType::Vulkan; + m_DeviceCaps.MajorVersion = 1; + m_DeviceCaps.MinorVersion = 0; + m_DeviceCaps.bSeparableProgramSupported = True; + m_DeviceCaps.bMultithreadedResourceCreationSupported = True; + for(int fmt = 1; fmt < m_TextureFormatsInfo.size(); ++fmt) + m_TextureFormatsInfo[fmt].Supported = true; // We will test every format on a specific hardware device } RenderDeviceVkImpl::~RenderDeviceVkImpl() @@ -136,10 +110,6 @@ RenderDeviceVkImpl::~RenderDeviceVkImpl() // release queues FinishFrame(true); -#if 0 - m_ContextPool.clear(); -#endif - m_TransientCmdPoolMgr.DestroyPools(m_pCommandQueue->GetCompletedFenceValue()); //if(m_PhysicalDevice) @@ -260,35 +230,22 @@ Uint64 RenderDeviceVkImpl::ExecuteCommandBuffer(const VkSubmitInfo &SubmitInfo, // As long as resources used by deferred contexts are not released until the command list // is executed through immediate context, this stategy always works. - m_ReleaseQueue.DiscardStaleResources(SubmittedCmdBuffNumber, SubmittedFenceValue); auto CompletedFenceValue = GetCompletedFenceValue(); - ProcessReleaseQueue(CompletedFenceValue); - m_MemoryMgr.ShrinkMemory(); + ProcessStaleResources(SubmittedCmdBuffNumber, SubmittedFenceValue, CompletedFenceValue); -#if 0 - // DiscardAllocator() is thread-safe - m_CmdListManager.DiscardAllocator(FenceValue, pAllocator); - - pCtx->DiscardDynamicDescriptors(FenceValue); - - { - std::lock_guard<std::mutex> LockGuard(m_ContextAllocationMutex); - m_AvailableContexts.push_back(pCtx); - } -#endif return SubmittedFenceValue; } void RenderDeviceVkImpl::IdleGPU(bool ReleaseStaleObjects) { - Uint64 FenceValue = 0; - Uint64 CmdBuffNumber = 0; + Uint64 SubmittedFenceValue = 0; + Uint64 SubmittedCmdBuffNumber = 0; { // Lock the command queue to avoid other threads interfering with the GPU std::lock_guard<std::mutex> LockGuard(m_CmdQueueMutex); - FenceValue = m_pCommandQueue->GetNextFenceValue(); + SubmittedFenceValue = m_pCommandQueue->GetNextFenceValue(); m_pCommandQueue->IdleGPU(); m_LogicalVkDevice->WaitIdle(); @@ -296,7 +253,7 @@ void RenderDeviceVkImpl::IdleGPU(bool ReleaseStaleObjects) // Increment cmd list number while keeping queue locked. // This guarantees that any Vk object released after the lock // is released, will be associated with the incremented cmd list number - CmdBuffNumber = m_NextCmdBuffNumber; + SubmittedCmdBuffNumber = m_NextCmdBuffNumber; Atomics::AtomicIncrement(m_NextCmdBuffNumber); } @@ -306,11 +263,10 @@ void RenderDeviceVkImpl::IdleGPU(bool ReleaseStaleObjects) // This is necessary to release outstanding references to the // swap chain buffers when it is resized in the middle of the frame. // Since GPU has been idled, it it is safe to do so - m_ReleaseQueue.DiscardStaleResources(CmdBuffNumber, FenceValue); - // FenceValue has now been signaled by the GPU since we waited for it - auto CompletedFenceValue = FenceValue; - ProcessReleaseQueue(CompletedFenceValue); - m_MemoryMgr.ShrinkMemory(); + + // SubmittedFenceValue has now been signaled by the GPU since we waited for it + auto CompletedFenceValue = SubmittedFenceValue; + ProcessStaleResources(SubmittedCmdBuffNumber, SubmittedFenceValue, CompletedFenceValue); } } @@ -368,33 +324,23 @@ void RenderDeviceVkImpl::FinishFrame(bool ReleaseAllResources) Atomics::AtomicIncrement(m_NextCmdBuffNumber); } - { - // This is OK if other thread disposes descriptor heap allocation at this time - // The allocation will be registered as part of the current frame - for(auto &Pool : m_DescriptorPools) - Pool.DisposeAllocations(NextFenceValue); - } - // Discard all remaining objects. This is important to do if there were - // no command lists submitted during the frame - m_ReleaseQueue.DiscardStaleResources(SubmittedCmdBuffNumber, NextFenceValue); - ProcessReleaseQueue(CompletedFenceValue); - m_MemoryMgr.ShrinkMemory(); + // no command lists submitted during the frame. All stale resources will + // be associated with the next fence value and thus will not be released + // until the next command list is finished by the GPU + ProcessStaleResources(SubmittedCmdBuffNumber, NextFenceValue, CompletedFenceValue); + Atomics::AtomicIncrement(m_FrameNumber); } -void RenderDeviceVkImpl::ProcessReleaseQueue(Uint64 CompletedFenceValue) +void RenderDeviceVkImpl::ProcessStaleResources(Uint64 SubmittedCmdBufferNumber, Uint64 SubmittedFenceValue, Uint64 CompletedFenceValue) { + m_ReleaseQueue.DiscardStaleResources(SubmittedCmdBufferNumber, SubmittedFenceValue); m_ReleaseQueue.Purge(CompletedFenceValue); - - { - // This is OK if other thread disposes descriptor heap allocation at this time - // The allocation will be registered as part of the current frame - for(auto &Pool : m_DescriptorPools) - Pool.ReleaseStaleAllocations(CompletedFenceValue); - } + m_MainDescriptorPool.ReleaseStaleAllocations(CompletedFenceValue); + m_MemoryMgr.ShrinkMemory(); } |
