From 5ef0f31c66270f12e3e9b5c6c488b6fa0196e48d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 10 Mar 2018 11:16:52 +0100 Subject: [PATCH] [dxvk/d3d11] Refactored resource binding Slightly reduces overhead of D3D11 *SetShaderResources methods. --- src/d3d11/d3d11_context.cpp | 175 +++++++++++++++------------------ src/d3d11/d3d11_context.h | 25 ++++- src/dxgi/dxgi_presenter.cpp | 4 +- src/dxvk/dxvk_context.cpp | 24 +---- src/dxvk/dxvk_context.h | 25 ++--- src/dxvk/hud/dxvk_hud_text.cpp | 2 +- 6 files changed, 119 insertions(+), 136 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index e2fc97658..cc994b28e 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1166,7 +1166,7 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) { - this->BindConstantBuffers( + this->SetConstantBuffers( DxbcProgramType::VertexShader, m_state.vs.constantBuffers, StartSlot, NumBuffers, @@ -1178,7 +1178,7 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) { - this->BindShaderResources( + this->SetShaderResources( DxbcProgramType::VertexShader, m_state.vs.shaderResources, StartSlot, NumViews, @@ -1190,7 +1190,7 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { - this->BindSamplers( + this->SetSamplers( DxbcProgramType::VertexShader, m_state.vs.samplers, StartSlot, NumSamplers, @@ -1257,7 +1257,7 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) { - this->BindShaderResources( + this->SetShaderResources( DxbcProgramType::HullShader, m_state.hs.shaderResources, StartSlot, NumViews, @@ -1269,7 +1269,7 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) { - this->BindConstantBuffers( + this->SetConstantBuffers( DxbcProgramType::HullShader, m_state.hs.constantBuffers, StartSlot, NumBuffers, @@ -1281,7 +1281,7 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { - this->BindSamplers( + this->SetSamplers( DxbcProgramType::HullShader, m_state.hs.samplers, StartSlot, NumSamplers, @@ -1348,7 +1348,7 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) { - this->BindShaderResources( + this->SetShaderResources( DxbcProgramType::DomainShader, m_state.ds.shaderResources, StartSlot, NumViews, @@ -1360,7 +1360,7 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) { - this->BindConstantBuffers( + this->SetConstantBuffers( DxbcProgramType::DomainShader, m_state.ds.constantBuffers, StartSlot, NumBuffers, @@ -1372,7 +1372,7 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { - this->BindSamplers( + this->SetSamplers( DxbcProgramType::DomainShader, m_state.ds.samplers, StartSlot, NumSamplers, @@ -1439,7 +1439,7 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) { - this->BindConstantBuffers( + this->SetConstantBuffers( DxbcProgramType::GeometryShader, m_state.gs.constantBuffers, StartSlot, NumBuffers, @@ -1451,7 +1451,7 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) { - this->BindShaderResources( + this->SetShaderResources( DxbcProgramType::GeometryShader, m_state.gs.shaderResources, StartSlot, NumViews, @@ -1463,7 +1463,7 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { - this->BindSamplers( + this->SetSamplers( DxbcProgramType::GeometryShader, m_state.gs.samplers, StartSlot, NumSamplers, @@ -1530,7 +1530,7 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) { - this->BindConstantBuffers( + this->SetConstantBuffers( DxbcProgramType::PixelShader, m_state.ps.constantBuffers, StartSlot, NumBuffers, @@ -1542,7 +1542,7 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) { - this->BindShaderResources( + this->SetShaderResources( DxbcProgramType::PixelShader, m_state.ps.shaderResources, StartSlot, NumViews, @@ -1554,7 +1554,7 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { - this->BindSamplers( + this->SetSamplers( DxbcProgramType::PixelShader, m_state.ps.samplers, StartSlot, NumSamplers, @@ -1621,7 +1621,7 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) { - this->BindConstantBuffers( + this->SetConstantBuffers( DxbcProgramType::ComputeShader, m_state.cs.constantBuffers, StartSlot, NumBuffers, @@ -1633,7 +1633,7 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) { - this->BindShaderResources( + this->SetShaderResources( DxbcProgramType::ComputeShader, m_state.cs.shaderResources, StartSlot, NumViews, @@ -1645,7 +1645,7 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { - this->BindSamplers( + this->SetSamplers( DxbcProgramType::ComputeShader, m_state.cs.samplers, StartSlot, NumSamplers, @@ -1658,7 +1658,7 @@ namespace dxvk { UINT NumUAVs, ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, const UINT* pUAVInitialCounts) { - this->BindUnorderedAccessViews( + this->SetUnorderedAccessViews( DxbcProgramType::ComputeShader, m_state.cs.unorderedAccessViews, StartSlot, NumUAVs, @@ -1762,7 +1762,7 @@ namespace dxvk { // the graphics pipeline even though this code may // suggest that they are limited to the pixel shader. // This behaviour is only required for FL_11_1. - BindUnorderedAccessViews( + SetUnorderedAccessViews( DxbcProgramType::PixelShader, m_state.ps.unorderedAccessViews, UAVStartSlot, NumUAVs, @@ -2098,7 +2098,61 @@ namespace dxvk { } - void D3D11DeviceContext::BindConstantBuffers( + void D3D11DeviceContext::BindConstantBuffer( + UINT Slot, + D3D11Buffer* pBuffer) { + EmitCs([ + cSlotId = Slot, + cBufferSlice = pBuffer != nullptr ? pBuffer->GetBufferSlice() : DxvkBufferSlice() + ] (DxvkContext* ctx) { + ctx->bindResourceBuffer(cSlotId, cBufferSlice); + }); + } + + + void D3D11DeviceContext::BindSampler( + UINT Slot, + D3D11SamplerState* pSampler) { + EmitCs([ + cSlotId = Slot, + cSampler = pSampler != nullptr ? pSampler->GetDXVKSampler() : nullptr + ] (DxvkContext* ctx) { + ctx->bindResourceSampler(cSlotId, cSampler); + }); + } + + + void D3D11DeviceContext::BindShaderResource( + UINT Slot, + D3D11ShaderResourceView* pResource) { + EmitCs([ + cSlotId = Slot, + cImageView = pResource != nullptr ? pResource->GetImageView() : nullptr, + cBufferView = pResource != nullptr ? pResource->GetBufferView() : nullptr + ] (DxvkContext* ctx) { + ctx->bindResourceView(cSlotId, cImageView, cBufferView); + }); + } + + + void D3D11DeviceContext::BindUnorderedAccessView( + UINT UavSlot, + UINT CtrSlot, + D3D11UnorderedAccessView* pUav) { + EmitCs([ + cUavSlotId = UavSlot, + cCtrSlotId = CtrSlot, + cImageView = pUav != nullptr ? pUav->GetImageView() : nullptr, + cBufferView = pUav != nullptr ? pUav->GetBufferView() : nullptr, + cCounterSlice = pUav != nullptr ? pUav->GetCounterSlice() : DxvkBufferSlice() + ] (DxvkContext* ctx) { + ctx->bindResourceView (cUavSlotId, cImageView, cBufferView); + ctx->bindResourceBuffer (cCtrSlotId, cCounterSlice); + }); + } + + + void D3D11DeviceContext::SetConstantBuffers( DxbcProgramType ShaderStage, D3D11ConstantBufferBindings& Bindings, UINT StartSlot, @@ -2113,21 +2167,13 @@ namespace dxvk { if (Bindings[StartSlot + i] != newBuffer) { Bindings[StartSlot + i] = newBuffer; - - EmitCs([ - cSlotId = slotId + i, - cSlice = newBuffer != nullptr - ? newBuffer->GetBufferSlice() - : DxvkBufferSlice() - ] (DxvkContext* ctx) { - ctx->bindResourceBuffer(cSlotId, cSlice); - }); + BindConstantBuffer(slotId + i, newBuffer); } } } - void D3D11DeviceContext::BindSamplers( + void D3D11DeviceContext::SetSamplers( DxbcProgramType ShaderStage, D3D11SamplerBindings& Bindings, UINT StartSlot, @@ -2142,21 +2188,13 @@ namespace dxvk { if (Bindings[StartSlot + i] != sampler) { Bindings[StartSlot + i] = sampler; - - EmitCs([ - cSlotId = slotId + i, - cSampler = sampler != nullptr - ? sampler->GetDXVKSampler() - : nullptr - ] (DxvkContext* ctx) { - ctx->bindResourceSampler(cSlotId, cSampler); - }); + BindSampler(slotId + i, sampler); } } } - void D3D11DeviceContext::BindShaderResources( + void D3D11DeviceContext::SetShaderResources( DxbcProgramType ShaderStage, D3D11ShaderResourceBindings& Bindings, UINT StartSlot, @@ -2171,34 +2209,13 @@ namespace dxvk { if (Bindings[StartSlot + i] != resView) { Bindings[StartSlot + i] = resView; - - if (resView != nullptr) { - // Figure out what we have to bind based on the resource type - if (resView->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) { - EmitCs([cSlotId = slotId + i, cView = resView->GetBufferView()] - (DxvkContext* ctx) { - ctx->bindResourceTexelBuffer(cSlotId, cView); - }); - } else { - EmitCs([cSlotId = slotId + i, cView = resView->GetImageView()] - (DxvkContext* ctx) { - ctx->bindResourceImage(cSlotId, cView); - }); - } - } else { - // When unbinding a resource, it doesn't really matter if - // the resource type is correct, so we'll just bind a null - // image to the given resource slot - EmitCs([cSlotId = slotId + i] (DxvkContext* ctx) { - ctx->bindResourceImage(cSlotId, nullptr); - }); - } + BindShaderResource(slotId + i, resView); } } } - void D3D11DeviceContext::BindUnorderedAccessViews( + void D3D11DeviceContext::SetUnorderedAccessViews( DxbcProgramType ShaderStage, D3D11UnorderedAccessBindings& Bindings, UINT StartSlot, @@ -2217,35 +2234,7 @@ namespace dxvk { if (Bindings[StartSlot + i] != uav) { Bindings[StartSlot + i] = uav; - - if (uav != nullptr) { - // Figure out what we have to bind based on the resource type - if (uav->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) { - EmitCs([ - cUavSlotId = uavSlotId + i, - cCtrSlotId = ctrSlotId + i, - cUavBuffer = uav->GetBufferView(), - cCtrBuffer = uav->GetCounterSlice() - ] (DxvkContext* ctx) { - ctx->bindResourceTexelBuffer(cUavSlotId, cUavBuffer); - ctx->bindResourceBuffer (cCtrSlotId, cCtrBuffer); - }); - } else { - EmitCs([cUavSlotId = uavSlotId + i, cUavImage = uav->GetImageView()] - (DxvkContext* ctx) { - ctx->bindResourceImage(cUavSlotId, cUavImage); - }); - } - } else { - // When unbinding a resource, it doesn't really matter if - // the resource type is correct, so we'll just bind a null - // image to the given resource slot - EmitCs([cUavSlotId = uavSlotId + i, cCtrSlotId = ctrSlotId + i] - (DxvkContext* ctx) { - ctx->bindResourceTexelBuffer(cUavSlotId, nullptr); - ctx->bindResourceBuffer (cCtrSlotId, DxvkBufferSlice()); - }); - } + BindUnorderedAccessView(uavSlotId + i, ctrSlotId + i, uav); } } } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 225eba350..751b5e9e2 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -552,28 +552,45 @@ namespace dxvk { UINT Offset, DXGI_FORMAT Format); - void BindConstantBuffers( + void BindConstantBuffer( + UINT Slot, + D3D11Buffer* pBuffer); + + void BindSampler( + UINT Slot, + D3D11SamplerState* pSampler); + + void BindShaderResource( + UINT Slot, + D3D11ShaderResourceView* pResource); + + void BindUnorderedAccessView( + UINT UavSlot, + UINT CtrSlot, + D3D11UnorderedAccessView* pUav); + + void SetConstantBuffers( DxbcProgramType ShaderStage, D3D11ConstantBufferBindings& Bindings, UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers); - void BindSamplers( + void SetSamplers( DxbcProgramType ShaderStage, D3D11SamplerBindings& Bindings, UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void BindShaderResources( + void SetShaderResources( DxbcProgramType ShaderStage, D3D11ShaderResourceBindings& Bindings, UINT StartSlot, UINT NumResources, ID3D11ShaderResourceView* const* ppResources); - void BindUnorderedAccessViews( + void SetUnorderedAccessViews( DxbcProgramType ShaderStage, D3D11UnorderedAccessBindings& Bindings, UINT StartSlot, diff --git a/src/dxgi/dxgi_presenter.cpp b/src/dxgi/dxgi_presenter.cpp index 003e8eb23..8cdc96bba 100644 --- a/src/dxgi/dxgi_presenter.cpp +++ b/src/dxgi/dxgi_presenter.cpp @@ -205,14 +205,14 @@ namespace dxvk { m_blendMode.enableBlending = VK_FALSE; m_context->setBlendMode(0, m_blendMode); - m_context->bindResourceImage(BindingIds::Texture, m_backBufferView); + m_context->bindResourceView(BindingIds::Texture, m_backBufferView, nullptr); m_context->draw(4, 1, 0, 0); if (m_hud != nullptr) { m_blendMode.enableBlending = VK_TRUE; m_context->setBlendMode(0, m_blendMode); - m_context->bindResourceImage(BindingIds::Texture, m_hud->texture()); + m_context->bindResourceView(BindingIds::Texture, m_hud->texture(), nullptr); m_context->draw(4, 1, 0, 0); } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index fc7ac8b9d..d3f2b0190 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -135,12 +135,14 @@ namespace dxvk { } - void DxvkContext::bindResourceTexelBuffer( + void DxvkContext::bindResourceView( uint32_t slot, + const Rc& imageView, const Rc& bufferView) { - if (m_rc[slot].bufferView != bufferView) { + if (m_rc[slot].imageView != imageView + || m_rc[slot].bufferView != bufferView) { m_rc[slot].sampler = nullptr; - m_rc[slot].imageView = nullptr; + m_rc[slot].imageView = imageView; m_rc[slot].bufferView = bufferView; m_rc[slot].bufferSlice = DxvkBufferSlice(); @@ -151,22 +153,6 @@ namespace dxvk { } - void DxvkContext::bindResourceImage( - uint32_t slot, - const Rc& image) { - if (m_rc[slot].imageView != image) { - m_rc[slot].sampler = nullptr; - m_rc[slot].imageView = image; - m_rc[slot].bufferView = nullptr; - m_rc[slot].bufferSlice = DxvkBufferSlice(); - - m_flags.set( - DxvkContextFlag::CpDirtyResources, - DxvkContextFlag::GpDirtyResources); - } - } - - void DxvkContext::bindResourceSampler( uint32_t slot, const Rc& sampler) { diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 51db5feb9..5990a08f6 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -96,28 +96,19 @@ namespace dxvk { const DxvkBufferSlice& buffer); /** - * \brief Binds texel buffer view + * \brief Binds image or buffer view * - * Can be used for both uniform texel - * buffers and storage texel buffers. - * \param [in] slot Resource binding slot - * \param [in] bufferView Buffer view to bind - */ - void bindResourceTexelBuffer( - uint32_t slot, - const Rc& bufferView); - - /** - * \brief Binds image view - * - * Can be used for sampled images with a - * dedicated sampler and storage images. + * Can be used for sampled images with a dedicated + * sampler and for storage images, as well as for + * uniform texel buffers and storage texel buffers. * \param [in] slot Resource binding slot * \param [in] imageView Image view to bind + * \param [in] bufferView Buffer view to bind */ - void bindResourceImage( + void bindResourceView( uint32_t slot, - const Rc& image); + const Rc& imageView, + const Rc& bufferView); /** * \brief Binds image sampler diff --git a/src/dxvk/hud/dxvk_hud_text.cpp b/src/dxvk/hud/dxvk_hud_text.cpp index 601558298..137a9b411 100644 --- a/src/dxvk/hud/dxvk_hud_text.cpp +++ b/src/dxvk/hud/dxvk_hud_text.cpp @@ -55,7 +55,7 @@ namespace dxvk::hud { sizeof(HudTextVertex)); context->bindResourceSampler(1, m_fontSampler); - context->bindResourceImage (2, m_fontView); + context->bindResourceView (2, m_fontView, nullptr); m_vertexIndex = 0; }