aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/CodeGen/Glsl/TypeConversion.cs
diff options
context:
space:
mode:
authorgdk <gab.dark.100@gmail.com>2019-10-13 03:02:07 -0300
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commit1876b346fea647e8284a66bb6d62c38801035cff (patch)
tree6eeff094298cda84d1613dc5ec0691e51d7b35f1 /Ryujinx.Graphics.Shader/CodeGen/Glsl/TypeConversion.cs
parentf617fb542a0e3d36012d77a4b5acbde7b08902f2 (diff)
Initial work
Diffstat (limited to 'Ryujinx.Graphics.Shader/CodeGen/Glsl/TypeConversion.cs')
-rw-r--r--Ryujinx.Graphics.Shader/CodeGen/Glsl/TypeConversion.cs85
1 files changed, 85 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/TypeConversion.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/TypeConversion.cs
new file mode 100644
index 00000000..7adc5ad3
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/TypeConversion.cs
@@ -0,0 +1,85 @@
+using Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.StructuredIr;
+using System;
+
+namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
+{
+ static class TypeConversion
+ {
+ public static string ReinterpretCast(
+ CodeGenContext context,
+ IAstNode node,
+ VariableType srcType,
+ VariableType dstType)
+ {
+ if (node is AstOperand operand && operand.Type == OperandType.Constant)
+ {
+ if (NumberFormatter.TryFormat(operand.Value, dstType, out string formatted))
+ {
+ return formatted;
+ }
+ }
+
+ string expr = InstGen.GetExpression(context, node);
+
+ return ReinterpretCast(expr, node, srcType, dstType);
+ }
+
+ private static string ReinterpretCast(string expr, IAstNode node, VariableType srcType, VariableType dstType)
+ {
+ if (srcType == dstType)
+ {
+ return expr;
+ }
+
+ if (srcType == VariableType.F32)
+ {
+ switch (dstType)
+ {
+ case VariableType.S32: return $"floatBitsToInt({expr})";
+ case VariableType.U32: return $"floatBitsToUint({expr})";
+ }
+ }
+ else if (dstType == VariableType.F32)
+ {
+ switch (srcType)
+ {
+ case VariableType.Bool: return $"intBitsToFloat({ReinterpretBoolToInt(expr, node, VariableType.S32)})";
+ case VariableType.S32: return $"intBitsToFloat({expr})";
+ case VariableType.U32: return $"uintBitsToFloat({expr})";
+ }
+ }
+ else if (srcType == VariableType.Bool)
+ {
+ return ReinterpretBoolToInt(expr, node, dstType);
+ }
+ else if (dstType == VariableType.Bool)
+ {
+ expr = InstGenHelper.Enclose(expr, node, Instruction.CompareNotEqual, isLhs: true);
+
+ return $"({expr} != 0)";
+ }
+ else if (dstType == VariableType.S32)
+ {
+ return $"int({expr})";
+ }
+ else if (dstType == VariableType.U32)
+ {
+ return $"uint({expr})";
+ }
+
+ throw new ArgumentException($"Invalid reinterpret cast from \"{srcType}\" to \"{dstType}\".");
+ }
+
+ private static string ReinterpretBoolToInt(string expr, IAstNode node, VariableType dstType)
+ {
+ string trueExpr = NumberFormatter.FormatInt(IrConsts.True, dstType);
+ string falseExpr = NumberFormatter.FormatInt(IrConsts.False, dstType);
+
+ expr = InstGenHelper.Enclose(expr, node, Instruction.ConditionalSelect, isLhs: false);
+
+ return $"({expr} ? {trueExpr} : {falseExpr})";
+ }
+ }
+} \ No newline at end of file