TypeConversion.cs 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. using Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions;
  2. using Ryujinx.Graphics.Shader.IntermediateRepresentation;
  3. using Ryujinx.Graphics.Shader.StructuredIr;
  4. using System;
  5. namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
  6. {
  7. static class TypeConversion
  8. {
  9. public static string ReinterpretCast(
  10. CodeGenContext context,
  11. IAstNode node,
  12. VariableType srcType,
  13. VariableType dstType)
  14. {
  15. if (node is AstOperand operand && operand.Type == OperandType.Constant)
  16. {
  17. if (NumberFormatter.TryFormat(operand.Value, dstType, out string formatted))
  18. {
  19. return formatted;
  20. }
  21. }
  22. string expr = InstGen.GetExpression(context, node);
  23. return ReinterpretCast(expr, node, srcType, dstType);
  24. }
  25. private static string ReinterpretCast(string expr, IAstNode node, VariableType srcType, VariableType dstType)
  26. {
  27. if (srcType == dstType)
  28. {
  29. return expr;
  30. }
  31. if (srcType == VariableType.F32)
  32. {
  33. switch (dstType)
  34. {
  35. case VariableType.Bool: return $"(floatBitsToInt({expr}) != 0)";
  36. case VariableType.S32: return $"floatBitsToInt({expr})";
  37. case VariableType.U32: return $"floatBitsToUint({expr})";
  38. }
  39. }
  40. else if (dstType == VariableType.F32)
  41. {
  42. switch (srcType)
  43. {
  44. case VariableType.Bool: return $"intBitsToFloat({ReinterpretBoolToInt(expr, node, VariableType.S32)})";
  45. case VariableType.S32: return $"intBitsToFloat({expr})";
  46. case VariableType.U32: return $"uintBitsToFloat({expr})";
  47. }
  48. }
  49. else if (srcType == VariableType.Bool)
  50. {
  51. return ReinterpretBoolToInt(expr, node, dstType);
  52. }
  53. else if (dstType == VariableType.Bool)
  54. {
  55. expr = InstGenHelper.Enclose(expr, node, Instruction.CompareNotEqual, isLhs: true);
  56. return $"({expr} != 0)";
  57. }
  58. else if (dstType == VariableType.S32)
  59. {
  60. return $"int({expr})";
  61. }
  62. else if (dstType == VariableType.U32)
  63. {
  64. return $"uint({expr})";
  65. }
  66. throw new ArgumentException($"Invalid reinterpret cast from \"{srcType}\" to \"{dstType}\".");
  67. }
  68. private static string ReinterpretBoolToInt(string expr, IAstNode node, VariableType dstType)
  69. {
  70. string trueExpr = NumberFormatter.FormatInt(IrConsts.True, dstType);
  71. string falseExpr = NumberFormatter.FormatInt(IrConsts.False, dstType);
  72. expr = InstGenHelper.Enclose(expr, node, Instruction.ConditionalSelect, isLhs: false);
  73. return $"({expr} ? {trueExpr} : {falseExpr})";
  74. }
  75. }
  76. }