From 3ceca9c381c58e4b29de842ba889d1987b9cca64 Mon Sep 17 00:00:00 2001 From: avan Date: Fri, 7 Aug 2026 10:58:41 +0800 Subject: [PATCH] Fix shadow state handling for blend enable updates Incorrect rendering was observed during loading transitions in Trails in the Sky 1st Chapter. Testing showed that routing the first render target's RT0 BlendEnable transition from disabled to enabled through the normal register write path prevented the issue. Further investigation found that the normal register write was restoring Shadow RAM behavior that was missing from UpdateBlendEnable. UpdateBlendEnable uses a fast bulk update path instead of issuing a normal register write for each render target. As a result, it bypasses the Shadow RAM handling provided by DeviceStateWithShadow.WriteWithRedundancyCheck. A normal register write updates both State and ShadowState in MethodTrack and MethodTrackWithFilter modes. In MethodReplay mode, it ignores the incoming value and restores the value previously stored in ShadowState to State. UpdateBlendEnable must reproduce the same behavior while retaining its bulk comparison and copy path. In track modes, copy the incoming enable values to shadowState. In replay mode, copy shadowState to the incoming enable span, then let the existing comparison and copy logic update state and mark BlendState dirty when necessary. The original implementation incorrectly used state for both track and replay handling. This prevented Shadow RAM from correctly recording or replaying BlendEnable values, which could cause rendering state synchronization errors. Correct the bulk update path to use ShadowState for tracking and replay. This preserves the optimized bulk operation while addressing the underlying issue without requiring an RT0-specific compatibility workaround. (cherry picked from commit 733bd0951b1397554087b63acc1b7d7d4c0b2906) --- src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs index 99cd0c2b2..67ab96f41 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs @@ -268,10 +268,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed { SetMmeShadowRamControlMode shadow = ShadowMode; Span state = _state.State.BlendEnable.AsSpan(); + Span shadowState = _state.ShadowState.BlendEnable.AsSpan(); if (shadow.IsReplay()) { - state.CopyTo(enable); + shadowState.CopyTo(enable); } if (!UnsafeEquals32Byte(enable, state)) @@ -283,7 +284,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed if (shadow.IsTrack()) { - enable.CopyTo(state); + enable.CopyTo(shadowState); } }