diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2021-02-07 21:59:11 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2021-02-07 21:59:11 +0000 |
| commit | cfc713b96b3aef8726ffe1f0d0af0e572d5ce84b (patch) | |
| tree | e982610d8a0d9ca230c86eadc0e87ea41039e0b9 /Graphics/GraphicsEngineD3D12 | |
| parent | Reworked ExecuteCommandList(s) to take multiple command lists instead of one (diff) | |
| download | DiligentCore-cfc713b96b3aef8726ffe1f0d0af0e572d5ce84b.tar.gz DiligentCore-cfc713b96b3aef8726ffe1f0d0af0e572d5ce84b.zip | |
DeviceContextD3D12Impl: reworked flush to also execute deferred command lists to avoid redundant submit
Diffstat (limited to 'Graphics/GraphicsEngineD3D12')
| -rw-r--r-- | Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp | 4 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp | 79 |
2 files changed, 44 insertions, 39 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp index 15c85492..39ac2431 100644 --- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.hpp @@ -346,7 +346,9 @@ private: void CommitScissorRects(class GraphicsContext& GraphCtx, bool ScissorEnable); void TransitionSubpassAttachments(Uint32 NextSubpass); void CommitSubpassRenderTargets(); - void Flush(bool RequestNewCmdCtx); + void Flush(bool RequestNewCmdCtx, + Uint32 NumCommandLists = 0, + ICommandList* const* ppCommandLists = nullptr); __forceinline void RequestCommandContext(RenderDeviceD3D12Impl* pDeviceD3D12Impl); diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index b7415753..1cd2f766 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -773,26 +773,52 @@ void DeviceContextD3D12Impl::RequestCommandContext(RenderDeviceD3D12Impl* pDevic m_CurrCmdCtx->SetDynamicGPUDescriptorAllocators(m_DynamicGPUDescriptorAllocator); } -void DeviceContextD3D12Impl::Flush(bool RequestNewCmdCtx) +void DeviceContextD3D12Impl::Flush(bool RequestNewCmdCtx, + Uint32 NumCommandLists, + ICommandList* const* ppCommandLists) { + VERIFY(!m_bIsDeferred || NumCommandLists == 0 && ppCommandLists == nullptr, "Only immediate context can execute command lists"); + + if (m_ActiveQueriesCounter > 0) + { + LOG_ERROR_MESSAGE("Flushing device context that has ", m_ActiveQueriesCounter, + " active queries. Direct3D12 requires that queries are begun and ended in the same command list"); + } + + // TODO: use small_vector + std::vector<RenderDeviceD3D12Impl::PooledCommandContext> Contexts; + Contexts.reserve(NumCommandLists + 1); + + // First, execute current context if (m_CurrCmdCtx) { VERIFY(!m_bIsDeferred, "Deferred contexts cannot execute command lists directly"); if (m_State.NumCommands != 0) - { - m_CurrCmdCtx->FlushResourceBarriers(); - m_pDevice->CloseAndExecuteCommandContexts(m_CommandQueueId, 1, &m_CurrCmdCtx, true, &m_PendingFences); - VERIFY(!m_CurrCmdCtx, "Context must be disposed by CloseAndExecuteCommandContexts"); - m_PendingFences.clear(); - } + Contexts.emplace_back(std::move(m_CurrCmdCtx)); else m_pDevice->DisposeCommandContext(std::move(m_CurrCmdCtx)); } - if (m_ActiveQueriesCounter > 0) + // Next, add extra command lists from deferred contexts + for (Uint32 i = 0; i < NumCommandLists; ++i) { - LOG_ERROR_MESSAGE("Flushing device context that has ", m_ActiveQueriesCounter, - " active queries. Direct3D12 requires that queries are begun and ended in the same command list"); + auto* const pCmdListD3D12 = ValidatedCast<CommandListD3D12Impl>(ppCommandLists[i]); + + RefCntAutoPtr<DeviceContextD3D12Impl> pDeferredCtx; + Contexts.emplace_back(pCmdListD3D12->Close(pDeferredCtx)); + // Set the bit in the deferred context cmd queue mask corresponding to the cmd queue of this context + pDeferredCtx->m_SubmittedBuffersCmdQueueMask.fetch_or(Uint64{1} << m_CommandQueueId); + } + + if (!Contexts.empty()) + { + m_pDevice->CloseAndExecuteCommandContexts(m_CommandQueueId, static_cast<Uint32>(Contexts.size()), Contexts.data(), true, &m_PendingFences); + m_PendingFences.clear(); + +#ifdef DILIGENT_DEBUG + for (Uint32 i = 0; i < NumCommandLists; ++i) + VERIFY(!Contexts[i], "All contexts must be disposed by CloseAndExecuteCommandContexts"); +#endif } // If there is no command list to submit, but there are pending fences, we need to signal them now @@ -2036,7 +2062,7 @@ void DeviceContextD3D12Impl::GenerateMips(ITextureView* pTexView) void DeviceContextD3D12Impl::FinishCommandList(ICommandList** ppCommandList) { - VERIFY(m_pActiveRenderPass == nullptr, "Finishing command list inside an active render pass."); + DEV_CHECK_ERR(m_pActiveRenderPass == nullptr, "Finishing command list inside an active render pass."); CommandListD3D12Impl* pCmdListD3D12(NEW_RC_OBJ(m_CmdListAllocator, "CommandListD3D12Impl instance", CommandListD3D12Impl)(m_pDevice, this, std::move(m_CurrCmdCtx))); pCmdListD3D12->QueryInterface(IID_CommandList, reinterpret_cast<IObject**>(ppCommandList)); @@ -2058,43 +2084,20 @@ void DeviceContextD3D12Impl::ExecuteCommandLists(Uint32 NumCommand return; DEV_CHECK_ERR(ppCommandLists != nullptr, "ppCommandLists must not be null when NumCommandLists is not zero"); - // First execute commands in this context - Flush(true); + Flush(true, NumCommandLists, ppCommandLists); InvalidateState(); - - VERIFY_EXPR(m_PendingFences.empty()); - - // TODO: use small_vector - std::vector<RenderDeviceD3D12Impl::PooledCommandContext> Contexts; - Contexts.reserve(NumCommandLists); - for (Uint32 i = 0; i < NumCommandLists; ++i) - { - auto* const pCmdListD3D12 = ValidatedCast<CommandListD3D12Impl>(ppCommandLists[i]); - - RefCntAutoPtr<DeviceContextD3D12Impl> pDeferredCtx; - Contexts.emplace_back(pCmdListD3D12->Close(pDeferredCtx)); - // Set the bit in the deferred context cmd queue mask corresponding to cmd queue of this context - pDeferredCtx->m_SubmittedBuffersCmdQueueMask |= Uint64{1} << m_CommandQueueId; - } - - m_pDevice->CloseAndExecuteCommandContexts(m_CommandQueueId, NumCommandLists, Contexts.data(), true, nullptr); - -#ifdef DILIGENT_DEBUG - for (Uint32 i = 0; i < NumCommandLists; ++i) - VERIFY(!Contexts[i], "All contexts must be disposed by CloseAndExecuteCommandContexts"); -#endif } void DeviceContextD3D12Impl::SignalFence(IFence* pFence, Uint64 Value) { - VERIFY(!m_bIsDeferred, "Fence can only be signaled from immediate context"); + DEV_CHECK_ERR(!m_bIsDeferred, "Fence can only be signaled from immediate context"); m_PendingFences.emplace_back(Value, pFence); } void DeviceContextD3D12Impl::WaitForFence(IFence* pFence, Uint64 Value, bool FlushContext) { - VERIFY(!m_bIsDeferred, "Fence can only be waited from immediate context"); + DEV_CHECK_ERR(!m_bIsDeferred, "Fence can only be waited from immediate context"); if (FlushContext) Flush(); auto* pFenceD3D12 = ValidatedCast<FenceD3D12Impl>(pFence); @@ -2103,7 +2106,7 @@ void DeviceContextD3D12Impl::WaitForFence(IFence* pFence, Uint64 Value, bool Flu void DeviceContextD3D12Impl::WaitForIdle() { - VERIFY(!m_bIsDeferred, "Only immediate contexts can be idled"); + DEV_CHECK_ERR(!m_bIsDeferred, "Only immediate contexts can be idled"); Flush(); m_pDevice->IdleCommandQueue(m_CommandQueueId, true); } |
