From 7ce5584f9e0d86f17ea4fc781483f60cfa288340 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sat, 7 Dec 2019 01:54:28 -0300 Subject: [PATCH] Support depth clip mode and disable shader fast math optimization on NVIDIA as a workaround for compiler bugs (?) --- Ryujinx.Graphics.GAL/DepthMode.cs | 8 ++++++++ Ryujinx.Graphics.GAL/IPipeline.cs | 2 ++ Ryujinx.Graphics.Gpu/Engine/Methods.cs | 6 +++++- Ryujinx.Graphics.Gpu/State/MethodOffset.cs | 1 + .../Converters/DepthModeConverter.cs | 20 +++++++++++++++++++ Ryujinx.Graphics.OpenGL/Pipeline.cs | 20 ++++++++++++++++--- .../CodeGen/Glsl/Declarations.cs | 2 ++ 7 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 Ryujinx.Graphics.GAL/DepthMode.cs create mode 100644 Ryujinx.Graphics.OpenGL/Converters/DepthModeConverter.cs diff --git a/Ryujinx.Graphics.GAL/DepthMode.cs b/Ryujinx.Graphics.GAL/DepthMode.cs new file mode 100644 index 0000000000..aafbb65a61 --- /dev/null +++ b/Ryujinx.Graphics.GAL/DepthMode.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Graphics.GAL +{ + public enum DepthMode + { + MinusOneToOne, + ZeroToOne + } +} \ No newline at end of file diff --git a/Ryujinx.Graphics.GAL/IPipeline.cs b/Ryujinx.Graphics.GAL/IPipeline.cs index 7706068955..7211fbe08e 100644 --- a/Ryujinx.Graphics.GAL/IPipeline.cs +++ b/Ryujinx.Graphics.GAL/IPipeline.cs @@ -49,6 +49,8 @@ namespace Ryujinx.Graphics.GAL void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp); + void SetDepthMode(DepthMode mode); + void SetDepthTest(DepthTestDescriptor depthTest); void SetFaceCulling(bool enable, Face face); diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs index 29360cf9cb..0fa3514f07 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs @@ -102,7 +102,7 @@ namespace Ryujinx.Graphics.Gpu.Engine UpdateDepthTestState(state); } - if (state.QueryModified(MethodOffset.ViewportTransform, MethodOffset.ViewportExtents)) + if (state.QueryModified(MethodOffset.DepthMode, MethodOffset.ViewportTransform, MethodOffset.ViewportExtents)) { UpdateViewportTransform(state); } @@ -294,6 +294,10 @@ namespace Ryujinx.Graphics.Gpu.Engine private void UpdateViewportTransform(GpuState state) { + DepthMode depthMode = state.Get(MethodOffset.DepthMode); + + _context.Renderer.Pipeline.SetDepthMode(depthMode); + bool transformEnable = GetViewportTransformEnable(state); bool flipY = (state.Get(MethodOffset.YControl) & 1) != 0; diff --git a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs index 93cd6f0636..5e43eb5182 100644 --- a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs +++ b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs @@ -21,6 +21,7 @@ namespace Ryujinx.Graphics.Gpu.State ViewportTransform = 0x280, ViewportExtents = 0x300, VertexBufferDrawState = 0x35d, + DepthMode = 0x35f, ClearColors = 0x360, ClearDepthValue = 0x364, ClearStencilValue = 0x368, diff --git a/Ryujinx.Graphics.OpenGL/Converters/DepthModeConverter.cs b/Ryujinx.Graphics.OpenGL/Converters/DepthModeConverter.cs new file mode 100644 index 0000000000..a02f69d23a --- /dev/null +++ b/Ryujinx.Graphics.OpenGL/Converters/DepthModeConverter.cs @@ -0,0 +1,20 @@ +using OpenTK.Graphics.OpenGL; +using Ryujinx.Graphics.GAL; +using System; + +namespace Ryujinx.Graphics.OpenGL +{ + static class DepthModeConverter + { + public static ClipDepthMode Convert(this DepthMode mode) + { + switch (mode) + { + case DepthMode.MinusOneToOne: return ClipDepthMode.NegativeOneToOne; + case DepthMode.ZeroToOne: return ClipDepthMode.ZeroToOne; + } + + throw new ArgumentException($"Invalid depth mode \"{mode}\"."); + } + } +} diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs index 4eb94097f9..9b1fec336f 100644 --- a/Ryujinx.Graphics.OpenGL/Pipeline.cs +++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs @@ -30,13 +30,15 @@ namespace Ryujinx.Graphics.OpenGL private TextureView _unit0Texture; - private ClipOrigin _clipOrigin; + private ClipOrigin _clipOrigin; + private ClipDepthMode _clipDepthMode; private uint[] _componentMasks; internal Pipeline() { - _clipOrigin = ClipOrigin.LowerLeft; + _clipOrigin = ClipOrigin.LowerLeft; + _clipDepthMode = ClipDepthMode.NegativeOneToOne; } public void BindBlendState(int index, BlendDescriptor blend) @@ -646,6 +648,18 @@ namespace Ryujinx.Graphics.OpenGL // GL.PolygonOffsetClamp(factor, units, clamp); } + public void SetDepthMode(DepthMode mode) + { + ClipDepthMode depthMode = mode.Convert(); + + if (_clipDepthMode != depthMode) + { + _clipDepthMode = depthMode; + + GL.ClipControl(_clipOrigin, depthMode); + } + } + public void SetDepthTest(DepthTestDescriptor depthTest) { GL.DepthFunc((DepthFunction)depthTest.Func.Convert()); @@ -828,7 +842,7 @@ namespace Ryujinx.Graphics.OpenGL { _clipOrigin = origin; - GL.ClipControl(origin, ClipDepthMode.NegativeOneToOne); + GL.ClipControl(origin, _clipDepthMode); } } diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs index 32c90c2d4a..5a84ff4903 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs @@ -26,6 +26,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl context.AppendLine("#extension GL_ARB_compute_shader : enable"); } + context.AppendLine("#pragma optionNV(fastmath off)"); + context.AppendLine(); context.AppendLine($"const int {DefaultNames.UndefinedName} = 0;");