[d3d11] Lazy-bind samplers

This commit is contained in:
Philip Rebohle 2025-02-19 02:36:45 +01:00
parent 5409af074a
commit ffe721c49e
2 changed files with 56 additions and 13 deletions

View file

@ -3206,6 +3206,24 @@ namespace dxvk {
} }
template<typename ContextType>
void D3D11CommonContext<ContextType>::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<typename ContextType> template<typename ContextType>
void D3D11CommonContext<ContextType>::ApplyDirtyShaderResources( void D3D11CommonContext<ContextType>::ApplyDirtyShaderResources(
DxbcProgramType Stage, DxbcProgramType Stage,
@ -3239,6 +3257,7 @@ namespace dxvk {
auto& boundMask = m_state.lazy.bindingsUsed[stage]; auto& boundMask = m_state.lazy.bindingsUsed[stage];
auto& dirtyMask = m_state.lazy.bindingsDirty[stage]; auto& dirtyMask = m_state.lazy.bindingsDirty[stage];
ApplyDirtySamplers(stage, boundMask, dirtyMask);
ApplyDirtyConstantBuffers(stage, boundMask, dirtyMask); ApplyDirtyConstantBuffers(stage, boundMask, dirtyMask);
ApplyDirtyShaderResources(stage, boundMask, dirtyMask); ApplyDirtyShaderResources(stage, boundMask, dirtyMask);
@ -3254,6 +3273,7 @@ namespace dxvk {
auto& boundMask = m_state.lazy.bindingsUsed[stage]; auto& boundMask = m_state.lazy.bindingsUsed[stage];
auto& dirtyMask = m_state.lazy.bindingsDirty[stage]; auto& dirtyMask = m_state.lazy.bindingsDirty[stage];
ApplyDirtySamplers(stage, boundMask, dirtyMask);
ApplyDirtyConstantBuffers(stage, boundMask, dirtyMask); ApplyDirtyConstantBuffers(stage, boundMask, dirtyMask);
ApplyDirtyShaderResources(stage, boundMask, dirtyMask); ApplyDirtyShaderResources(stage, boundMask, dirtyMask);
@ -3838,25 +3858,27 @@ namespace dxvk {
template<typename ContextType> template<typename ContextType>
template<DxbcProgramType ShaderStage>
void D3D11CommonContext<ContextType>::BindSampler( void D3D11CommonContext<ContextType>::BindSampler(
DxbcProgramType ShaderStage,
UINT Slot, UINT Slot,
D3D11SamplerState* pSampler) { D3D11SamplerState* pSampler) {
uint32_t slotId = computeSamplerBinding(ShaderStage, Slot);
if (pSampler) { if (pSampler) {
EmitCs([ EmitCs([
cSlotId = Slot, cSlotId = slotId,
cStage = GetShaderStage(ShaderStage),
cSampler = pSampler->GetDXVKSampler() cSampler = pSampler->GetDXVKSampler()
] (DxvkContext* ctx) mutable { ] (DxvkContext* ctx) mutable {
VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); ctx->bindResourceSampler(cStage, cSlotId,
ctx->bindResourceSampler(stage, cSlotId,
Forwarder::move(cSampler)); Forwarder::move(cSampler));
}); });
} else { } else {
EmitCs([ EmitCs([
cSlotId = Slot cSlotId = slotId,
cStage = GetShaderStage(ShaderStage)
] (DxvkContext* ctx) { ] (DxvkContext* ctx) {
VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); ctx->bindResourceSampler(cStage, cSlotId, nullptr);
ctx->bindResourceSampler(stage, cSlotId, nullptr);
}); });
} }
} }
@ -4388,6 +4410,18 @@ namespace dxvk {
} }
template<typename ContextType>
bool D3D11CommonContext<ContextType>::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<typename ContextType> template<typename ContextType>
bool D3D11CommonContext<ContextType>::DirtyShaderResource( bool D3D11CommonContext<ContextType>::DirtyShaderResource(
DxbcProgramType ShaderStage, DxbcProgramType ShaderStage,
@ -4908,10 +4942,8 @@ namespace dxvk {
template<DxbcProgramType Stage> template<DxbcProgramType Stage>
void D3D11CommonContext<ContextType>::RestoreSamplers() { void D3D11CommonContext<ContextType>::RestoreSamplers() {
const auto& bindings = m_state.samplers[Stage]; const auto& bindings = m_state.samplers[Stage];
uint32_t slotId = computeSamplerBinding(Stage, 0);
for (uint32_t i = 0; i < bindings.maxCount; i++) for (uint32_t i = 0; i < bindings.maxCount; i++)
BindSampler<Stage>(slotId + i, bindings.samplers[i]); BindSampler(Stage, i, bindings.samplers[i]);
} }
@ -5088,14 +5120,15 @@ namespace dxvk {
UINT NumSamplers, UINT NumSamplers,
ID3D11SamplerState* const* ppSamplers) { ID3D11SamplerState* const* ppSamplers) {
auto& bindings = m_state.samplers[ShaderStage]; auto& bindings = m_state.samplers[ShaderStage];
uint32_t slotId = computeSamplerBinding(ShaderStage, StartSlot);
for (uint32_t i = 0; i < NumSamplers; i++) { for (uint32_t i = 0; i < NumSamplers; i++) {
auto sampler = static_cast<D3D11SamplerState*>(ppSamplers[i]); auto sampler = static_cast<D3D11SamplerState*>(ppSamplers[i]);
if (bindings.samplers[StartSlot + i] != sampler) { if (bindings.samplers[StartSlot + i] != sampler) {
bindings.samplers[StartSlot + i] = sampler; bindings.samplers[StartSlot + i] = sampler;
BindSampler<ShaderStage>(slotId + i, sampler);
if (!DirtySampler(ShaderStage, StartSlot + i, !sampler))
BindSampler(ShaderStage, StartSlot + i, sampler);
} }
} }

View file

@ -804,6 +804,11 @@ namespace dxvk {
const DxbcBindingMask& BoundMask, const DxbcBindingMask& BoundMask,
DxbcBindingMask& DirtyMask); DxbcBindingMask& DirtyMask);
void ApplyDirtySamplers(
DxbcProgramType Stage,
const DxbcBindingMask& BoundMask,
DxbcBindingMask& DirtyMask);
void ApplyDirtyShaderResources( void ApplyDirtyShaderResources(
DxbcProgramType Stage, DxbcProgramType Stage,
const DxbcBindingMask& BoundMask, const DxbcBindingMask& BoundMask,
@ -881,8 +886,8 @@ namespace dxvk {
UINT Offset, UINT Offset,
UINT Length); UINT Length);
template<DxbcProgramType ShaderStage>
void BindSampler( void BindSampler(
DxbcProgramType ShaderStage,
UINT Slot, UINT Slot,
D3D11SamplerState* pSampler); D3D11SamplerState* pSampler);
@ -938,6 +943,11 @@ namespace dxvk {
uint32_t Slot, uint32_t Slot,
bool IsNull); bool IsNull);
bool DirtySampler(
DxbcProgramType ShaderStage,
uint32_t Slot,
bool IsNull);
bool DirtyShaderResource( bool DirtyShaderResource(
DxbcProgramType ShaderStage, DxbcProgramType ShaderStage,
uint32_t Slot, uint32_t Slot,