From 2f37583ab3b49aa5064a72c8d3b4e8245ebb6b5b Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Sat, 14 Jul 2018 13:08:39 -0300
Subject: [PATCH] Some small shader related fixes (#258)

* Some small shader related fixes

* Address PR feedback
---
 Ryujinx.Graphics/Gal/IGalShader.cs            |  2 ++
 Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs      | 12 +++++++
 Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs | 31 +++++++++++++------
 Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs      | 10 +++---
 Ryujinx.HLE/Gpu/Texture/TextureHelper.cs      | 28 ++++++++---------
 Ryujinx.HLE/Gpu/Texture/TextureReader.cs      |  2 +-
 6 files changed, 57 insertions(+), 28 deletions(-)

diff --git a/Ryujinx.Graphics/Gal/IGalShader.cs b/Ryujinx.Graphics/Gal/IGalShader.cs
index 06f3fac979..9adaceaf50 100644
--- a/Ryujinx.Graphics/Gal/IGalShader.cs
+++ b/Ryujinx.Graphics/Gal/IGalShader.cs
@@ -18,6 +18,8 @@ namespace Ryujinx.Graphics.Gal
 
         void Bind(long Key);
 
+        void Unbind(GalShaderType Type);
+
         void BindProgram();
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs
index 3c5c874eaa..c55a758b4a 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs
@@ -203,6 +203,18 @@ namespace Ryujinx.Graphics.Gal.OpenGL
             }
         }
 
+        public void Unbind(GalShaderType Type)
+        {
+            switch (Type)
+            {
+                case GalShaderType.Vertex:         Current.Vertex         = null; break;
+                case GalShaderType.TessControl:    Current.TessControl    = null; break;
+                case GalShaderType.TessEvaluation: Current.TessEvaluation = null; break;
+                case GalShaderType.Geometry:       Current.Geometry       = null; break;
+                case GalShaderType.Fragment:       Current.Fragment       = null; break;
+            }
+        }
+
         public void BindProgram()
         {
             if (Current.Vertex   == null ||
diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs
index f3075a504e..575fb72f9a 100644
--- a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs
+++ b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs
@@ -216,7 +216,7 @@ namespace Ryujinx.Graphics.Gal.Shader
 
         private void PrintDeclOutAttributes()
         {
-            if (Decl.ShaderType == GalShaderType.Vertex)
+            if (Decl.ShaderType != GalShaderType.Fragment)
             {
                 SB.AppendLine("layout (location = " + GlslDecl.PositionOutAttrLocation + ") out vec4 " + GlslDecl.PositionOutAttrName + ";");
             }
@@ -337,7 +337,10 @@ namespace Ryujinx.Graphics.Gal.Shader
             if (Decl.ShaderType == GalShaderType.Vertex)
             {
                 SB.AppendLine(IdentationStr + "gl_Position.xy *= " + GlslDecl.FlipUniformName + ";");
+            }
 
+            if (Decl.ShaderType != GalShaderType.Fragment)
+            {
                 SB.AppendLine(IdentationStr + GlslDecl.PositionOutAttrName + " = gl_Position;");
                 SB.AppendLine(IdentationStr + GlslDecl.PositionOutAttrName + ".w = 1;");
             }
@@ -598,9 +601,6 @@ namespace Ryujinx.Graphics.Gal.Shader
         {
             switch (Op.Inst)
             {
-                case ShaderIrInst.Frcp:
-                    return true;
-
                 case ShaderIrInst.Ipa:
                 case ShaderIrInst.Texq:
                 case ShaderIrInst.Texs:
@@ -608,8 +608,7 @@ namespace Ryujinx.Graphics.Gal.Shader
                     return false;
             }
 
-            return Op.OperandB != null ||
-                   Op.OperandC != null;
+            return true;
         }
 
         private string GetName(ShaderIrOperCbuf Cbuf)
@@ -711,13 +710,13 @@ namespace Ryujinx.Graphics.Gal.Shader
             }
             else
             {
-                return Imm.Value.ToString(CultureInfo.InvariantCulture);
+                return GetIntConst(Imm.Value);
             }
         }
 
         private string GetValue(ShaderIrOperImmf Immf)
         {
-            return Immf.Value.ToString(CultureInfo.InvariantCulture);
+            return GetFloatConst(Immf.Value);
         }
 
         private string GetName(ShaderIrOperPred Pred)
@@ -1047,7 +1046,7 @@ namespace Ryujinx.Graphics.Gal.Shader
 
                             if (!float.IsNaN(Value) && !float.IsInfinity(Value))
                             {
-                                return Value.ToString(CultureInfo.InvariantCulture);
+                                return GetFloatConst(Value);
                             }
                         }
                         break;
@@ -1064,6 +1063,20 @@ namespace Ryujinx.Graphics.Gal.Shader
             return Expr;
         }
 
