Sfoglia il codice sorgente

Simplified F2I shader instruction codegen

gdk 6 anni fa
parent
commit
99f236fcf0

+ 1 - 0
Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs

@@ -50,6 +50,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
             Add(Instruction.CompareNotEqual,          InstType.OpBinaryCom,    "!=",              5);
             Add(Instruction.ConditionalSelect,        InstType.OpTernary,      "?:",              12);
             Add(Instruction.ConvertFPToS32,           InstType.CallUnary,      "int");
+            Add(Instruction.ConvertFPToU32,           InstType.CallUnary,      "uint");
             Add(Instruction.ConvertS32ToFP,           InstType.CallUnary,      "float");
             Add(Instruction.ConvertU32ToFP,           InstType.CallUnary,      "float");
             Add(Instruction.Cosine,                   InstType.CallUnary,      "cos");

+ 18 - 4
Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs

@@ -99,12 +99,26 @@ namespace Ryujinx.Graphics.Shader.Instructions
                     break;
             }
 
-            long min = GetIntMin(intType);
-            long max = GetIntMax(intType);
+            if (!isSignedInt)
+            {
+                // Negative float to uint cast is undefined, so we clamp
+                // the value before conversion.
+                srcB = context.FPMaximum(srcB, ConstF(0));
+            }
 
-            srcB = context.FPClamp(srcB, ConstF(min), ConstF(max));
+            srcB = isSignedInt
+                ? context.FPConvertToS32(srcB)
+                : context.FPConvertToU32(srcB);
+
+            if (isSmallInt)
+            {
+                int min = (int)GetIntMin(intType);
+                int max = (int)GetIntMax(intType);
 
-            srcB = context.FPConvertToS32(srcB);
+                srcB = isSignedInt
+                    ? context.IClampS32(srcB, Const(min), Const(max))
+                    : context.IClampU32(srcB, Const(min), Const(max));
+            }
 
             Operand dest = GetDest(context);
 

+ 1 - 0
Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs

@@ -46,6 +46,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
         CompareNotEqual,
         ConditionalSelect,
         ConvertFPToS32,
+        ConvertFPToU32,
         ConvertS32ToFP,
         ConvertU32ToFP,
         Copy,

+ 1 - 0
Ryujinx.Graphics.Shader/StructuredIr/InstructionInfo.cs

@@ -64,6 +64,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
             Add(Instruction.CompareNotEqual,          VariableType.Bool,   VariableType.Scalar, VariableType.Scalar);
             Add(Instruction.ConditionalSelect,        VariableType.Scalar, VariableType.Bool,   VariableType.Scalar, VariableType.Scalar);
             Add(Instruction.ConvertFPToS32,           VariableType.S32,    VariableType.F32);
+            Add(Instruction.ConvertFPToU32,           VariableType.U32,    VariableType.F32);
             Add(Instruction.ConvertS32ToFP,           VariableType.F32,    VariableType.S32);
             Add(Instruction.ConvertU32ToFP,           VariableType.F32,    VariableType.U32);
             Add(Instruction.Cosine,                   VariableType.Scalar, VariableType.Scalar);

+ 5 - 5
Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs

@@ -206,11 +206,6 @@ namespace Ryujinx.Graphics.Shader.Translation
             return context.Add(Instruction.FP | Instruction.Ceiling, Local(), a);
         }
 
-        public static Operand FPClamp(this EmitterContext context, Operand a, Operand b, Operand c)
-        {
-            return context.Add(Instruction.FP | Instruction.Clamp, Local(), a, b, c);
-        }
-
         public static Operand FPCompareEqual(this EmitterContext context, Operand a, Operand b)
         {
             return context.Add(Instruction.FP | Instruction.CompareEqual, Local(), a, b);
@@ -226,6 +221,11 @@ namespace Ryujinx.Graphics.Shader.Translation
             return context.Add(Instruction.ConvertFPToS32, Local(), a);
         }
 
+        public static Operand FPConvertToU32(this EmitterContext context, Operand a)
+        {
+            return context.Add(Instruction.ConvertFPToU32, Local(), a);
+        }
+
         public static Operand FPCosine(this EmitterContext context, Operand a)
         {
             return context.Add(Instruction.FP | Instruction.Cosine, Local(), a);