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;
}
///