TypeConversion.cs 3.1 KB

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