diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-10-05 04:51:33 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-10-05 04:51:33 +0000 |
| commit | c7391919d2e9d34e7f4fc18e8ffc174a9eabfb5e (patch) | |
| tree | 1ff73fa0f1ae15b057db84bdeb12de1c5b19b97f /Graphics/GraphicsEngineD3D12 | |
| parent | Added ReleaseStaleResources() to IRenderDevice interface + a bunch of minor c... (diff) | |
| download | DiligentCore-c7391919d2e9d34e7f4fc18e8ffc174a9eabfb5e.tar.gz DiligentCore-c7391919d2e9d34e7f4fc18e8ffc174a9eabfb5e.zip | |
Reworked context pool management in D3D12
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
14 files changed, 140 insertions, 146 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/CommandContext.h b/Graphics/GraphicsEngineD3D12/include/CommandContext.h index 717354f3..c3b0d6f7 100644 --- a/Graphics/GraphicsEngineD3D12/include/CommandContext.h +++ b/Graphics/GraphicsEngineD3D12/include/CommandContext.h @@ -60,6 +60,10 @@ class CommandContext public: CommandContext( class CommandListManager& CmdListManager); + CommandContext (const CommandContext&) = delete; + CommandContext& operator = (const CommandContext&) = delete; + CommandContext ( CommandContext&&) = delete; + CommandContext& operator = ( CommandContext&&) = delete; ~CommandContext(); diff --git a/Graphics/GraphicsEngineD3D12/include/CommandListD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/CommandListD3D12Impl.h index b9c43692..09e295b7 100644 --- a/Graphics/GraphicsEngineD3D12/include/CommandListD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/CommandListD3D12Impl.h @@ -41,13 +41,13 @@ class CommandListD3D12Impl final : public CommandListBase<ICommandList, RenderDe public: using TCommandListBase = CommandListBase<ICommandList, RenderDeviceD3D12Impl>; - CommandListD3D12Impl(IReferenceCounters* pRefCounters, - RenderDeviceD3D12Impl* pDevice, - DeviceContextD3D12Impl* pDeferredCtx, - CommandContext* pCmdContext) : + CommandListD3D12Impl(IReferenceCounters* pRefCounters, + RenderDeviceD3D12Impl* pDevice, + DeviceContextD3D12Impl* pDeferredCtx, + RenderDeviceD3D12Impl::PooledCommandContext&& pCmdContext) : TCommandListBase(pRefCounters, pDevice), m_pDeferredCtx (pDeferredCtx), - m_pCmdContext (pCmdContext) + m_pCmdContext (std::move(pCmdContext)) { } @@ -56,16 +56,15 @@ public: DEV_CHECK_ERR(m_pCmdContext == nullptr && m_pDeferredCtx == nullptr, "Destroying a command list that has not been executed"); } - void Close(CommandContext*& pCmdContext, RefCntAutoPtr<DeviceContextD3D12Impl>& pDeferredCtx) + RenderDeviceD3D12Impl::PooledCommandContext Close(RefCntAutoPtr<DeviceContextD3D12Impl>& pDeferredCtx) { - pCmdContext = m_pCmdContext; - m_pCmdContext = nullptr; pDeferredCtx = std::move(m_pDeferredCtx); + return std::move(m_pCmdContext); } private: - RefCntAutoPtr<DeviceContextD3D12Impl> m_pDeferredCtx; - CommandContext* m_pCmdContext = nullptr; + RefCntAutoPtr<DeviceContextD3D12Impl> m_pDeferredCtx; + RenderDeviceD3D12Impl::PooledCommandContext m_pCmdContext; }; } diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h index 4136f517..fa0e4e19 100644 --- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h @@ -183,15 +183,15 @@ private: friend class SwapChainD3D12Impl; - inline class CommandContext* RequestCmdContext() + inline class CommandContext& GetCmdContext() { // Make sure that the number of commands in the context is at least one, // so that the context cannot be disposed by Flush() m_NumCommandsInCurCtx = m_NumCommandsInCurCtx != 0 ? m_NumCommandsInCurCtx : 1; - return m_pCurrCmdCtx; + return *m_CurrCmdCtx; } size_t m_NumCommandsInCurCtx = 0; - CommandContext* m_pCurrCmdCtx = nullptr; + std::unique_ptr<CommandContext, STDDeleterRawMem<CommandContext> > m_CurrCmdCtx; CComPtr<ID3D12Resource> m_CommittedD3D12IndexBuffer; VALUE_TYPE m_CommittedIBFormat = VT_UNDEFINED; diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h index 11316ef8..64978ea0 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.h @@ -25,7 +25,6 @@ /// \file /// Declaration of Diligent::RenderDeviceD3D12Impl class - #include "RenderDeviceD3D12.h" #include "RenderDeviceD3DBase.h" #include "RenderDeviceNextGenBase.h" @@ -80,12 +79,14 @@ public: DescriptorHeapAllocation AllocateGPUDescriptors( D3D12_DESCRIPTOR_HEAP_TYPE Type, UINT Count = 1 ); void IdleGPU(bool ReleaseStaleObjects); - CommandContext* AllocateCommandContext(const Char *ID = ""); - void CloseAndExecuteTransientCommandContext(Uint32 CommandQueueIndex, CommandContext* pCtx); - Uint64 CloseAndExecuteCommandContext(Uint32 QueueIndex, CommandContext *pCtx, bool DiscardStaleObjects, std::vector<std::pair<Uint64, RefCntAutoPtr<IFence> > >* pSignalFences); - + + using PooledCommandContext = std::unique_ptr<CommandContext, STDDeleterRawMem<CommandContext> >; + PooledCommandContext AllocateCommandContext(const Char *ID = ""); + void CloseAndExecuteTransientCommandContext(Uint32 CommandQueueIndex, PooledCommandContext&& Ctx); + Uint64 CloseAndExecuteCommandContext(Uint32 QueueIndex, PooledCommandContext&& Ctx, bool DiscardStaleObjects, std::vector<std::pair<Uint64, RefCntAutoPtr<IFence> > >* pSignalFences); + // Disposes an unused command context - void DisposeCommandContext(CommandContext* pCtx); + void DisposeCommandContext(PooledCommandContext&& Ctx); void FlushStaleResources(Uint32 CmdQueueIndex); virtual void ReleaseStaleResources(bool ForceRelease = false)override final; @@ -100,8 +101,8 @@ public: private: virtual void TestTextureFormat( TEXTURE_FORMAT TexFormat )override final; + void FreeCommandContext(PooledCommandContext&& Ctx); - /// D3D12 device CComPtr<ID3D12Device> m_pd3d12Device; EngineD3D12Attribs m_EngineAttribs; @@ -112,12 +113,11 @@ private: CommandListManager m_CmdListManager; - typedef std::unique_ptr<CommandContext, STDDeleterRawMem<CommandContext> > ContextPoolElemType; - std::vector< ContextPoolElemType, STDAllocatorRawMem<ContextPoolElemType> > m_ContextPool; - - std::mutex m_AvailableContextsMutex; - std::deque<CommandContext*, STDAllocatorRawMem<CommandContext*> > m_AvailableContexts; - + std::mutex m_ContextPoolMutex; + std::vector< PooledCommandContext, STDAllocatorRawMem<PooledCommandContext> > m_ContextPool; +#ifdef DEVELOPMENT + Atomics::AtomicLong m_AllocatedCtxCounter = 0; +#endif D3D12DynamicMemoryManager m_DynamicMemoryManager; }; diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h index f32e89eb..460c06c6 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h @@ -109,7 +109,7 @@ namespace Diligent class ShaderResourceLayoutD3D12 final { public: - ShaderResourceLayoutD3D12(IObject& Owner, IMemoryAllocator& ResourceLayoutDataAllocator); + ShaderResourceLayoutD3D12(IObject& Owner); ShaderResourceLayoutD3D12 (const ShaderResourceLayoutD3D12&) = delete; ShaderResourceLayoutD3D12 (ShaderResourceLayoutD3D12&&) = delete; diff --git a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp index 155a8fc6..3c6ca015 100644 --- a/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/BufferD3D12Impl.cpp @@ -175,13 +175,13 @@ BufferD3D12Impl :: BufferD3D12Impl(IReferenceCounters* pRefCounters, memcpy(DestAddress, BuffData.pData, BuffData.DataSize); UploadBuffer->Unmap(0, nullptr); - auto *pInitContext = pRenderDeviceD3D12->AllocateCommandContext(); + auto InitContext = pRenderDeviceD3D12->AllocateCommandContext(); // copy data to the intermediate upload heap and then schedule a copy from the upload heap to the default buffer VERIFY_EXPR(m_UsageState == D3D12_RESOURCE_STATE_COPY_DEST); // We MUST NOT call TransitionResource() from here, because // it will call AddRef() and potentially Release(), while // the object is not constructed yet - pInitContext->CopyResource(m_pd3d12Resource, UploadBuffer); + InitContext->CopyResource(m_pd3d12Resource, UploadBuffer); // Command list fence should only be signaled when submitting cmd list // from the immediate context, otherwise the basic requirement will be violated @@ -202,7 +202,7 @@ BufferD3D12Impl :: BufferD3D12Impl(IReferenceCounters* pRefCounters, // | was added to the delete queue | | // | with value N | | Uint32 QueueIndex = 0; - pRenderDeviceD3D12->CloseAndExecuteTransientCommandContext(QueueIndex, pInitContext); + pRenderDeviceD3D12->CloseAndExecuteTransientCommandContext(QueueIndex, std::move(InitContext)); // Add reference to the object to the release queue to keep it alive // until copy operation is complete. This must be done after diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index e93106d8..12d981d5 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -120,7 +120,7 @@ namespace Diligent DeviceContextD3D12Impl::~DeviceContextD3D12Impl() { if(m_bIsDeferred) - m_pDevice.RawPtr<RenderDeviceD3D12Impl>()->DisposeCommandContext(m_pCurrCmdCtx); + m_pDevice.RawPtr<RenderDeviceD3D12Impl>()->DisposeCommandContext(std::move(m_CurrCmdCtx)); else { if (m_NumCommandsInCurCtx != 0) @@ -178,16 +178,16 @@ namespace Diligent TDeviceContextBase::SetPipelineState( pPipelineStateD3D12, 0 /*Dummy*/ ); - auto *pCmdCtx = RequestCmdContext(); + auto& CmdCtx = GetCmdContext(); auto *pd3d12PSO = pPipelineStateD3D12->GetD3D12PipelineState(); if (PSODesc.IsComputePipeline) { - pCmdCtx->AsComputeContext().SetPipelineState(pd3d12PSO); + CmdCtx.AsComputeContext().SetPipelineState(pd3d12PSO); } else { - auto &GraphicsCtx = pCmdCtx->AsGraphicsContext(); + auto &GraphicsCtx = CmdCtx.AsGraphicsContext(); GraphicsCtx.SetPipelineState(pd3d12PSO); auto D3D12Topology = TopologyToD3D12Topology(PSODesc.GraphicsPipeline.PrimitiveTopology); @@ -213,9 +213,9 @@ namespace Diligent { VERIFY_EXPR(pPipelineState != nullptr); - auto *pCtx = RequestCmdContext(); + auto& Ctx = GetCmdContext(); auto *pPipelineStateD3D12 = ValidatedCast<PipelineStateD3D12Impl>(pPipelineState); - pPipelineStateD3D12->CommitAndTransitionShaderResources(pShaderResourceBinding, *pCtx, false, true); + pPipelineStateD3D12->CommitAndTransitionShaderResources(pShaderResourceBinding, Ctx, false, true); } void DeviceContextD3D12Impl::CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, Uint32 Flags) @@ -223,15 +223,15 @@ namespace Diligent if (!DeviceContextBase::CommitShaderResources(pShaderResourceBinding, Flags, 0 /*Dummy*/)) return; - auto *pCtx = RequestCmdContext(); - m_pCommittedResourceCache = m_pPipelineState->CommitAndTransitionShaderResources(pShaderResourceBinding, *pCtx, true, (Flags & COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES)!=0); + auto& Ctx = GetCmdContext(); + m_pCommittedResourceCache = m_pPipelineState->CommitAndTransitionShaderResources(pShaderResourceBinding, Ctx, true, (Flags & COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES)!=0); } void DeviceContextD3D12Impl::SetStencilRef(Uint32 StencilRef) { if (TDeviceContextBase::SetStencilRef(StencilRef, 0)) { - RequestCmdContext()->AsGraphicsContext().SetStencilRef( m_StencilRef ); + GetCmdContext().AsGraphicsContext().SetStencilRef( m_StencilRef ); } } @@ -239,7 +239,7 @@ namespace Diligent { if (TDeviceContextBase::SetBlendFactors(m_BlendFactors, 0)) { - RequestCmdContext()->AsGraphicsContext().SetBlendFactor( m_BlendFactors ); + GetCmdContext().AsGraphicsContext().SetBlendFactor( m_BlendFactors ); } } @@ -263,7 +263,7 @@ namespace Diligent // Device context keeps strong reference to bound index buffer. // When the buffer is unbound, the reference to the D3D12 resource // is added to the context. There is no need to add reference here - //auto &GraphicsCtx = RequestCmdContext()->AsGraphicsContext(); + //auto &GraphicsCtx = GetCmdContext().AsGraphicsContext(); //auto *pd3d12Resource = pBuffD3D12->GetD3D12Buffer(); //GraphicsCtx.AddReferencedObject(pd3d12Resource); @@ -272,7 +272,7 @@ namespace Diligent if(IsDynamic) pBuffD3D12->DvpVerifyDynamicAllocation(this); #endif - auto &GraphicsCtx = RequestCmdContext()->AsGraphicsContext(); + auto& GraphicsCtx = GetCmdContext().AsGraphicsContext(); // Resource transitioning must always be performed! GraphicsCtx.TransitionResource(pBuffD3D12, D3D12_RESOURCE_STATE_INDEX_BUFFER, true); @@ -361,7 +361,7 @@ namespace Diligent return; #endif - auto &GraphCtx = RequestCmdContext()->AsGraphicsContext(); + auto& GraphCtx = GetCmdContext().AsGraphicsContext(); if( drawAttribs.IsIndexed ) { if( m_CommittedIBFormat != drawAttribs.IndexType ) @@ -427,7 +427,7 @@ namespace Diligent return; #endif - auto& ComputeCtx = RequestCmdContext()->AsComputeContext(); + auto& ComputeCtx = GetCmdContext().AsComputeContext(); ComputeCtx.SetRootSignature( m_pPipelineState->GetD3D12RootSignature() ); if(m_pCommittedResourceCache != nullptr) @@ -494,7 +494,7 @@ namespace Diligent if( ClearFlags & CLEAR_STENCIL_FLAG ) d3d12ClearFlags |= D3D12_CLEAR_FLAG_STENCIL; // The full extent of the resource view is always cleared. // Viewport and scissor settings are not applied?? - RequestCmdContext()->AsGraphicsContext().ClearDepthStencil( pDSVD3D12, d3d12ClearFlags, fDepth, Stencil ); + GetCmdContext().AsGraphicsContext().ClearDepthStencil( pDSVD3D12, d3d12ClearFlags, fDepth, Stencil ); ++m_NumCommandsInCurCtx; } @@ -528,30 +528,30 @@ namespace Diligent // The full extent of the resource view is always cleared. // Viewport and scissor settings are not applied?? - RequestCmdContext()->AsGraphicsContext().ClearRenderTarget( pd3d12RTV, RGBA ); + GetCmdContext().AsGraphicsContext().ClearRenderTarget( pd3d12RTV, RGBA ); ++m_NumCommandsInCurCtx; } void DeviceContextD3D12Impl::RequestCommandContext(RenderDeviceD3D12Impl* pDeviceD3D12Impl) { - m_pCurrCmdCtx = pDeviceD3D12Impl->AllocateCommandContext(); - m_pCurrCmdCtx->SetDynamicGPUDescriptorAllocators(m_DynamicGPUDescriptorAllocator); + m_CurrCmdCtx = pDeviceD3D12Impl->AllocateCommandContext(); + m_CurrCmdCtx->SetDynamicGPUDescriptorAllocators(m_DynamicGPUDescriptorAllocator); } void DeviceContextD3D12Impl::Flush(bool RequestNewCmdCtx) { auto pDeviceD3D12Impl = m_pDevice.RawPtr<RenderDeviceD3D12Impl>(); - if( m_pCurrCmdCtx ) + if( m_CurrCmdCtx ) { VERIFY(!m_bIsDeferred, "Deferred contexts cannot execute command lists directly"); if (m_NumCommandsInCurCtx != 0) { - m_pCurrCmdCtx->FlushResourceBarriers(); - pDeviceD3D12Impl->CloseAndExecuteCommandContext(m_CommandQueueId, m_pCurrCmdCtx, true, &m_PendingFences); + m_CurrCmdCtx->FlushResourceBarriers(); + pDeviceD3D12Impl->CloseAndExecuteCommandContext(m_CommandQueueId, std::move(m_CurrCmdCtx), true, &m_PendingFences); m_PendingFences.clear(); } else - pDeviceD3D12Impl->DisposeCommandContext(m_pCurrCmdCtx); + pDeviceD3D12Impl->DisposeCommandContext(std::move(m_CurrCmdCtx)); } if(RequestNewCmdCtx) @@ -626,7 +626,7 @@ namespace Diligent } // All viewports must be set atomically as one operation. // Any viewports not defined by the call are disabled. - RequestCmdContext()->AsGraphicsContext().SetViewports( m_NumViewports, d3d12Viewports ); + GetCmdContext().AsGraphicsContext().SetViewports( m_NumViewports, d3d12Viewports ); } void DeviceContextD3D12Impl::SetViewports( Uint32 NumViewports, const Viewport* pViewports, Uint32 RTWidth, Uint32 RTHeight ) @@ -704,7 +704,7 @@ namespace Diligent if(!PSODesc.IsComputePipeline && PSODesc.GraphicsPipeline.RasterizerDesc.ScissorEnable) { VERIFY(NumRects == m_NumScissorRects, "Unexpected number of scissor rects"); - auto &Ctx = RequestCmdContext()->AsGraphicsContext(); + auto& Ctx = GetCmdContext().AsGraphicsContext(); CommitScissorRects(Ctx, true); } } @@ -741,7 +741,7 @@ namespace Diligent ppRTVs[rt] = m_pBoundRenderTargets[rt].RawPtr<ITextureViewD3D12>(); pDSV = m_pBoundDepthStencil.RawPtr<ITextureViewD3D12>(); } - RequestCmdContext()->AsGraphicsContext().SetRenderTargets(NumRenderTargets, ppRTVs, pDSV); + GetCmdContext().AsGraphicsContext().SetRenderTargets(NumRenderTargets, ppRTVs, pDSV); } void DeviceContextD3D12Impl::SetRenderTargets( Uint32 NumRenderTargets, ITextureView *ppRenderTargets[], ITextureView *pDepthStencil ) @@ -762,13 +762,13 @@ namespace Diligent void DeviceContextD3D12Impl::UpdateBufferRegion(BufferD3D12Impl* pBuffD3D12, D3D12DynamicAllocation& Allocation, Uint64 DstOffset, Uint64 NumBytes) { - auto pCmdCtx = RequestCmdContext(); + auto& CmdCtx = GetCmdContext(); VERIFY_EXPR( static_cast<size_t>(NumBytes) == NumBytes ); - pCmdCtx->TransitionResource(pBuffD3D12, D3D12_RESOURCE_STATE_COPY_DEST, true); + CmdCtx.TransitionResource(pBuffD3D12, D3D12_RESOURCE_STATE_COPY_DEST, true); size_t DstBuffDataStartByteOffset; auto *pd3d12Buff = pBuffD3D12->GetD3D12Buffer(DstBuffDataStartByteOffset, this); VERIFY(DstBuffDataStartByteOffset == 0, "Dst buffer must not be suballocated"); - pCmdCtx->GetCommandList()->CopyBufferRegion( pd3d12Buff, DstOffset + DstBuffDataStartByteOffset, Allocation.pBuffer, Allocation.Offset, NumBytes); + CmdCtx.GetCommandList()->CopyBufferRegion( pd3d12Buff, DstOffset + DstBuffDataStartByteOffset, Allocation.pBuffer, Allocation.Offset, NumBytes); ++m_NumCommandsInCurCtx; } @@ -786,25 +786,25 @@ namespace Diligent { VERIFY(pDstBuffD3D12->GetDesc().Usage != USAGE_DYNAMIC, "Dynamic buffers cannot be copy destinations"); - auto pCmdCtx = RequestCmdContext(); - pCmdCtx->TransitionResource(pSrcBuffD3D12, D3D12_RESOURCE_STATE_COPY_SOURCE); - pCmdCtx->TransitionResource(pDstBuffD3D12, D3D12_RESOURCE_STATE_COPY_DEST, true); + auto& CmdCtx = GetCmdContext(); + CmdCtx.TransitionResource(pSrcBuffD3D12, D3D12_RESOURCE_STATE_COPY_SOURCE); + CmdCtx.TransitionResource(pDstBuffD3D12, D3D12_RESOURCE_STATE_COPY_DEST, true); size_t DstDataStartByteOffset; auto *pd3d12DstBuff = pDstBuffD3D12->GetD3D12Buffer(DstDataStartByteOffset, this); VERIFY(DstDataStartByteOffset == 0, "Dst buffer must not be suballocated"); size_t SrcDataStartByteOffset; auto *pd3d12SrcBuff = pSrcBuffD3D12->GetD3D12Buffer(SrcDataStartByteOffset, this); - pCmdCtx->GetCommandList()->CopyBufferRegion( pd3d12DstBuff, DstOffset + DstDataStartByteOffset, pd3d12SrcBuff, SrcOffset+SrcDataStartByteOffset, NumBytes); + CmdCtx.GetCommandList()->CopyBufferRegion( pd3d12DstBuff, DstOffset + DstDataStartByteOffset, pd3d12SrcBuff, SrcOffset+SrcDataStartByteOffset, NumBytes); ++m_NumCommandsInCurCtx; } void DeviceContextD3D12Impl::CopyTextureRegion(TextureD3D12Impl* pSrcTexture, Uint32 SrcSubResIndex, const D3D12_BOX* pD3D12SrcBox, TextureD3D12Impl* pDstTexture, Uint32 DstSubResIndex, Uint32 DstX, Uint32 DstY, Uint32 DstZ) { - auto pCmdCtx = RequestCmdContext(); - pCmdCtx->TransitionResource(pSrcTexture, D3D12_RESOURCE_STATE_COPY_SOURCE); - pCmdCtx->TransitionResource(pDstTexture, D3D12_RESOURCE_STATE_COPY_DEST, true); + auto& CmdCtx = GetCmdContext(); + CmdCtx.TransitionResource(pSrcTexture, D3D12_RESOURCE_STATE_COPY_SOURCE); + CmdCtx.TransitionResource(pDstTexture, D3D12_RESOURCE_STATE_COPY_DEST, true); D3D12_TEXTURE_COPY_LOCATION DstLocation = {}, SrcLocation = {}; @@ -816,7 +816,7 @@ namespace Diligent SrcLocation.pResource = pSrcTexture->GetD3D12Resource(); SrcLocation.SubresourceIndex = SrcSubResIndex; - pCmdCtx->GetCommandList()->CopyTextureRegion( &DstLocation, DstX, DstY, DstZ, &SrcLocation, pD3D12SrcBox); + CmdCtx.GetCommandList()->CopyTextureRegion( &DstLocation, DstX, DstY, DstZ, &SrcLocation, pD3D12SrcBox); ++m_NumCommandsInCurCtx; } @@ -830,8 +830,8 @@ namespace Diligent const Box& DstBox) { const auto& TexDesc = TextureD3D12.GetDesc(); - auto *pCmdCtx = RequestCmdContext(); - auto *pCmdList = pCmdCtx->GetCommandList(); + auto& CmdCtx = GetCmdContext(); + auto *pCmdList = CmdCtx.GetCommandList(); auto TextureState = TextureD3D12.GetState(); D3D12_RESOURCE_BARRIER BarrierDesc; BarrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; @@ -877,7 +877,7 @@ namespace Diligent D3D12SrcBox.bottom = Footpring.Footprint.Height; D3D12SrcBox.front = 0; D3D12SrcBox.back = Footpring.Footprint.Depth; - pCmdCtx->GetCommandList()->CopyTextureRegion( &DstLocation, + CmdCtx.GetCommandList()->CopyTextureRegion( &DstLocation, static_cast<UINT>( DstBox.MinX ), static_cast<UINT>( DstBox.MinY ), static_cast<UINT>( DstBox.MinZ ), @@ -904,7 +904,7 @@ namespace Diligent if(pBufferD3D12->GetDesc().Usage == USAGE_DYNAMIC) VERIFY(pBufferD3D12->GetState() == D3D12_RESOURCE_STATE_GENERIC_READ, "Dynamic buffer is expected to always be in D3D12_RESOURCE_STATE_GENERIC_READ state"); else if(pBufferD3D12->GetState() != D3D12_RESOURCE_STATE_GENERIC_READ) - RequestCmdContext()->TransitionResource(pBufferD3D12, D3D12_RESOURCE_STATE_GENERIC_READ, true); + GetCmdContext().TransitionResource(pBufferD3D12, D3D12_RESOURCE_STATE_GENERIC_READ, true); size_t DataStartByteOffset = 0; auto* pd3d12Buffer = pBufferD3D12->GetD3D12Buffer(DataStartByteOffset, this); CopyTextureRegion(pd3d12Buffer, static_cast<Uint32>(DataStartByteOffset) + SrcOffset, SrcStride, SrcDepthStride, pBufferD3D12->GetDesc().uiSizeInBytes, TextureD3D12, DstSubResIndex, DstBox); @@ -1038,8 +1038,8 @@ namespace Diligent void DeviceContextD3D12Impl::GenerateMips(TextureViewD3D12Impl* pTexView) { - auto *pCtx = RequestCmdContext(); - m_MipsGenerator.GenerateMips(m_pDevice.RawPtr<RenderDeviceD3D12Impl>(), pTexView, *pCtx); + auto& Ctx = GetCmdContext(); + m_MipsGenerator.GenerateMips(m_pDevice.RawPtr<RenderDeviceD3D12Impl>(), pTexView, Ctx); ++m_NumCommandsInCurCtx; } @@ -1047,9 +1047,8 @@ namespace Diligent { auto* pDeviceD3D12Impl = m_pDevice.RawPtr<RenderDeviceD3D12Impl>(); CommandListD3D12Impl* pCmdListD3D12( NEW_RC_OBJ(m_CmdListAllocator, "CommandListD3D12Impl instance", CommandListD3D12Impl) - (pDeviceD3D12Impl, this, m_pCurrCmdCtx) ); + (pDeviceD3D12Impl, this, std::move(m_CurrCmdCtx)) ); pCmdListD3D12->QueryInterface( IID_CommandList, reinterpret_cast<IObject**>(ppCommandList) ); - m_pCurrCmdCtx = nullptr; Flush(true); InvalidateState(); @@ -1069,10 +1068,9 @@ namespace Diligent CommandListD3D12Impl* pCmdListD3D12 = ValidatedCast<CommandListD3D12Impl>(pCommandList); VERIFY_EXPR(m_PendingFences.empty()); - CommandContext* pCmdContext = nullptr; RefCntAutoPtr<DeviceContextD3D12Impl> pDeferredCtx; - pCmdListD3D12->Close(pCmdContext, pDeferredCtx); - m_pDevice.RawPtr<RenderDeviceD3D12Impl>()->CloseAndExecuteCommandContext(m_CommandQueueId, pCmdContext, true, nullptr); + auto CmdContext = pCmdListD3D12->Close(pDeferredCtx); + m_pDevice.RawPtr<RenderDeviceD3D12Impl>()->CloseAndExecuteCommandContext(m_CommandQueueId, std::move(CmdContext), 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; } @@ -1086,14 +1084,14 @@ namespace Diligent void DeviceContextD3D12Impl::TransitionTextureState(ITexture *pTexture, D3D12_RESOURCE_STATES State) { VERIFY_EXPR(pTexture != nullptr); - auto *pCmdCtx = RequestCmdContext(); - pCmdCtx->TransitionResource(ValidatedCast<ITextureD3D12>(pTexture), State); + auto& CmdCtx = GetCmdContext(); + CmdCtx.TransitionResource(ValidatedCast<ITextureD3D12>(pTexture), State); } void DeviceContextD3D12Impl::TransitionBufferState(IBuffer *pBuffer, D3D12_RESOURCE_STATES State) { VERIFY_EXPR(pBuffer != nullptr); - auto *pCmdCtx = RequestCmdContext(); - pCmdCtx->TransitionResource(ValidatedCast<IBufferD3D12>(pBuffer), State); + auto& CmdCtx = GetCmdContext(); + CmdCtx.TransitionResource(ValidatedCast<IBufferD3D12>(pBuffer), State); } } diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 964d101e..85d8ee0a 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -77,7 +77,7 @@ PipelineStateD3D12Impl :: PipelineStateD3D12Impl(IReferenceCounters* pRefCo for (Uint32 s=0; s < m_NumShaders; ++s) { auto* pShaderD3D12 = GetShader<ShaderD3D12Impl>(s); - new (m_pShaderResourceLayouts+s) ShaderResourceLayoutD3D12(*this, GetRawAllocator()); + new (m_pShaderResourceLayouts+s) ShaderResourceLayoutD3D12(*this); m_pShaderResourceLayouts[s].Initialize(pDeviceD3D12->GetD3D12Device(), pShaderD3D12->GetShaderResources(), GetRawAllocator(), nullptr, 0, nullptr, &m_RootSig); } m_RootSig.Finalize(pd3d12Device); diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index 91f87a47..4049d468 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -76,8 +76,7 @@ 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_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_ContextPool(STD_ALLOCATOR_RAW_MEM(PooledCommandContext, GetRawAllocator(), "Allocator for vector<PooledCommandContext>")), m_DynamicMemoryManager(GetRawAllocator(), *this, CreationAttribs.NumDynamicHeapPagesToReserve, CreationAttribs.DynamicHeapPageSize) { m_DeviceCaps.DevType = DeviceType::D3D12; @@ -96,28 +95,34 @@ 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."); + DEV_CHECK_ERR(m_AllocatedCtxCounter == 0, "All contexts must have been released."); m_ContextPool.clear(); DestroyCommandQueues(); } -void RenderDeviceD3D12Impl::DisposeCommandContext(CommandContext* pCtx) +void RenderDeviceD3D12Impl::DisposeCommandContext(PooledCommandContext&& Ctx) { CComPtr<ID3D12CommandAllocator> pAllocator; - pCtx->Close(pAllocator); + Ctx->Close(pAllocator); // 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)); - { - std::lock_guard<std::mutex> LockGuard(m_AvailableContextsMutex); - m_AvailableContexts.push_back(pCtx); - } + FreeCommandContext(std::move(Ctx)); +} + +void RenderDeviceD3D12Impl::FreeCommandContext(PooledCommandContext&& Ctx) +{ + std::lock_guard<std::mutex> LockGuard(m_ContextPoolMutex); + m_ContextPool.emplace_back(std::move(Ctx)); +#ifdef DEVELOPMENT + Atomics::AtomicDecrement(m_AllocatedCtxCounter); +#endif } -void RenderDeviceD3D12Impl::CloseAndExecuteTransientCommandContext(Uint32 CommandQueueIndex, CommandContext *pCtx) +void RenderDeviceD3D12Impl::CloseAndExecuteTransientCommandContext(Uint32 CommandQueueIndex, PooledCommandContext&& Ctx) { CComPtr<ID3D12CommandAllocator> pAllocator; - ID3D12GraphicsCommandList* pCmdList = pCtx->Close(pAllocator); + ID3D12GraphicsCommandList* pCmdList = Ctx->Close(pAllocator); Uint64 FenceValue = 0; // Execute command list directly through the queue to avoid interference with command list numbers in the queue LockCommandQueue(CommandQueueIndex, @@ -126,19 +131,14 @@ void RenderDeviceD3D12Impl::CloseAndExecuteTransientCommandContext(Uint32 Comman FenceValue = pCmdQueue->Submit(pCmdList); } ); - m_CmdListManager.ReleaseAllocator(std::move(pAllocator), CommandQueueIndex, FenceValue); - - { - std::lock_guard<std::mutex> LockGuard(m_AvailableContextsMutex); - m_AvailableContexts.push_back(pCtx); - } + FreeCommandContext(std::move(Ctx)); } -Uint64 RenderDeviceD3D12Impl::CloseAndExecuteCommandContext(Uint32 QueueIndex, CommandContext* pCtx, bool DiscardStaleObjects, std::vector<std::pair<Uint64, RefCntAutoPtr<IFence> > >* pSignalFences) +Uint64 RenderDeviceD3D12Impl::CloseAndExecuteCommandContext(Uint32 QueueIndex, PooledCommandContext&& Ctx, bool DiscardStaleObjects, std::vector<std::pair<Uint64, RefCntAutoPtr<IFence> > >* pSignalFences) { CComPtr<ID3D12CommandAllocator> pAllocator; - ID3D12GraphicsCommandList* pCmdList = pCtx->Close(pAllocator); + ID3D12GraphicsCommandList* pCmdList = Ctx->Close(pAllocator); Uint64 FenceValue = 0; { @@ -174,11 +174,7 @@ Uint64 RenderDeviceD3D12Impl::CloseAndExecuteCommandContext(Uint32 QueueIndex, C } m_CmdListManager.ReleaseAllocator(std::move(pAllocator), QueueIndex, FenceValue); - - { - std::lock_guard<std::mutex> LockGuard(m_AvailableContextsMutex); - m_AvailableContexts.push_back(pCtx); - } + FreeCommandContext(std::move(Ctx)); PurgeReleaseQueue(QueueIndex); @@ -208,30 +204,31 @@ void RenderDeviceD3D12Impl::ReleaseStaleResources(bool ForceRelease) } -CommandContext* RenderDeviceD3D12Impl::AllocateCommandContext(const Char* ID) +RenderDeviceD3D12Impl::PooledCommandContext RenderDeviceD3D12Impl::AllocateCommandContext(const Char* ID) { - std::lock_guard<std::mutex> LockGuard(m_AvailableContextsMutex); - - CommandContext* ret = nullptr; - if (m_AvailableContexts.empty()) - { - auto &CmdCtxAllocator = GetRawAllocator(); - auto *pRawMem = ALLOCATE(CmdCtxAllocator, "CommandContext instance", sizeof(CommandContext)); - ret = new (pRawMem) CommandContext(m_CmdListManager); - m_ContextPool.emplace_back(ret, STDDeleterRawMem<CommandContext>(CmdCtxAllocator) ); - } - else - { - ret = m_AvailableContexts.front(); - m_AvailableContexts.pop_front(); - ret->Reset(m_CmdListManager); - } - VERIFY_EXPR(ret != nullptr); - ret->SetID(ID); - //if ( ID != nullptr && *ID != 0 ) - // EngineProfiling::BeginBlock(ID, NewContext); - - return ret; + { + std::lock_guard<std::mutex> LockGuard(m_ContextPoolMutex); + if (!m_ContextPool.empty()) + { + PooledCommandContext Ctx = std::move(m_ContextPool.back()); + m_ContextPool.pop_back(); + Ctx->Reset(m_CmdListManager); + Ctx->SetID(ID); +#ifdef DEVELOPMENT + Atomics::AtomicIncrement(m_AllocatedCtxCounter); +#endif + return Ctx; + } + } + + auto& CmdCtxAllocator = GetRawAllocator(); + auto* pRawMem = ALLOCATE(CmdCtxAllocator, "CommandContext instance", sizeof(CommandContext)); + auto pCtx = new (pRawMem) CommandContext(m_CmdListManager); + pCtx->SetID(ID); +#ifdef DEVELOPMENT + Atomics::AtomicIncrement(m_AllocatedCtxCounter); +#endif + return PooledCommandContext(pCtx, CmdCtxAllocator); } bool CreateTestResource(ID3D12Device* pDevice, const D3D12_RESOURCE_DESC& ResDesc) diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp index 1a5e03dc..af353150 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp @@ -38,7 +38,7 @@ ShaderD3D12Impl::ShaderD3D12Impl(IReferenceCounters* pRefCounters, const ShaderCreationAttribs& ShaderCreationAttribs) : TShaderBase(pRefCounters, pRenderDeviceD3D12, ShaderCreationAttribs.Desc), ShaderD3DBase(ShaderCreationAttribs), - m_StaticResLayout(*this, GetRawAllocator()), + m_StaticResLayout(*this), m_StaticResCache(ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources), m_StaticVarsMgr(*this) { diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index 4c3e125f..73cb334d 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -38,10 +38,8 @@ namespace Diligent { -ShaderResourceLayoutD3D12::ShaderResourceLayoutD3D12(IObject& Owner, - IMemoryAllocator& ResourceLayoutDataAllocator) : - m_Owner(Owner), - m_ResourceBuffer(nullptr, STDDeleterRawMem<void>(ResourceLayoutDataAllocator)) +ShaderResourceLayoutD3D12::ShaderResourceLayoutD3D12(IObject& Owner) : + m_Owner(Owner) { } @@ -85,8 +83,6 @@ void ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& const std::array<Uint32, SHADER_VARIABLE_TYPE_NUM_TYPES>& CbvSrvUavCount, const std::array<Uint32, SHADER_VARIABLE_TYPE_NUM_TYPES>& SamplerCount) { - VERIFY( &m_ResourceBuffer.get_deleter().m_Allocator == &Allocator, "Inconsistent memory allocators" ); - m_CbvSrvUavOffsets[0] = 0; for(SHADER_VARIABLE_TYPE VarType = SHADER_VARIABLE_TYPE_STATIC; VarType < SHADER_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast<SHADER_VARIABLE_TYPE>(VarType+1)) { @@ -108,7 +104,7 @@ void ShaderResourceLayoutD3D12::AllocateMemory(IMemoryAllocator& return; auto *pRawMem = ALLOCATE(Allocator, "Raw memory buffer for shader resource layout resources", MemSize); - m_ResourceBuffer.reset(pRawMem); + m_ResourceBuffer = std::unique_ptr<void, STDDeleterRawMem<void> >(pRawMem, Allocator); } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp index 2a06fd03..d77793ed 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp @@ -35,7 +35,7 @@ namespace Diligent ShaderResourcesD3D12::ShaderResourcesD3D12(ID3DBlob *pShaderBytecode, const ShaderDesc &ShdrDesc) : - ShaderResources(GetRawAllocator(), ShdrDesc.ShaderType) + ShaderResources(ShdrDesc.ShaderType) { Uint32 CurrCB = 0, CurrTexSRV = 0, CurrTexUAV = 0, CurrBufSRV = 0, CurrBufUAV = 0, CurrSampler = 0; LoadD3DShaderResources<D3D12_SHADER_DESC, D3D12_SHADER_INPUT_BIND_DESC, ID3D12ShaderReflection>( diff --git a/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp index 30a56b67..423d73ce 100644 --- a/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/SwapChainD3D12Impl.cpp @@ -117,12 +117,12 @@ void SwapChainD3D12Impl::Present(Uint32 SyncInterval) return; } - auto *pImmediateCtx = pDeviceContext.RawPtr(); - auto *pImmediateCtxD3D12 = ValidatedCast<DeviceContextD3D12Impl>( pImmediateCtx ); + auto* pImmediateCtx = pDeviceContext.RawPtr(); + auto* pImmediateCtxD3D12 = ValidatedCast<DeviceContextD3D12Impl>( pImmediateCtx ); - auto *pCmdCtx = pImmediateCtxD3D12->RequestCmdContext(); - auto *pBackBuffer = ValidatedCast<TextureD3D12Impl>( GetCurrentBackBufferRTV()->GetTexture() ); - pCmdCtx->TransitionResource( pBackBuffer, D3D12_RESOURCE_STATE_PRESENT); + auto& CmdCtx = pImmediateCtxD3D12->GetCmdContext(); + auto* pBackBuffer = ValidatedCast<TextureD3D12Impl>( GetCurrentBackBufferRTV()->GetTexture() ); + CmdCtx.TransitionResource( pBackBuffer, D3D12_RESOURCE_STATE_PRESENT); pImmediateCtxD3D12->Flush(); diff --git a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp index e76da5dd..8a0ddb56 100644 --- a/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/TextureD3D12Impl.cpp @@ -187,7 +187,7 @@ TextureD3D12Impl :: TextureD3D12Impl(IReferenceCounters* pRefCounters, if(FAILED(hr)) LOG_ERROR_AND_THROW("Failed to create committed resource in an upload heap"); - auto *pInitContext = pRenderDeviceD3D12->AllocateCommandContext(); + auto InitContext = pRenderDeviceD3D12->AllocateCommandContext(); // copy data to the intermediate upload heap and then schedule a copy from the upload heap to the default texture VERIFY_EXPR(m_UsageState == D3D12_RESOURCE_STATE_COPY_DEST); std::vector<D3D12_SUBRESOURCE_DATA, STDAllocatorRawMem<D3D12_SUBRESOURCE_DATA> > D3D12SubResData(InitData.NumSubresources, D3D12_SUBRESOURCE_DATA(), STD_ALLOCATOR_RAW_MEM(D3D12_SUBRESOURCE_DATA, GetRawAllocator(), "Allocator for vector<D3D12_SUBRESOURCE_DATA>") ); @@ -197,7 +197,7 @@ TextureD3D12Impl :: TextureD3D12Impl(IReferenceCounters* pRefCounters, D3D12SubResData[subres].RowPitch = InitData.pSubResources[subres].Stride; D3D12SubResData[subres].SlicePitch = InitData.pSubResources[subres].DepthStride; } - auto UploadedSize = UpdateSubresources(pInitContext->GetCommandList(), m_pd3d12Resource, UploadBuffer, 0, 0, InitData.NumSubresources, D3D12SubResData.data()); + auto UploadedSize = UpdateSubresources(InitContext->GetCommandList(), m_pd3d12Resource, UploadBuffer, 0, 0, InitData.NumSubresources, D3D12SubResData.data()); VERIFY(UploadedSize == uploadBufferSize, "Incorrect uploaded data size (", UploadedSize, "). ", uploadBufferSize, " is expected"); // Command list fence should only be signaled when submitting cmd list @@ -219,7 +219,7 @@ TextureD3D12Impl :: TextureD3D12Impl(IReferenceCounters* pRefCounters, // | was added to the delete queue | | // | with value N | | Uint32 QueueIndex = 0; - pRenderDeviceD3D12->CloseAndExecuteTransientCommandContext(QueueIndex, pInitContext); + pRenderDeviceD3D12->CloseAndExecuteTransientCommandContext(QueueIndex, std::move(InitContext)); // We MUST NOT call TransitionResource() from here, because // it will call AddRef() and potentially Release(), while |
