diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 07671f54..d0ff8524 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3621,8 +3621,8 @@ namespace dxvk { || Type == D3DSAMP_MAXMIPLEVEL || Type == D3DSAMP_BORDERCOLOR) m_dirtySamplerStates |= 1u << StateSampler; - else if (Type == D3DSAMP_SRGBTEXTURE) - BindTexture(StateSampler); + else if (Type == D3DSAMP_SRGBTEXTURE && m_state.textures[StateSampler] != nullptr) + m_dirtyTextures |= 1u << StateSampler; constexpr DWORD Fetch4Enabled = MAKEFOURCC('G', 'E', 'T', '4'); constexpr DWORD Fetch4Disabled = MAKEFOURCC('G', 'E', 'T', '1'); @@ -3676,7 +3676,7 @@ namespace dxvk { TextureChangePrivate(m_state.textures[StateSampler], pTexture); - BindTexture(StateSampler); + m_dirtyTextures |= 1u << StateSampler; UpdateActiveTextures(StateSampler, combinedUsage); @@ -5779,7 +5779,17 @@ namespace dxvk { } } - if (commonTex == nullptr) { + if (commonTex != nullptr) { + EmitCs([ + cColorSlot = colorSlot, + cDepthSlot = depthSlot, + cDepth = commonTex->IsShadow(), + cImageView = commonTex->GetSampleView(srgb) + ](DxvkContext* ctx) { + ctx->bindResourceView(cColorSlot, !cDepth ? cImageView : nullptr, nullptr); + ctx->bindResourceView(cDepthSlot, cDepth ? cImageView : nullptr, nullptr); + }); + } else { EmitCs([ cColorSlot = colorSlot, cDepthSlot = depthSlot @@ -5787,18 +5797,7 @@ namespace dxvk { ctx->bindResourceView(cColorSlot, nullptr, nullptr); ctx->bindResourceView(cDepthSlot, nullptr, nullptr); }); - return; } - - EmitCs([ - cColorSlot = colorSlot, - cDepthSlot = depthSlot, - cDepth = commonTex->IsShadow(), - cImageView = commonTex->GetSampleView(srgb) - ](DxvkContext* ctx) { - ctx->bindResourceView(cColorSlot, !cDepth ? cImageView : nullptr, nullptr); - ctx->bindResourceView(cDepthSlot, cDepth ? cImageView : nullptr, nullptr); - }); } @@ -5810,6 +5809,13 @@ namespace dxvk { } + void D3D9DeviceEx::UndirtyTextures() { + for (uint32_t tex = m_dirtyTextures; tex; tex &= tex - 1) + BindTexture(bit::tzcnt(tex)); + + m_dirtyTextures = 0; + } + void D3D9DeviceEx::MarkSamplersDirty() { m_dirtySamplerStates = 0x001fffff; // 21 bits. } @@ -5881,6 +5887,9 @@ namespace dxvk { if (m_dirtySamplerStates) UndirtySamplers(); + if (m_dirtyTextures) + UndirtyTextures(); + if (m_flags.test(D3D9DeviceFlag::DirtyBlendState)) BindBlendState(); @@ -6990,6 +6999,8 @@ namespace dxvk { }); } + m_dirtyTextures = 0; + auto& ss = m_state.samplerStates; for (uint32_t i = 0; i < ss.size(); i++) { auto& state = ss[i]; diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 71972113..573bc15a 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -838,6 +838,8 @@ namespace dxvk { void UndirtySamplers(); + void UndirtyTextures(); + void MarkSamplersDirty(); D3D9DrawInfo GenerateDrawInfo( @@ -919,6 +921,7 @@ namespace dxvk { D3D9DeviceFlags m_flags; uint32_t m_dirtySamplerStates = 0; + uint32_t m_dirtyTextures = 0; D3D9Adapter* m_adapter; Rc m_dxvkDevice;