From 61adaa941deca50f807c00d16fe499be6727115e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 28 Mar 2019 14:09:08 +0100 Subject: [PATCH] [d3d11] Implement fast path for binding full constant buffers Saves a few CPU cycles in the most common case where we don't have to perform any sort of range check. --- src/d3d11/d3d11_context.cpp | 62 +++++++++++++++++++++++++------------ src/d3d11/d3d11_context.h | 7 +++++ 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 02d557281..07f4571b2 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1657,8 +1657,7 @@ namespace dxvk { DxbcProgramType::VertexShader, m_state.vs.constantBuffers, StartSlot, NumBuffers, - ppConstantBuffers, - nullptr, nullptr); + ppConstantBuffers); } @@ -1670,7 +1669,7 @@ namespace dxvk { const UINT* pNumConstants) { D3D10DeviceLock lock = LockContext(); - SetConstantBuffers( + SetConstantBuffers1( DxbcProgramType::VertexShader, m_state.vs.constantBuffers, StartSlot, NumBuffers, @@ -1820,8 +1819,7 @@ namespace dxvk { DxbcProgramType::HullShader, m_state.hs.constantBuffers, StartSlot, NumBuffers, - ppConstantBuffers, - nullptr, nullptr); + ppConstantBuffers); } @@ -1833,7 +1831,7 @@ namespace dxvk { const UINT* pNumConstants) { D3D10DeviceLock lock = LockContext(); - SetConstantBuffers( + SetConstantBuffers1( DxbcProgramType::HullShader, m_state.hs.constantBuffers, StartSlot, NumBuffers, @@ -1969,8 +1967,7 @@ namespace dxvk { DxbcProgramType::DomainShader, m_state.ds.constantBuffers, StartSlot, NumBuffers, - ppConstantBuffers, - nullptr, nullptr); + ppConstantBuffers); } @@ -1982,7 +1979,7 @@ namespace dxvk { const UINT* pNumConstants) { D3D10DeviceLock lock = LockContext(); - SetConstantBuffers( + SetConstantBuffers1( DxbcProgramType::DomainShader, m_state.ds.constantBuffers, StartSlot, NumBuffers, @@ -2104,8 +2101,7 @@ namespace dxvk { DxbcProgramType::GeometryShader, m_state.gs.constantBuffers, StartSlot, NumBuffers, - ppConstantBuffers, - nullptr, nullptr); + ppConstantBuffers); } @@ -2117,7 +2113,7 @@ namespace dxvk { const UINT* pNumConstants) { D3D10DeviceLock lock = LockContext(); - SetConstantBuffers( + SetConstantBuffers1( DxbcProgramType::GeometryShader, m_state.gs.constantBuffers, StartSlot, NumBuffers, @@ -2253,8 +2249,7 @@ namespace dxvk { DxbcProgramType::PixelShader, m_state.ps.constantBuffers, StartSlot, NumBuffers, - ppConstantBuffers, - nullptr, nullptr); + ppConstantBuffers); } @@ -2266,7 +2261,7 @@ namespace dxvk { const UINT* pNumConstants) { D3D10DeviceLock lock = LockContext(); - SetConstantBuffers( + SetConstantBuffers1( DxbcProgramType::PixelShader, m_state.ps.constantBuffers, StartSlot, NumBuffers, @@ -2402,8 +2397,7 @@ namespace dxvk { DxbcProgramType::ComputeShader, m_state.cs.constantBuffers, StartSlot, NumBuffers, - ppConstantBuffers, - nullptr, nullptr); + ppConstantBuffers); } @@ -2415,7 +2409,7 @@ namespace dxvk { const UINT* pNumConstants) { D3D10DeviceLock lock = LockContext(); - SetConstantBuffers( + SetConstantBuffers1( DxbcProgramType::ComputeShader, m_state.cs.constantBuffers, StartSlot, NumBuffers, @@ -3357,6 +3351,36 @@ namespace dxvk { void D3D11DeviceContext::SetConstantBuffers( + DxbcProgramType ShaderStage, + D3D11ConstantBufferBindings& Bindings, + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers) { + const uint32_t slotId = computeResourceSlotId( + ShaderStage, DxbcBindingType::ConstantBuffer, + StartSlot); + + for (uint32_t i = 0; i < NumBuffers; i++) { + auto newBuffer = static_cast(ppConstantBuffers[i]); + + UINT constantBound = newBuffer + ? newBuffer->Desc()->ByteWidth / 16 + : 0; + + if (Bindings[StartSlot + i].buffer != newBuffer + || Bindings[StartSlot + i].constantBound != constantBound) { + Bindings[StartSlot + i].buffer = newBuffer; + Bindings[StartSlot + i].constantOffset = 0; + Bindings[StartSlot + i].constantCount = constantBound; + Bindings[StartSlot + i].constantBound = constantBound; + + BindConstantBuffer(slotId + i, &Bindings[StartSlot + i]); + } + } + } + + + void D3D11DeviceContext::SetConstantBuffers1( DxbcProgramType ShaderStage, D3D11ConstantBufferBindings& Bindings, UINT StartSlot, @@ -3378,7 +3402,7 @@ namespace dxvk { if (likely(newBuffer != nullptr)) { constantBound = newBuffer->Desc()->ByteWidth / 16; - if (pFirstConstant && pNumConstants) { + if (likely(pFirstConstant && pNumConstants)) { constantOffset = pFirstConstant[i]; constantCount = pNumConstants [i]; diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index fd49ae8e0..0a6e2a111 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -735,6 +735,13 @@ namespace dxvk { ID3D11Buffer* pBuffer); void SetConstantBuffers( + DxbcProgramType ShaderStage, + D3D11ConstantBufferBindings& Bindings, + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers); + + void SetConstantBuffers1( DxbcProgramType ShaderStage, D3D11ConstantBufferBindings& Bindings, UINT StartSlot,