Bläddra i källkod

Support depth clip mode and disable shader fast math optimization on NVIDIA as a workaround for compiler bugs (?)

gdkchan 6 år sedan
förälder
incheckning
7ce5584f9e

+ 8 - 0
Ryujinx.Graphics.GAL/DepthMode.cs

@@ -0,0 +1,8 @@
+namespace Ryujinx.Graphics.GAL
+{
+    public enum DepthMode
+    {
+        MinusOneToOne,
+        ZeroToOne
+    }
+}

+ 2 - 0
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);

+ 5 - 1
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<DepthMode>(MethodOffset.DepthMode);
+
+            _context.Renderer.Pipeline.SetDepthMode(depthMode);
+
             bool transformEnable = GetViewportTransformEnable(state);
 
             bool flipY = (state.Get<int>(MethodOffset.YControl) & 1) != 0;

+ 1 - 0
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,

+ 20 - 0
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}\".");
+        }
+    }
+}

+ 17 - 3
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);
             }
         }
 

+ 2 - 0
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;");