From 17a1b0ad44f4019aec1057f0325c839f815f4439 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 18 Feb 2022 14:14:18 +0100 Subject: [PATCH] [d3d11] Consider empty CS chunks when tracking resources Avoids deadlocks if we track multiple resources and flush in between. --- src/d3d11/d3d11_context_imm.cpp | 14 ++++++++++++-- src/d3d11/d3d11_context_imm.h | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index f43ecfb3..0ff64e25 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -734,7 +734,8 @@ namespace dxvk { void D3D11ImmediateContext::TrackTextureSequenceNumber( D3D11CommonTexture* pResource, UINT Subresource) { - pResource->TrackSequenceNumber(Subresource, m_csSeqNum + 1); + uint64_t sequenceNumber = GetCurrentSequenceNumber(); + pResource->TrackSequenceNumber(Subresource, sequenceNumber); FlushImplicit(TRUE); } @@ -742,12 +743,21 @@ namespace dxvk { void D3D11ImmediateContext::TrackBufferSequenceNumber( D3D11Buffer* pResource) { - pResource->TrackSequenceNumber(m_csSeqNum + 1); + uint64_t sequenceNumber = GetCurrentSequenceNumber(); + pResource->TrackSequenceNumber(sequenceNumber); FlushImplicit(TRUE); } + uint64_t D3D11ImmediateContext::GetCurrentSequenceNumber() { + // We do not flush empty chunks, so if we are tracking a resource + // immediately after a flush, we need to use the sequence number + // of the previously submitted chunk to prevent deadlocks. + return m_csChunk->empty() ? m_csSeqNum : m_csSeqNum + 1; + } + + void D3D11ImmediateContext::FlushImplicit(BOOL StrongHint) { // Flush only if the GPU is about to go idle, in // order to keep the number of submissions low. diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index e96396a3..9a5ba21f 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -174,6 +174,8 @@ namespace dxvk { void TrackBufferSequenceNumber( D3D11Buffer* pResource); + uint64_t GetCurrentSequenceNumber(); + void FlushImplicit(BOOL StrongHint); void SignalEvent(HANDLE hEvent);