From cf5adb8b12b16c1e944743bb9db316b187bf5bbf Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 15 Jan 2023 01:02:03 +0100 Subject: [PATCH] [d3d11] Improve flushing around deferred context submissions --- src/d3d11/d3d11_cmdlist.cpp | 6 +++--- src/d3d11/d3d11_cmdlist.h | 12 ++++++++++-- src/d3d11/d3d11_context_imm.cpp | 27 +++++++++++++++++++-------- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/d3d11/d3d11_cmdlist.cpp b/src/d3d11/d3d11_cmdlist.cpp index aeb1cd5a..c3475781 100644 --- a/src/d3d11/d3d11_cmdlist.cpp +++ b/src/d3d11/d3d11_cmdlist.cpp @@ -67,20 +67,20 @@ namespace dxvk { } - uint64_t D3D11CommandList::EmitToCsThread(DxvkCsThread* CsThread) { + void D3D11CommandList::EmitToCsThread( + const D3D11ChunkDispatchProc& DispatchProc) { uint64_t seq = 0; for (const auto& query : m_queries) query->DoDeferredEnd(); for (const auto& chunk : m_chunks) - seq = CsThread->dispatchChunk(DxvkCsChunkRef(chunk)); + seq = DispatchProc(DxvkCsChunkRef(chunk)); for (const auto& resource : m_resources) TrackResourceSequenceNumber(resource, seq); MarkSubmitted(); - return seq; } diff --git a/src/d3d11/d3d11_cmdlist.h b/src/d3d11/d3d11_cmdlist.h index 8be313ad..95330b15 100644 --- a/src/d3d11/d3d11_cmdlist.h +++ b/src/d3d11/d3d11_cmdlist.h @@ -1,9 +1,13 @@ #pragma once +#include + #include "d3d11_context.h" namespace dxvk { + using D3D11ChunkDispatchProc = std::function; + class D3D11CommandList : public D3D11DeviceChild { public: @@ -29,14 +33,18 @@ namespace dxvk { void EmitToCommandList( ID3D11CommandList* pCommandList); - uint64_t EmitToCsThread( - DxvkCsThread* CsThread); + void EmitToCsThread( + const D3D11ChunkDispatchProc& DispatchProc); void TrackResourceUsage( ID3D11Resource* pResource, D3D11_RESOURCE_DIMENSION ResourceType, UINT Subresource); + bool HasTrackedResources() const { + return !m_resources.empty(); + } + private: UINT const m_contextFlags; diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 7386e848..e6cfd1d7 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -237,18 +237,29 @@ namespace dxvk { // number of pending draw calls is high enough. ConsiderFlush(GpuFlushType::ImplicitWeakHint); - // Dispatch command list to the CS thread and - // restore the immediate context's state - uint64_t csSeqNum = commandList->EmitToCsThread(&m_csThread); - m_csSeqNum = std::max(m_csSeqNum, csSeqNum); - + // Dispatch command list to the CS thread + commandList->EmitToCsThread([this] (DxvkCsChunkRef&& chunk) { + EmitCsChunk(std::move(chunk)); + + // Return the sequence number from before the flush since + // that is actually going to be needed for resource tracking + uint64_t csSeqNum = m_csSeqNum; + + // Consider a flush after every chunk in case the app + // submits a very large command list or the GPU is idle + ConsiderFlush(GpuFlushType::ImplicitWeakHint); + return csSeqNum; + }); + + // If any resource tracking took place, flush with a strong hint + if (commandList->HasTrackedResources()) + ConsiderFlush(GpuFlushType::ImplicitStrongHint); + + // Restore the immediate context's state if (RestoreContextState) RestoreCommandListState(); else ResetContextState(); - - // Flush again if the command list was sufficiently long - ConsiderFlush(GpuFlushType::ImplicitWeakHint); }