diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs index 6b4ea89f3..b3eb62185 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs @@ -343,11 +343,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed bool unalignedChanged = _currentSpecState.SetHasUnalignedStorageBuffer(_channel.BufferManager.HasUnalignedStorageBuffers); - if (!_channel.TextureManager.CommitGraphicsBindings(_shaderSpecState) || unalignedChanged) + bool scaleMismatch; + do { - // Shader must be reloaded. _vtgWritesRtLayer should not change. - UpdateShaderState(); + if (!_channel.TextureManager.CommitGraphicsBindings(_shaderSpecState, out scaleMismatch) || unalignedChanged) + { + // Shader must be reloaded. _vtgWritesRtLayer should not change. + UpdateShaderState(); + } + + if (scaleMismatch) + { + // Binding textures changed scale of the bound render targets, correct the render target scale and rebind. + UpdateRenderTargetState(); + } } + while (scaleMismatch); _channel.BufferManager.CommitGraphicsBindings(_drawState.DrawIndexed); } diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureManager.cs index 3bf0beefd..8c2a88727 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureManager.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureManager.cs @@ -360,15 +360,16 @@ namespace Ryujinx.Graphics.Gpu.Image /// Commits bindings on the graphics pipeline. /// /// Specialization state for the bound shader + /// True if there is a scale mismatch in the render targets, indicating they must be re-evaluated /// True if all bound textures match the current shader specialization state, false otherwise - public bool CommitGraphicsBindings(ShaderSpecializationState specState) + public bool CommitGraphicsBindings(ShaderSpecializationState specState, out bool scaleMismatch) { _texturePoolCache.Tick(); _samplerPoolCache.Tick(); bool result = _gpBindingsManager.CommitBindings(specState); - UpdateRenderTargets(); + scaleMismatch = UpdateRenderTargets(); return result; } @@ -426,9 +427,12 @@ namespace Ryujinx.Graphics.Gpu.Image /// /// Update host framebuffer attachments based on currently bound render target buffers. /// - public void UpdateRenderTargets() + /// True if there is a scale mismatch in the render targets, indicating they must be re-evaluated + public bool UpdateRenderTargets() { bool anyChanged = false; + float expectedScale = RenderTargetScale; + bool scaleMismatch = false; Texture dsTexture = _rtDepthStencil; ITexture hostDsTexture = null; @@ -448,6 +452,11 @@ namespace Ryujinx.Graphics.Gpu.Image { _rtHostDs = hostDsTexture; anyChanged = true; + + if (dsTexture != null && dsTexture.ScaleFactor != expectedScale) + { + scaleMismatch = true; + } } for (int index = 0; index < _rtColors.Length; index++) @@ -470,6 +479,11 @@ namespace Ryujinx.Graphics.Gpu.Image { _rtHostColors[index] = hostTexture; anyChanged = true; + + if (texture != null && texture.ScaleFactor != expectedScale) + { + scaleMismatch = true; + } } } @@ -477,6 +491,8 @@ namespace Ryujinx.Graphics.Gpu.Image { _context.Renderer.Pipeline.SetRenderTargets(_rtHostColors, _rtHostDs); } + + return scaleMismatch; } ///