aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs12
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs40
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs2
-rw-r--r--Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs12
-rw-r--r--Ryujinx.Graphics.Shader/StructuredIr/InstructionInfo.cs12
-rw-r--r--Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs40
-rw-r--r--Ryujinx.Graphics.Shader/Translation/Rewriter.cs6
7 files changed, 90 insertions, 34 deletions
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs
index 1fa25399..a52e70c3 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenHelper.cs
@@ -53,10 +53,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
Add(Instruction.ConditionalSelect, InstType.OpTernary, "?:", 12);
Add(Instruction.ConvertFP32ToFP64, InstType.CallUnary, "double");
Add(Instruction.ConvertFP64ToFP32, InstType.CallUnary, "float");
- 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.ConvertFP32ToS32, InstType.CallUnary, "int");
+ Add(Instruction.ConvertFP32ToU32, InstType.CallUnary, "uint");
+ Add(Instruction.ConvertFP64ToS32, InstType.CallUnary, "int");
+ Add(Instruction.ConvertFP64ToU32, InstType.CallUnary, "uint");
+ Add(Instruction.ConvertS32ToFP32, InstType.CallUnary, "float");
+ Add(Instruction.ConvertS32ToFP64, InstType.CallUnary, "double");
+ Add(Instruction.ConvertU32ToFP32, InstType.CallUnary, "float");
+ Add(Instruction.ConvertU32ToFP64, InstType.CallUnary, "double");
Add(Instruction.Cosine, InstType.CallUnary, "cos");
Add(Instruction.Ddx, InstType.CallUnary, "dFdx");
Add(Instruction.Ddy, InstType.CallUnary, "dFdy");
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs
index 01cdc445..62124554 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs
@@ -179,27 +179,40 @@ namespace Ryujinx.Graphics.Shader.Instructions
return;
}
+ Instruction fpType = srcType.ToInstFPType();
+
bool isSignedInt = dstType == IDstFmt.S16 || dstType == IDstFmt.S32 || dstType == IDstFmt.S64;
bool isSmallInt = dstType == IDstFmt.U16 || dstType == IDstFmt.S16;
- Operand srcB = context.FPAbsNeg(src, absolute, negate);
+ Operand srcB = context.FPAbsNeg(src, absolute, negate, fpType);
srcB = roundingMode switch
{
- RoundMode2.Round => context.FPRound(srcB),
- RoundMode2.Floor => context.FPFloor(srcB),
- RoundMode2.Ceil => context.FPCeiling(srcB),
- RoundMode2.Trunc => context.FPTruncate(srcB),
+ RoundMode2.Round => context.FPRound(srcB, fpType),
+ RoundMode2.Floor => context.FPFloor(srcB, fpType),
+ RoundMode2.Ceil => context.FPCeiling(srcB, fpType),
+ RoundMode2.Trunc => context.FPTruncate(srcB, fpType),
_ => srcB
};
if (!isSignedInt)
{
// Negative float to uint cast is undefined, so we clamp the value before conversion.
- srcB = context.FPMaximum(srcB, ConstF(0));
+ srcB = context.FPMaximum(srcB, ConstF(0), fpType);
}
- srcB = isSignedInt ? context.FPConvertToS32(srcB) : context.FPConvertToU32(srcB);
+ if (srcType == DstFmt.F64)
+ {
+ srcB = isSignedInt
+ ? context.FP64ConvertToS32(srcB)
+ : context.FP64ConvertToU32(srcB);
+ }
+ else
+ {
+ srcB = isSignedInt
+ ? context.FP32ConvertToS32(srcB)
+ : context.FP32ConvertToU32(srcB);
+ }
if (isSmallInt)
{
@@ -252,7 +265,18 @@ namespace Ryujinx.Graphics.Shader.Instructions
: context.BitfieldExtractU32(srcB, Const((int)byteSelection * 8), Const(size));
}
- srcB = isSignedInt ? context.IConvertS32ToFP(srcB) : context.IConvertU32ToFP(srcB);
+ if (dstType == DstFmt.F64)
+ {
+ srcB = isSignedInt
+ ? context.IConvertS32ToFP64(srcB)
+ : context.IConvertU32ToFP64(srcB);
+ }
+ else
+ {
+ srcB = isSignedInt
+ ? context.IConvertS32ToFP32(srcB)
+ : context.IConvertU32ToFP32(srcB);
+ }
WriteFP(context, dstType, srcB, rd);
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
index ba1fdf17..33cc6af7 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
@@ -939,7 +939,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
tempDest = context.FPMultiply(tempDest, ConstF(256.0f));
- Operand fixedPointValue = context.FPConvertToS32(tempDest);
+ Operand fixedPointValue = context.FP32ConvertToS32(tempDest);
context.Copy(GetDest(), fixedPointValue);
}
diff --git a/Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs b/Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs
index 791c8f11..c3fb2882 100644
--- a/Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs
+++ b/Ryujinx.Graphics.Shader/IntermediateRepresentation/Instruction.cs
@@ -49,10 +49,14 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
ConditionalSelect,
ConvertFP32ToFP64,
ConvertFP64ToFP32,
- ConvertFPToS32,
- ConvertFPToU32,
- ConvertS32ToFP,
- ConvertU32ToFP,
+ ConvertFP32ToS32,
+ ConvertFP32ToU32,
+ ConvertFP64ToS32,
+ ConvertFP64ToU32,
+ ConvertS32ToFP32,
+ ConvertS32ToFP64,
+ ConvertU32ToFP32,
+ ConvertU32ToFP64,
Copy,
Cosine,
Ddx,
diff --git a/Ryujinx.Graphics.Shader/StructuredIr/InstructionInfo.cs b/Ryujinx.Graphics.Shader/StructuredIr/InstructionInfo.cs
index c647f450..f3397ada 100644
--- a/Ryujinx.Graphics.Shader/StructuredIr/InstructionInfo.cs
+++ b/Ryujinx.Graphics.Shader/StructuredIr/InstructionInfo.cs
@@ -66,10 +66,14 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
Add(Instruction.ConditionalSelect, VariableType.Scalar, VariableType.Bool, VariableType.Scalar, VariableType.Scalar);
Add(Instruction.ConvertFP32ToFP64, VariableType.F64, VariableType.F32);
Add(Instruction.ConvertFP64ToFP32, VariableType.F32, VariableType.F64);
- 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.ConvertFP32ToS32, VariableType.S32, VariableType.F32);
+ Add(Instruction.ConvertFP32ToU32, VariableType.U32, VariableType.F32);
+ Add(Instruction.ConvertFP64ToS32, VariableType.S32, VariableType.F64);
+ Add(Instruction.ConvertFP64ToU32, VariableType.U32, VariableType.F64);
+ Add(Instruction.ConvertS32ToFP32, VariableType.F32, VariableType.S32);
+ Add(Instruction.ConvertS32ToFP64, VariableType.F64, VariableType.S32);
+ Add(Instruction.ConvertU32ToFP32, VariableType.F32, VariableType.U32);
+ Add(Instruction.ConvertU32ToFP64, VariableType.F64, VariableType.U32);
Add(Instruction.Cosine, VariableType.Scalar, VariableType.Scalar);
Add(Instruction.Ddx, VariableType.F32, VariableType.F32);
Add(Instruction.Ddy, VariableType.F32, VariableType.F32);
diff --git a/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs b/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs
index 5e607b44..6baf33e1 100644
--- a/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs
+++ b/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs
@@ -241,14 +241,24 @@ namespace Ryujinx.Graphics.Shader.Translation
return context.Add(fpType | Instruction.CompareLess, Local(), a, b);
}
- public static Operand FPConvertToS32(this EmitterContext context, Operand a)
+ public static Operand FP32ConvertToS32(this EmitterContext context, Operand a)
{
- return context.Add(Instruction.ConvertFPToS32, Local(), a);
+ return context.Add(Instruction.ConvertFP32ToS32, Local(), a);
}
- public static Operand FPConvertToU32(this EmitterContext context, Operand a)
+ public static Operand FP32ConvertToU32(this EmitterContext context, Operand a)
{
- return context.Add(Instruction.ConvertFPToU32, Local(), a);
+ return context.Add(Instruction.ConvertFP32ToU32, Local(), a);
+ }
+
+ public static Operand FP64ConvertToS32(this EmitterContext context, Operand a)
+ {
+ return context.Add(Instruction.ConvertFP64ToS32, Local(), a);
+ }
+
+ public static Operand FP64ConvertToU32(this EmitterContext context, Operand a)
+ {
+ return context.Add(Instruction.ConvertFP64ToU32, Local(), a);
}
public static Operand FPCosine(this EmitterContext context, Operand a)
@@ -281,9 +291,9 @@ namespace Ryujinx.Graphics.Shader.Translation
return context.Add(Instruction.FP32 | Instruction.LogarithmB2, Local(), a);
}
- public static Operand FPMaximum(this EmitterContext context, Operand a, Operand b)
+ public static Operand FPMaximum(this EmitterContext context, Operand a, Operand b, Instruction fpType = Instruction.FP32)
{
- return context.Add(Instruction.FP32 | Instruction.Maximum, Local(), a, b);
+ return context.Add(fpType | Instruction.Maximum, Local(), a, b);
}
public static Operand FPMinimum(this EmitterContext context, Operand a, Operand b)
@@ -461,14 +471,24 @@ namespace Ryujinx.Graphics.Shader.Translation
return context.Add(Instruction.CompareNotEqual, Local(), a, b);
}
- public static Operand IConvertS32ToFP(this EmitterContext context, Operand a)
+ public static Operand IConvertS32ToFP32(this EmitterContext context, Operand a)
+ {
+ return context.Add(Instruction.ConvertS32ToFP32, Local(), a);
+ }
+
+ public static Operand IConvertS32ToFP64(this EmitterContext context, Operand a)
+ {
+ return context.Add(Instruction.ConvertS32ToFP64, Local(), a);
+ }
+
+ public static Operand IConvertU32ToFP32(this EmitterContext context, Operand a)
{
- return context.Add(Instruction.ConvertS32ToFP, Local(), a);
+ return context.Add(Instruction.ConvertU32ToFP32, Local(), a);
}
- public static Operand IConvertU32ToFP(this EmitterContext context, Operand a)
+ public static Operand IConvertU32ToFP64(this EmitterContext context, Operand a)
{
- return context.Add(Instruction.ConvertU32ToFP, Local(), a);
+ return context.Add(Instruction.ConvertU32ToFP64, Local(), a);
}
public static Operand IMaximumS32(this EmitterContext context, Operand a, Operand b)
diff --git a/Ryujinx.Graphics.Shader/Translation/Rewriter.cs b/Ryujinx.Graphics.Shader/Translation/Rewriter.cs
index 02a0feda..910faf1c 100644
--- a/Ryujinx.Graphics.Shader/Translation/Rewriter.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Rewriter.cs
@@ -286,7 +286,7 @@ namespace Ryujinx.Graphics.Shader.Translation
{
Operand res = Local();
- node.List.AddBefore(node, new Operation(Instruction.ConvertFPToS32, res, value));
+ node.List.AddBefore(node, new Operation(Instruction.ConvertFP32ToS32, res, value));
return res;
}
@@ -295,7 +295,7 @@ namespace Ryujinx.Graphics.Shader.Translation
{
Operand res = Local();
- node.List.AddBefore(node, new Operation(Instruction.ConvertS32ToFP, res, value));
+ node.List.AddBefore(node, new Operation(Instruction.ConvertS32ToFP32, res, value));
return res;
}
@@ -501,7 +501,7 @@ namespace Ryujinx.Graphics.Shader.Translation
// as replacement for SNORM (which is not supported).
INode[] uses = texOp.Dest.UseOps.ToArray();
- Operation convOp = new Operation(Instruction.ConvertS32ToFP, Local(), texOp.Dest);
+ Operation convOp = new Operation(Instruction.ConvertS32ToFP32, Local(), texOp.Dest);
Operation normOp = new Operation(Instruction.FP32 | Instruction.Multiply, Local(), convOp.Dest, ConstF(1f / maxPositive));
node = node.List.AddAfter(node, convOp);