Ver código fonte

Add FaceAttr in GLSL, unmanaged case in EmitTex and ConstantColorG80 blend factor (#207)

* Add FaceAttr (0x3fc) input attribute in GLSL

* Implement unmanaged case in EmitTex

* Add ConstantColor for 0xC001 (G80) from PR #145
ReinUsesLisp 7 anos atrás
pai
commit
9cbf908cf5

+ 2 - 1
Ryujinx.Graphics/Gal/GalBlendFactor.cs

@@ -20,6 +20,7 @@ namespace Ryujinx.Graphics.Gal
         ConstantColor         = 0x61,
         OneMinusConstantColor = 0x62,
         ConstantAlpha         = 0x63,
-        OneMinusConstantAlpha = 0x64
+        OneMinusConstantAlpha = 0x64,
+        ConstantColorG80      = 0xc001
     }
 }

+ 4 - 1
Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs

@@ -187,7 +187,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
                 case GalBlendFactor.OneMinusSrcAlpha:      return BlendingFactor.OneMinusSrcAlpha;
                 case GalBlendFactor.DstAlpha:              return BlendingFactor.DstAlpha;
                 case GalBlendFactor.OneMinusDstAlpha:      return BlendingFactor.OneMinusDstAlpha;
-                case GalBlendFactor.ConstantColor:         return BlendingFactor.ConstantColor;
                 case GalBlendFactor.OneMinusConstantColor: return BlendingFactor.OneMinusConstantColor;
                 case GalBlendFactor.ConstantAlpha:         return BlendingFactor.ConstantAlpha;
                 case GalBlendFactor.OneMinusConstantAlpha: return BlendingFactor.OneMinusConstantAlpha;
@@ -196,6 +195,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL
                 case GalBlendFactor.OneMinusSrc1Color:     return (BlendingFactor)BlendingFactorSrc.OneMinusSrc1Color;
                 case GalBlendFactor.Src1Alpha:             return BlendingFactor.Src1Alpha;
                 case GalBlendFactor.OneMinusSrc1Alpha:     return (BlendingFactor)BlendingFactorSrc.OneMinusSrc1Alpha;
+
+                case GalBlendFactor.ConstantColor:
+                case GalBlendFactor.ConstantColorG80:
+                    return BlendingFactor.ConstantColor;
             }
 
             throw new ArgumentException(nameof(BlendFactor));

+ 3 - 1
Ryujinx.Graphics/Gal/Shader/GlslDecl.cs

@@ -9,6 +9,7 @@ namespace Ryujinx.Graphics.Gal.Shader
         public const int TessCoordAttrZ  = 0x2f8;
         public const int InstanceIdAttr  = 0x2f8;
         public const int VertexIdAttr    = 0x2fc;
+        public const int FaceAttr        = 0x3fc;
         public const int GlPositionWAttr = 0x7c;
 
         public const int MaxUboSize = 1024;
@@ -208,7 +209,8 @@ namespace Ryujinx.Graphics.Gal.Shader
                 {
                     //This is a built-in input variable.
                     if (Abuf.Offs == VertexIdAttr ||
-                        Abuf.Offs == InstanceIdAttr)
+                        Abuf.Offs == InstanceIdAttr ||
+                        Abuf.Offs == FaceAttr)
                     {
                         break;
                     }

+ 10 - 1
Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs

@@ -658,6 +658,14 @@ namespace Ryujinx.Graphics.Gal.Shader
                     case GlslDecl.TessCoordAttrZ: return "gl_TessCoord.z";
                 }
             }
+            else if (Decl.ShaderType == GalShaderType.Fragment)
+            {
+                switch (Abuf.Offs)
+                {
+                    //Note: It's a guess that Maxwell's face is 1 when gl_FrontFacing == true
+                    case GlslDecl.FaceAttr: return "(gl_FrontFacing ? 1 : 0)";
+                }
+            }
 
             return GetAttrTempName(Abuf);
         }
@@ -1084,7 +1092,8 @@ namespace Ryujinx.Graphics.Gal.Shader
             {
                 case ShaderIrOperAbuf Abuf:
                     return Abuf.Offs == GlslDecl.VertexIdAttr ||
-                           Abuf.Offs == GlslDecl.InstanceIdAttr
+                           Abuf.Offs == GlslDecl.InstanceIdAttr ||
+                           Abuf.Offs == GlslDecl.FaceAttr
                         ? OperType.I32
                         : OperType.F32;
 

+ 27 - 12
Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs

@@ -8,6 +8,29 @@ namespace Ryujinx.Graphics.Gal.Shader
     {
         private const int TempRegStart = 0x100;
 
+        private const int ____ = 0x0;
+        private const int R___ = 0x1;
+        private const int _G__ = 0x2;
+        private const int RG__ = 0x3;
+        private const int __B_ = 0x4;
+        private const int RGB_ = 0x7;
+        private const int ___A = 0x8;
+        private const int R__A = 0x9;
+        private const int _G_A = 0xa;
+        private const int RG_A = 0xb;
+        private const int __BA = 0xc;
+        private const int R_BA = 0xd;
+        private const int _GBA = 0xe;
+        private const int RGBA = 0xf;
+
+        private static int[,] MaskLut = new int[,]
+        {
+            { ____, ____, ____, ____, ____, ____, ____, ____ },
+            { R___, _G__, __B_, ___A, RG__, ____, ____, ____ },
+            { R___, _G__, __B_, ___A, RG__, R__A, _G_A, __BA },
+            { RGB_, RG_A, R_BA, _GBA, RGBA, ____, ____, ____ }
+        };
+
         public static void Ld_A(ShaderIrBlock Block, long OpCode)
         {
             ShaderIrNode[] Opers = GetOperAbuf20(OpCode);
@@ -167,20 +190,12 @@ namespace Ryujinx.Graphics.Gal.Shader
             ShaderIrNode OperB = GetOperGpr20   (OpCode);
             ShaderIrNode OperC = GetOperImm13_36(OpCode);
 
-            bool TwoDests = GetOperGpr28(OpCode).Index != ShaderIrOperGpr.ZRIndex;
+            int LutIndex;
 
-            int ChMask;
+            LutIndex = GetOperGpr0(OpCode).Index != ShaderIrOperGpr.ZRIndex ? 1 : 0;
+            LutIndex |= GetOperGpr28(OpCode).Index != ShaderIrOperGpr.ZRIndex ? 2 : 0;
 
-            switch ((OpCode >> 50) & 7)
-            {
-                case 0: ChMask = TwoDests ? 0x7 : 0x1; break;
-                case 1: ChMask = TwoDests ? 0xb : 0x2; break;
-                case 2: ChMask = TwoDests ? 0xd : 0x4; break;
-                case 3: ChMask = TwoDests ? 0xe : 0x8; break;
-                case 4: ChMask = TwoDests ? 0xf : 0x3; break;
-
-                default: throw new InvalidOperationException();
-            }
+            int ChMask = MaskLut[LutIndex, (OpCode >> 50) & 7];
 
             for (int Ch = 0; Ch < 4; Ch++)
             {