From c7a9763f6d5abcffe3125d3f2a4850d1dec4cbe6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 13 Jan 2018 23:09:03 +0100 Subject: [PATCH] [d3d11] Re-implemented draw call-based context flush After doing more testing, it became apparent that this optimization is beneficial most of the time and may also improve stability by limiting the number of commands recorded into a single command buffer. --- src/d3d11/d3d11_context.cpp | 15 +++++++++++++++ src/d3d11/d3d11_context.h | 9 +++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 4fd6d8fa..fff3efb5 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -166,6 +166,7 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::Flush() { if (m_type == D3D11_DEVICE_CONTEXT_IMMEDIATE) { m_parent->FlushInitContext(); + m_drawCount = 0; m_device->submitCommandList( m_context->endRecording(), @@ -737,6 +738,7 @@ namespace dxvk { m_context->draw( VertexCount, 1, StartVertexLocation, 0); + m_drawCount += 1; } @@ -748,6 +750,7 @@ namespace dxvk { IndexCount, 1, StartIndexLocation, BaseVertexLocation, 0); + m_drawCount += 1; } @@ -761,6 +764,7 @@ namespace dxvk { InstanceCount, StartVertexLocation, StartInstanceLocation); + m_drawCount += 1; } @@ -776,6 +780,7 @@ namespace dxvk { StartIndexLocation, BaseVertexLocation, StartInstanceLocation); + m_drawCount += 1; } @@ -786,6 +791,7 @@ namespace dxvk { DxvkBufferSlice bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs); m_context->drawIndexedIndirect(bufferSlice, 1, 0); + m_drawCount += 1; } @@ -796,6 +802,7 @@ namespace dxvk { DxvkBufferSlice bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs); m_context->drawIndirect(bufferSlice, 1, 0); + m_drawCount += 1; } @@ -807,6 +814,7 @@ namespace dxvk { ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); + m_drawCount += 1; } @@ -817,6 +825,7 @@ namespace dxvk { DxvkBufferSlice bufferSlice = buffer->GetBufferSlice(AlignedByteOffsetForArgs); m_context->dispatchIndirect(bufferSlice); + m_drawCount += 1; } @@ -1541,6 +1550,12 @@ namespace dxvk { UINT NumViews, ID3D11RenderTargetView* const* ppRenderTargetViews, ID3D11DepthStencilView* pDepthStencilView) { + // Optimization: If the number of draw and dispatch calls issued + // prior to the previous context flush is above a certain threshold, + // submit the current command buffer in order to keep the GPU busy. + if (m_drawCount >= 500) + this->Flush(); + for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) { D3D11RenderTargetView* view = nullptr; diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index a80715e9..f55eb874 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -554,15 +554,16 @@ namespace dxvk { const D3D11_DEVICE_CONTEXT_TYPE m_type = D3D11_DEVICE_CONTEXT_IMMEDIATE; const UINT m_flags = 0; - Rc m_device; - Rc m_context; - Rc m_defaultSampler; + Rc m_device; + Rc m_context; + Rc m_defaultSampler; Com m_defaultBlendState; Com m_defaultDepthStencilState; Com m_defaultRasterizerState; - D3D11ContextState m_state; + D3D11ContextState m_state; + uint64_t m_drawCount = 0; void BindConstantBuffers( DxbcProgramType ShaderStage,