Răsfoiți Sursa

Add R2P shader instruction

gdk 6 ani în urmă
părinte
comite
6a8ba6d600

+ 3 - 0
Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs

@@ -143,6 +143,9 @@ namespace Ryujinx.Graphics.Shader.Decoders
             Set("0011100x00001x", InstEmit.Popc,    typeof(OpCodeAluImm));
             Set("0011100x00001x", InstEmit.Popc,    typeof(OpCodeAluImm));
             Set("0101110000001x", InstEmit.Popc,    typeof(OpCodeAluReg));
             Set("0101110000001x", InstEmit.Popc,    typeof(OpCodeAluReg));
             Set("0101000010010x", InstEmit.Psetp,   typeof(OpCodePsetp));
             Set("0101000010010x", InstEmit.Psetp,   typeof(OpCodePsetp));
+            Set("0100110011110x", InstEmit.R2p,     typeof(OpCodeAluCbuf));
+            Set("0011100x11110x", InstEmit.R2p,     typeof(OpCodeAluImm));
+            Set("0101110011110x", InstEmit.R2p,     typeof(OpCodeAluReg));
             Set("1110101111111x", InstEmit.Red,     typeof(OpCodeRed));
             Set("1110101111111x", InstEmit.Red,     typeof(OpCodeRed));
             Set("0100110010010x", InstEmit.Rro,     typeof(OpCodeFArithCbuf));
             Set("0100110010010x", InstEmit.Rro,     typeof(OpCodeFArithCbuf));
             Set("0011100x10010x", InstEmit.Rro,     typeof(OpCodeFArithImm));
             Set("0011100x10010x", InstEmit.Rro,     typeof(OpCodeFArithImm));

+ 1 - 1
Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs

@@ -213,7 +213,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
             Operand        mem,
             Operand        mem,
             Operand        value)
             Operand        value)
         {
         {
-            Operand res = null;
+            Operand res = Const(0);
 
 
             switch (op)
             switch (op)
             {
             {

+ 32 - 0
Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs

@@ -16,6 +16,38 @@ namespace Ryujinx.Graphics.Shader.Instructions
             context.Copy(GetDest(context), GetSrcB(context));
             context.Copy(GetDest(context), GetSrcB(context));
         }
         }
 
 
+        public static void R2p(EmitterContext context)
+        {
+            OpCodeAlu op = (OpCodeAlu)context.CurrOp;
+
+            bool isCC  = op.RawOpCode.Extract(40);
+            int  shift = op.RawOpCode.Extract(41, 2) * 8;
+
+            Operand value = GetSrcA(context);
+            Operand mask  = GetSrcB(context);
+
+            Operand Test(Operand value, int bit)
+            {
+                return context.ICompareNotEqual(context.BitwiseAnd(value, Const(1 << bit)), Const(0));
+            }
+
+            if (isCC)
+            {
+                // TODO.
+            }
+            else
+            {
+                for (int bit = 0; bit < 7; bit++)
+                {
+                    Operand pred = Register(bit, RegisterType.Predicate);
+
+                    Operand res = context.ConditionalSelect(Test(mask, bit), Test(value, bit + shift), pred);
+
+                    context.Copy(pred, res);
+                }
+            }
+        }
+
         public static void S2r(EmitterContext context)
         public static void S2r(EmitterContext context)
         {
         {
             // TODO: Better impl.
             // TODO: Better impl.