+        private static string GetIntConst(int Value)
+        {
+            string Expr = Value.ToString(CultureInfo.InvariantCulture);
+
+            return Value < 0 ? "(" + Expr + ")" : Expr;
+        }
+
+        private static string GetFloatConst(float Value)
+        {
+            string Expr = Value.ToString(CultureInfo.InvariantCulture);
+
+            return Value < 0 ? "(" + Expr + ")" : Expr;
+        }
+
         private static OperType GetDstNodeType(ShaderIrNode Node)
         {
             //Special case instructions with the result type different
diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs
index 2bacd71b36..5c474ab0bc 100644
--- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs
+++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs
@@ -172,6 +172,8 @@ namespace Ryujinx.HLE.Gpu.Engines
 
             for (; Index < 6; Index++)
             {
+                GalShaderType Type = GetTypeFromProgram(Index);
+
                 int Control = ReadRegister(NvGpuEngine3dReg.ShaderNControl + Index * 0x10);
                 int Offset  = ReadRegister(NvGpuEngine3dReg.ShaderNOffset  + Index * 0x10);
 
@@ -180,16 +182,16 @@ namespace Ryujinx.HLE.Gpu.Engines
 
                 if (!Enable)
                 {
+                    Gpu.Renderer.Shader.Unbind(Type);
+
                     continue;
                 }
 
                 long Key = BasePosition + (uint)Offset;
 
-                GalShaderType ShaderType = GetTypeFromProgram(Index);
+                Keys[(int)Type] = Key;
 
-                Keys[(int)ShaderType] = Key;
-
-                Gpu.Renderer.Shader.Create(Vmm, Key, ShaderType);
+                Gpu.Renderer.Shader.Create(Vmm, Key, Type);
                 Gpu.Renderer.Shader.Bind(Key);
             }
 
diff --git a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs
index 6b9a306355..c0749d6a25 100644
--- a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs
+++ b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs
@@ -62,67 +62,67 @@ namespace Ryujinx.HLE.Gpu.Texture
                 {
                     return CompressedTextureSize(Texture.Width, Texture.Height, 4, 4, 16);
                 }
-                    
+
                 case GalTextureFormat.Astc2D5x5:
                 {
                     return CompressedTextureSize(Texture.Width, Texture.Height, 5, 5, 16);
                 }
-                
+
                 case GalTextureFormat.Astc2D6x6:
                 {
                     return CompressedTextureSize(Texture.Width, Texture.Height, 6, 6, 16);
                 }
-                    
+
                 case GalTextureFormat.Astc2D8x8:
                 {
                     return CompressedTextureSize(Texture.Width, Texture.Height, 8, 8, 16);
                 }
-                    
+
                 case GalTextureFormat.Astc2D10x10:
                 {
                     return CompressedTextureSize(Texture.Width, Texture.Height, 10, 10, 16);
                 }
-                    
+
                 case GalTextureFormat.Astc2D12x12:
                 {
                     return CompressedTextureSize(Texture.Width, Texture.Height, 12, 12, 16);
                 }
-                
+
                 case GalTextureFormat.Astc2D5x4:
                 {
                     return CompressedTextureSize(Texture.Width, Texture.Height, 5, 4, 16);
                 }
-				
+
                 case GalTextureFormat.Astc2D6x5:
                 {
                     return CompressedTextureSize(Texture.Width, Texture.Height, 6, 5, 16);
                 }
-				
+
                 case GalTextureFormat.Astc2D8x6:
                 {
                     return CompressedTextureSize(Texture.Width, Texture.Height, 8, 6, 16);
                 }
-				
+
                 case GalTextureFormat.Astc2D10x8:
                 {
                     return CompressedTextureSize(Texture.Width, Texture.Height, 10, 8, 16);
                 }
-				
+
                 case GalTextureFormat.Astc2D12x10:
                 {
                     return CompressedTextureSize(Texture.Width, Texture.Height, 12, 10, 16);
                 }
-				
+
                 case GalTextureFormat.Astc2D8x5:
                 {
                     return CompressedTextureSize(Texture.Width, Texture.Height, 8, 5, 16);
                 }
-				
+
                 case GalTextureFormat.Astc2D10x5:
                 {
                     return CompressedTextureSize(Texture.Width, Texture.Height, 10, 5, 16);
                 }
-				
+
                 case GalTextureFormat.Astc2D10x6:
                 {
                     return CompressedTextureSize(Texture.Width, Texture.Height, 10, 6, 16);
@@ -139,7 +139,7 @@ namespace Ryujinx.HLE.Gpu.Texture
 
             return W * H * Bpb;
         }
-        
+
         public static (AMemory Memory, long Position) GetMemoryAndPosition(
             IAMemory Memory,
             long     Position)
diff --git a/Ryujinx.HLE/Gpu/Texture/TextureReader.cs b/Ryujinx.HLE/Gpu/Texture/TextureReader.cs
index 8bd4dbcbaa..6c08cd6c4d 100644
--- a/Ryujinx.HLE/Gpu/Texture/TextureReader.cs
+++ b/Ryujinx.HLE/Gpu/Texture/TextureReader.cs
@@ -30,7 +30,7 @@ namespace Ryujinx.HLE.Gpu.Texture
                 case GalTextureFormat.Astc2D5x5:    return Read16BptCompressedTexture(Memory, Texture, 5, 5);
                 case GalTextureFormat.Astc2D6x6:    return Read16BptCompressedTexture(Memory, Texture, 6, 6);
                 case GalTextureFormat.Astc2D8x8:    return Read16BptCompressedTexture(Memory, Texture, 8, 8);
-                case GalTextureFormat.Astc2D10x10:  return Read16BptCompressedTexture(Memory, Texture, 10, 10); 
+                case GalTextureFormat.Astc2D10x10:  return Read16BptCompressedTexture(Memory, Texture, 10, 10);
                 case GalTextureFormat.Astc2D12x12:  return Read16BptCompressedTexture(Memory, Texture, 12, 12);
                 case GalTextureFormat.Astc2D5x4:    return Read16BptCompressedTexture(Memory, Texture, 5, 4);
                 case GalTextureFormat.Astc2D6x5:    return Read16BptCompressedTexture(Memory, Texture, 6, 5);