TypeConversion.cs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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.S32: return $"floatBitsToInt({expr})";
  36. case VariableType.U32: return $"floatBitsToUint({expr})";
  37. }
  38. }
  39. else if (dstType == VariableType.F32)
  40. {
  41. switch (srcType)
  42. {
  43. case VariableType.Bool: return $"intBitsToFloat({ReinterpretBoolToInt(expr, node, VariableType.S32)})";
  44. case VariableType.S32: return $"intBitsToFloat({expr})";
  45. case VariableType.U32: return $"uintBitsToFloat({expr})";
  46. }
  47. }
  48. else if (srcType == VariableType.Bool)
  49. {
  50. return ReinterpretBoolToInt(expr, node, dstType);
  51. }
  52. else if (dstType == VariableType.Bool)
  53. {
  54. expr = InstGenHelper.Enclose(expr, node, Instruction.CompareNotEqual, isLhs: true);
  55. return $"({expr} != 0)";
  56. }
  57. else if (dstType == VariableType.S32)
  58. {
  59. return $"int({expr})";
  60. }
  61. else if (dstType == VariableType.U32)
  62. {
  63. return $"uint({expr})";
  64. }
  65. throw new ArgumentException($"Invalid reinterpret cast from \"{srcType}\" to \"{dstType}\".");
  66. }
  67. private static string ReinterpretBoolToInt(string expr, IAstNode node, VariableType dstType)
  68. {
  69. string trueExpr = NumberFormatter.FormatInt(IrConsts.True, dstType);
  70. string falseExpr = NumberFormatter.FormatInt(IrConsts.False, dstType);
  71. expr = InstGenHelper.Enclose(expr, node, Instruction.ConditionalSelect, isLhs: false);
  72. return $"({expr} ? {trueExpr} : {falseExpr})";
  73. }
  74. }
  75. }