diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 58a110048..e61fb1a0e 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3206,6 +3206,24 @@ namespace dxvk { } + template + void D3D11CommonContext::ApplyDirtySamplers( + DxbcProgramType Stage, + const DxbcBindingMask& BoundMask, + DxbcBindingMask& DirtyMask) { + uint32_t bindMask = BoundMask.samplerMask & DirtyMask.samplerMask; + + if (!bindMask) + return; + + const auto& state = m_state.samplers[Stage]; + DirtyMask.samplerMask -= bindMask; + + for (uint32_t slot : bit::BitMask(bindMask)) + BindSampler(Stage, slot, state.samplers[slot]); + } + + template void D3D11CommonContext::ApplyDirtyShaderResources( DxbcProgramType Stage, @@ -3239,6 +3257,7 @@ namespace dxvk { auto& boundMask = m_state.lazy.bindingsUsed[stage]; auto& dirtyMask = m_state.lazy.bindingsDirty[stage]; + ApplyDirtySamplers(stage, boundMask, dirtyMask); ApplyDirtyConstantBuffers(stage, boundMask, dirtyMask); ApplyDirtyShaderResources(stage, boundMask, dirtyMask); @@ -3254,6 +3273,7 @@ namespace dxvk { auto& boundMask = m_state.lazy.bindingsUsed[stage]; auto& dirtyMask = m_state.lazy.bindingsDirty[stage]; + ApplyDirtySamplers(stage, boundMask, dirtyMask); ApplyDirtyConstantBuffers(stage, boundMask, dirtyMask); ApplyDirtyShaderResources(stage, boundMask, dirtyMask); @@ -3838,25 +3858,27 @@ namespace dxvk { template - template void D3D11CommonContext::BindSampler( + DxbcProgramType ShaderStage, UINT Slot, D3D11SamplerState* pSampler) { + uint32_t slotId = computeSamplerBinding(ShaderStage, Slot); + if (pSampler) { EmitCs([ - cSlotId = Slot, + cSlotId = slotId, + cStage = GetShaderStage(ShaderStage), cSampler = pSampler->GetDXVKSampler() ] (DxvkContext* ctx) mutable { - VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); - ctx->bindResourceSampler(stage, cSlotId, + ctx->bindResourceSampler(cStage, cSlotId, Forwarder::move(cSampler)); }); } else { EmitCs([ - cSlotId = Slot + cSlotId = slotId, + cStage = GetShaderStage(ShaderStage) ] (DxvkContext* ctx) { - VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); - ctx->bindResourceSampler(stage, cSlotId, nullptr); + ctx->bindResourceSampler(cStage, cSlotId, nullptr); }); } } @@ -4388,6 +4410,18 @@ namespace dxvk { } + template + bool D3D11CommonContext::DirtySampler( + DxbcProgramType ShaderStage, + uint32_t Slot, + bool IsNull) { + return DirtyBindingGeneric(ShaderStage, + m_state.lazy.bindingsUsed[ShaderStage].samplerMask, + m_state.lazy.bindingsDirty[ShaderStage].samplerMask, + 1u << Slot, IsNull); + } + + template bool D3D11CommonContext::DirtyShaderResource( DxbcProgramType ShaderStage, @@ -4908,10 +4942,8 @@ namespace dxvk { template void D3D11CommonContext::RestoreSamplers() { const auto& bindings = m_state.samplers[Stage]; - uint32_t slotId = computeSamplerBinding(Stage, 0); - for (uint32_t i = 0; i < bindings.maxCount; i++) - BindSampler(slotId + i, bindings.samplers[i]); + BindSampler(Stage, i, bindings.samplers[i]); } @@ -5088,14 +5120,15 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { auto& bindings = m_state.samplers[ShaderStage]; - uint32_t slotId = computeSamplerBinding(ShaderStage, StartSlot); for (uint32_t i = 0; i < NumSamplers; i++) { auto sampler = static_cast(ppSamplers[i]); if (bindings.samplers[StartSlot + i] != sampler) { bindings.samplers[StartSlot + i] = sampler; - BindSampler(slotId + i, sampler); + + if (!DirtySampler(ShaderStage, StartSlot + i, !sampler)) + BindSampler(ShaderStage, StartSlot + i, sampler); } } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 6a0b9f7fb..62fb05ac0 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -804,6 +804,11 @@ namespace dxvk { const DxbcBindingMask& BoundMask, DxbcBindingMask& DirtyMask); + void ApplyDirtySamplers( + DxbcProgramType Stage, + const DxbcBindingMask& BoundMask, + DxbcBindingMask& DirtyMask); + void ApplyDirtyShaderResources( DxbcProgramType Stage, const DxbcBindingMask& BoundMask, @@ -881,8 +886,8 @@ namespace dxvk { UINT Offset, UINT Length); - template void BindSampler( + DxbcProgramType ShaderStage, UINT Slot, D3D11SamplerState* pSampler); @@ -938,6 +943,11 @@ namespace dxvk { uint32_t Slot, bool IsNull); + bool DirtySampler( + DxbcProgramType ShaderStage, + uint32_t Slot, + bool IsNull); + bool DirtyShaderResource( DxbcProgramType ShaderStage, uint32_t Slot,