Do not set render targets as modified for discard-only draws

- Shader cache version bump
This commit is contained in:
gdkchan
2026-08-21 12:38:11 -05:00
committed by KeatonTheBot
parent bd78dada19
commit 00fc037bfd
11 changed files with 197 additions and 54 deletions
@@ -466,6 +466,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
engine.UpdateState(ulong.MaxValue & ~(1UL << StateUpdater.ShaderStateIndex));
_channel.TextureManager.SignalRenderTargetsModifiable();
_channel.TextureManager.UpdateRenderTargets();
int textureId = _state.State.DrawTextureTextureId;
@@ -803,7 +804,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
int index = (argument >> 6) & 0xf;
int layer = (argument >> 10) & 0x3ff;
RenderTargetUpdateFlags updateFlags = RenderTargetUpdateFlags.SingleColor;
RenderTargetUpdateFlags updateFlags = RenderTargetUpdateFlags.SingleColor | RenderTargetUpdateFlags.ForClear;
if (layer != 0 || layerCount > 1)
{
@@ -38,6 +38,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
/// </summary>
DiscardClip = 1 << 4,
/// <summary>
/// Indicates that the render target will be used for a clear operation.
/// </summary>
ForClear = 1 << 5,
/// <summary>
/// Default update flags for draw.
/// </summary>
@@ -45,6 +45,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
private ProgramPipelineState _pipeline;
private bool _fsReadsFragCoord;
private bool _fsAlwaysDiscards;
private bool _vsUsesDrawParameters;
private bool _vtgWritesRtLayer;
private byte _vsClipDistancesWritten;
@@ -491,6 +492,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
Span<RtColorState> rtColorStateSpan = _state.State.RtColorState.AsSpan();
bool rtModifiable = updateFlags.HasFlag(RenderTargetUpdateFlags.ForClear) || !_fsAlwaysDiscards;
for (int index = 0; index < Constants.TotalRenderTargets; index++)
{
int rtIndex = useControl ? rtControl.UnpackPermutationIndex(index) : index;
@@ -499,7 +502,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
if (index >= count || !IsRtEnabled(colorState) || (singleColor && index != singleUse))
{
changedScale |= _channel.TextureManager.SetRenderTargetColor(index, null);
changedScale |= _channel.TextureManager.SetRenderTargetColor(index, null, rtModifiable);
continue;
}
@@ -518,7 +521,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
samplesInY,
sizeHint);
changedScale |= _channel.TextureManager.SetRenderTargetColor(index, color);
changedScale |= _channel.TextureManager.SetRenderTargetColor(index, color, rtModifiable);
if (color != null)
{
@@ -572,7 +575,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
}
}
changedScale |= _channel.TextureManager.SetRenderTargetDepthStencil(depthStencil);
changedScale |= _channel.TextureManager.SetRenderTargetDepthStencil(depthStencil, rtModifiable);
if (changedScale)
{
@@ -1517,20 +1520,38 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_currentProgramInfo[stageIndex] = info;
}
if (gs.Shaders[5]?.Info.UsesFragCoord == true)
{
// Make sure we update the viewport size on the support buffer if it will be consumed on the new shader.
_fsReadsFragCoord = false;
if (!_fsReadsFragCoord && (_state.State.YControl & YControl.NegateY) != 0)
ShaderProgramInfo fragmentShaderInfo = gs.Shaders[5]?.Info;
if (fragmentShaderInfo != null)
{
if (fragmentShaderInfo.UsesFragCoord)
{
UpdateSupportBufferViewportSize();
// Make sure we update the viewport size on the support buffer if it will be consumed on the new shader.
if (!_fsReadsFragCoord && (_state.State.YControl & YControl.NegateY) != 0)
{
UpdateSupportBufferViewportSize();
}
_fsReadsFragCoord = true;
}
_fsReadsFragCoord = true;
if (_fsAlwaysDiscards != fragmentShaderInfo.HasUnconditionalDiscard)
{
_fsAlwaysDiscards = fragmentShaderInfo.HasUnconditionalDiscard;
if (!_fsAlwaysDiscards)
{
_channel.TextureManager.RefreshModifiedTextures();
_channel.TextureManager.SignalRenderTargetsModifiable();
}
}
}
else
{
_fsReadsFragCoord = false;
_fsAlwaysDiscards = false;
}
if (gs.VertexAsCompute != null)