diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs index 4a5633c9c..cf74f649e 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. ///