From a3f6a3fd03ce5ce6b785fae70c7c890eb6f8fb7c Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Thu, 4 Oct 2018 09:50:09 -0700 Subject: Added ReleaseStaleResources() to IRenderDevice interface + a bunch of minor chnages --- .../include/RenderDeviceD3D12Impl.h | 22 ++++++++---------- .../interface/RenderDeviceD3D12.h | 7 ------ .../src/DeviceContextD3D12Impl.cpp | 8 +++---- .../src/RenderDeviceD3D12Impl.cpp | 27 +++++++++++----------- 4 files changed, 27 insertions(+), 37 deletions(-) (limited to 'Graphics/GraphicsEngineD3D12') diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h index 85f39b5c..11316ef8 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h @@ -81,24 +81,23 @@ public: void IdleGPU(bool ReleaseStaleObjects); CommandContext* AllocateCommandContext(const Char *ID = ""); - void CloseAndExecuteTransientCommandContext(Uint32 CommandQueueIndex, CommandContext *pCtx); - Uint64 CloseAndExecuteCommandContext(CommandContext *pCtx, bool DiscardStaleObjects, std::vector > >* pSignalFences); - void DisposeCommandContext(CommandContext*); + void CloseAndExecuteTransientCommandContext(Uint32 CommandQueueIndex, CommandContext* pCtx); + Uint64 CloseAndExecuteCommandContext(Uint32 QueueIndex, CommandContext *pCtx, bool DiscardStaleObjects, std::vector > >* pSignalFences); + + // Disposes an unused command context + void DisposeCommandContext(CommandContext* pCtx); void FlushStaleResources(Uint32 CmdQueueIndex); - void ReleaseStaleResources(bool ForceRelease = false); + virtual void ReleaseStaleResources(bool ForceRelease = false)override final; D3D12DynamicMemoryManager& GetDynamicMemoryManager() {return m_DynamicMemoryManager;} GPUDescriptorHeap& GetGPUDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE Type) { + VERIFY_EXPR(Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || Type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); return m_GPUDescriptorHeaps[Type]; } - Uint32 GetDynamicDescriptorAllocationChunkSize(D3D12_DESCRIPTOR_HEAP_TYPE Type) - { - return m_DynamicDescriptorAllocationChunkSize[Type]; - } - + private: virtual void TestTextureFormat( TEXTURE_FORMAT TexFormat )override final; @@ -111,15 +110,14 @@ private: GPUDescriptorHeap m_GPUDescriptorHeaps[2]; // D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV == 0 // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER == 1 - const Uint32 m_DynamicDescriptorAllocationChunkSize[2]; - CommandListManager m_CmdListManager; typedef std::unique_ptr > ContextPoolElemType; std::vector< ContextPoolElemType, STDAllocatorRawMem > m_ContextPool; + std::mutex m_AvailableContextsMutex; std::deque > m_AvailableContexts; - std::mutex m_ContextAllocationMutex; + D3D12DynamicMemoryManager m_DynamicMemoryManager; }; diff --git a/Graphics/GraphicsEngineD3D12/interface/RenderDeviceD3D12.h b/Graphics/GraphicsEngineD3D12/interface/RenderDeviceD3D12.h index c7d91a87..18fc6dd4 100644 --- a/Graphics/GraphicsEngineD3D12/interface/RenderDeviceD3D12.h +++ b/Graphics/GraphicsEngineD3D12/interface/RenderDeviceD3D12.h @@ -55,13 +55,6 @@ public: /// that all associated work has been finished virtual Bool IsFenceSignaled(Uint32 QueueIndex, Uint64 FenceValue) = 0; - /// Purges device release queues and releases all stale resources. - /// This method is automatically called by ISwapChain::Present(). - /// \param [in] ForceRelease - Forces release of all objects. Use this option with - /// great care only if you are sure the resources are not - /// in use by the GPU (such as when the device has just been idled). - virtual void ReleaseStaleResources(bool ForceRelease = false) = 0; - /// Creates a texture object from native d3d12 resource /// \param [in] pd3d12Texture - pointer to the native D3D12 texture diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index f2732a65..e93106d8 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -77,12 +77,12 @@ namespace Diligent { GetRawAllocator(), pDeviceD3D12Impl->GetGPUDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV), - pDeviceD3D12Impl->GetDynamicDescriptorAllocationChunkSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) + Attribs.DynamicDescriptorAllocationChunkSize[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] }, { GetRawAllocator(), pDeviceD3D12Impl->GetGPUDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER), - pDeviceD3D12Impl->GetDynamicDescriptorAllocationChunkSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) + Attribs.DynamicDescriptorAllocationChunkSize[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER] } }, m_NumCommandsInCurCtx(0), @@ -547,7 +547,7 @@ namespace Diligent if (m_NumCommandsInCurCtx != 0) { m_pCurrCmdCtx->FlushResourceBarriers(); - pDeviceD3D12Impl->CloseAndExecuteCommandContext(m_pCurrCmdCtx, true, &m_PendingFences); + pDeviceD3D12Impl->CloseAndExecuteCommandContext(m_CommandQueueId, m_pCurrCmdCtx, true, &m_PendingFences); m_PendingFences.clear(); } else @@ -1072,7 +1072,7 @@ namespace Diligent CommandContext* pCmdContext = nullptr; RefCntAutoPtr pDeferredCtx; pCmdListD3D12->Close(pCmdContext, pDeferredCtx); - m_pDevice.RawPtr()->CloseAndExecuteCommandContext(pCmdContext, true, nullptr); + m_pDevice.RawPtr()->CloseAndExecuteCommandContext(m_CommandQueueId, pCmdContext, true, nullptr); // Set the bit in the deferred context cmd queue mask corresponding to cmd queue of this context pDeferredCtx->m_SubmittedBuffersCmdQueueMask |= Uint64{1} << m_CommandQueueId; } diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index 2812402d..91f87a47 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -76,11 +76,6 @@ RenderDeviceD3D12Impl :: RenderDeviceD3D12Impl(IReferenceCounters* pRef {RawMemAllocator, *this, CreationAttribs.GPUDescriptorHeapSize[0], CreationAttribs.GPUDescriptorHeapDynamicSize[0], D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE}, {RawMemAllocator, *this, CreationAttribs.GPUDescriptorHeapSize[1], CreationAttribs.GPUDescriptorHeapDynamicSize[1], D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE} }, - m_DynamicDescriptorAllocationChunkSize - { - CreationAttribs.DynamicDescriptorAllocationChunkSize[0], // D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV - CreationAttribs.DynamicDescriptorAllocationChunkSize[1] // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER - }, m_ContextPool(STD_ALLOCATOR_RAW_MEM(ContextPoolElemType, GetRawAllocator(), "Allocator for vector>")), m_AvailableContexts(STD_ALLOCATOR_RAW_MEM(CommandContext*, GetRawAllocator(), "Allocator for vector")), m_DynamicMemoryManager(GetRawAllocator(), *this, CreationAttribs.NumDynamicHeapPagesToReserve, CreationAttribs.DynamicHeapPageSize) @@ -101,6 +96,7 @@ RenderDeviceD3D12Impl::~RenderDeviceD3D12Impl() DEV_CHECK_ERR(m_DynamicMemoryManager.GetAllocatedPageCounter() == 0, "All allocated dynamic pages must have been returned to the manager at this point."); m_DynamicMemoryManager.Destroy(); DEV_CHECK_ERR(m_CmdListManager.GetAllocatorCounter() == 0, "All allocators must have been returned to the manager at this point."); + DEV_CHECK_ERR(m_AvailableContexts.size() == m_ContextPool.size(), "All contexts must have been released."); m_ContextPool.clear(); DestroyCommandQueues(); @@ -108,12 +104,14 @@ RenderDeviceD3D12Impl::~RenderDeviceD3D12Impl() void RenderDeviceD3D12Impl::DisposeCommandContext(CommandContext* pCtx) { - std::lock_guard LockGuard(m_ContextAllocationMutex); - CComPtr pAllocator; + CComPtr pAllocator; pCtx->Close(pAllocator); - // Since allocator has not been used, we can add it directly to the free allocator list + // Since allocator has not been used, we cmd list manager can put it directly into the free allocator list m_CmdListManager.FreeAllocator(std::move(pAllocator)); - m_AvailableContexts.push_back(pCtx); + { + std::lock_guard LockGuard(m_AvailableContextsMutex); + m_AvailableContexts.push_back(pCtx); + } } void RenderDeviceD3D12Impl::CloseAndExecuteTransientCommandContext(Uint32 CommandQueueIndex, CommandContext *pCtx) @@ -132,17 +130,16 @@ void RenderDeviceD3D12Impl::CloseAndExecuteTransientCommandContext(Uint32 Comman m_CmdListManager.ReleaseAllocator(std::move(pAllocator), CommandQueueIndex, FenceValue); { - std::lock_guard LockGuard(m_ContextAllocationMutex); + std::lock_guard LockGuard(m_AvailableContextsMutex); m_AvailableContexts.push_back(pCtx); } } -Uint64 RenderDeviceD3D12Impl::CloseAndExecuteCommandContext(CommandContext* pCtx, bool DiscardStaleObjects, std::vector > >* pSignalFences) +Uint64 RenderDeviceD3D12Impl::CloseAndExecuteCommandContext(Uint32 QueueIndex, CommandContext* pCtx, bool DiscardStaleObjects, std::vector > >* pSignalFences) { CComPtr pAllocator; ID3D12GraphicsCommandList* pCmdList = pCtx->Close(pAllocator); - Uint32 QueueIndex = 0; Uint64 FenceValue = 0; { // Stale objects should only be discarded when submitting cmd list from @@ -179,10 +176,12 @@ Uint64 RenderDeviceD3D12Impl::CloseAndExecuteCommandContext(CommandContext* pCtx m_CmdListManager.ReleaseAllocator(std::move(pAllocator), QueueIndex, FenceValue); { - std::lock_guard LockGuard(m_ContextAllocationMutex); + std::lock_guard LockGuard(m_AvailableContextsMutex); m_AvailableContexts.push_back(pCtx); } + PurgeReleaseQueue(QueueIndex); + return FenceValue; } @@ -211,7 +210,7 @@ void RenderDeviceD3D12Impl::ReleaseStaleResources(bool ForceRelease) CommandContext* RenderDeviceD3D12Impl::AllocateCommandContext(const Char* ID) { - std::lock_guard LockGuard(m_ContextAllocationMutex); + std::lock_guard LockGuard(m_AvailableContextsMutex); CommandContext* ret = nullptr; if (m_AvailableContexts.empty()) -- cgit v1.2.3