diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
index 4a5633c9..cf74f649 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
@@ -485,6 +485,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
var face = _state.State.FaceState;
UpdateFrontFace(yControl, face.FrontFace);
+ UpdateDepthMode();
bool flipY = yControl.HasFlag(YControl.NegateY);
@@ -492,8 +493,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
for (int index = 0; index < Constants.TotalViewports; index++)
{
- var transform = _state.State.ViewportTransform[index];
- var extents = _state.State.ViewportExtents[index];
+ ref var transform = ref _state.State.ViewportTransform[index];
+ ref var extents = ref _state.State.ViewportExtents[index];
float scaleX = MathF.Abs(transform.ScaleX);
float scaleY = transform.ScaleY;
@@ -508,24 +509,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
scaleY = -scaleY;
}
- if (index == 0)
- {
- // Try to guess the depth mode being used on the high level API
- // based on current transform.
- // It is setup like so by said APIs:
- // If depth mode is ZeroToOne:
- // TranslateZ = Near
- // ScaleZ = Far - Near
- // If depth mode is MinusOneToOne:
- // TranslateZ = (Near + Far) / 2
- // ScaleZ = (Far - Near) / 2
- // DepthNear/Far are sorted such as that Near is always less than Far.
- DepthMode depthMode = extents.DepthNear != transform.TranslateZ &&
- extents.DepthFar != transform.TranslateZ ? DepthMode.MinusOneToOne : DepthMode.ZeroToOne;
-
- _context.Renderer.Pipeline.SetDepthMode(depthMode);
- }
-
float x = transform.TranslateX - scaleX;
float y = transform.TranslateY - scaleY;
@@ -564,6 +547,44 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_context.Renderer.Pipeline.SetViewports(0, viewports);
}
+ ///
+ /// Updates the depth mode (0 to 1 or -1 to 1) based on the current viewport and depth mode register state.
+ ///
+ private void UpdateDepthMode()
+ {
+ ref var transform = ref _state.State.ViewportTransform[0];
+ ref var extents = ref _state.State.ViewportExtents[0];
+
+ DepthMode depthMode;
+
+ if (!float.IsInfinity(extents.DepthNear) &&
+ !float.IsInfinity(extents.DepthFar) &&
+ (extents.DepthFar - extents.DepthNear) != 0)
+ {
+ // Try to guess the depth mode being used on the high level API
+ // based on current transform.
+ // It is setup like so by said APIs:
+ // If depth mode is ZeroToOne:
+ // TranslateZ = Near
+ // ScaleZ = Far - Near
+ // If depth mode is MinusOneToOne:
+ // TranslateZ = (Near + Far) / 2
+ // ScaleZ = (Far - Near) / 2
+ // DepthNear/Far are sorted such as that Near is always less than Far.
+ depthMode = extents.DepthNear != transform.TranslateZ &&
+ extents.DepthFar != transform.TranslateZ
+ ? DepthMode.MinusOneToOne
+ : DepthMode.ZeroToOne;
+ }
+ else
+ {
+ // If we can't guess from the viewport transform, then just use the depth mode register.
+ depthMode = (DepthMode)(_state.State.DepthMode & 1);
+ }
+
+ _context.Renderer.Pipeline.SetDepthMode(depthMode);
+ }
+
///
/// Updates polygon mode state based on current GPU state.
///