diff --git a/src/d3d11/d3d11_cmdlist.cpp b/src/d3d11/d3d11_cmdlist.cpp index c4e12eae4..883f4986e 100644 --- a/src/d3d11/d3d11_cmdlist.cpp +++ b/src/d3d11/d3d11_cmdlist.cpp @@ -41,8 +41,11 @@ namespace dxvk { } - void D3D11CommandList::AddChunk(Rc&& Chunk) { + void D3D11CommandList::AddChunk( + Rc&& Chunk, + UINT DrawCount) { m_chunks.push_back(std::move(Chunk)); + m_drawCount += DrawCount; } @@ -51,6 +54,8 @@ namespace dxvk { for (auto chunk : m_chunks) cmdList->m_chunks.push_back(chunk); + + cmdList->m_drawCount += m_drawCount; } diff --git a/src/d3d11/d3d11_cmdlist.h b/src/d3d11/d3d11_cmdlist.h index 199588556..dc6d45e82 100644 --- a/src/d3d11/d3d11_cmdlist.h +++ b/src/d3d11/d3d11_cmdlist.h @@ -23,7 +23,9 @@ namespace dxvk { UINT STDMETHODCALLTYPE GetContextFlags() final; - void AddChunk(Rc&& Chunk); + void AddChunk( + Rc&& Chunk, + UINT DrawCount); void EmitToCommandList( ID3D11CommandList* pCommandList); @@ -31,10 +33,15 @@ namespace dxvk { void EmitToCsThread( DxvkCsThread* CsThread); + UINT GetDrawCount() const { + return m_drawCount; + } + private: D3D11Device* const m_device; UINT const m_contextFlags; + UINT m_drawCount = 0; std::vector> m_chunks; diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 6b7bef9e8..8ebc65c82 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -648,7 +648,7 @@ namespace dxvk { Com m_defaultRasterizerState; D3D11ContextState m_state; - uint64_t m_drawCount = 0; + UINT m_drawCount = 0; void ApplyInputLayout(); diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index 541aa7434..791ad1972 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -256,7 +256,8 @@ namespace dxvk { void D3D11DeferredContext::EmitCsChunk(Rc&& chunk) { - m_commandList->AddChunk(std::move(chunk)); + m_commandList->AddChunk(std::move(chunk), m_drawCount); + m_drawCount = 0; } } \ No newline at end of file diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index f899520f3..4daf8867a 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -72,16 +72,30 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11ImmediateContext::ExecuteCommandList( ID3D11CommandList* pCommandList, BOOL RestoreContextState) { + auto commandList = static_cast(pCommandList); + + // Flush any outstanding commands so that + // we don't mess up the execution order FlushCsChunk(); - static_cast(pCommandList)->EmitToCsThread(&m_csThread); + // As an optimization, flush everything if the + // number of pending draw calls is high enough. + if (m_drawCount >= MaxPendingDraws) + Flush(); + + // Dispatch command list to the CS thread and + // restore the immediate context's state + commandList->EmitToCsThread(&m_csThread); if (RestoreContextState) RestoreState(); else ClearState(); + // Mark CS thread as busy so that subsequent + // flush operations get executed correctly. m_csIsBusy = true; + m_drawCount += commandList->GetDrawCount(); } @@ -190,7 +204,7 @@ namespace dxvk { // prior to the previous context flush is above a certain threshold, // submit the current command buffer in order to keep the GPU busy. // This also helps keep the command buffers at a reasonable size. - if (m_drawCount >= 500) + if (m_drawCount >= MaxPendingDraws) Flush(); D3D11DeviceContext::OMSetRenderTargets( diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index 18a5b4e77..97ec2c83d 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -8,7 +8,7 @@ namespace dxvk { class D3D11CommonTexture; class D3D11ImmediateContext : public D3D11DeviceContext { - + constexpr static UINT MaxPendingDraws = 500; public: D3D11ImmediateContext(