InstGen.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. using Ryujinx.Graphics.Shader.IntermediateRepresentation;
  2. using Ryujinx.Graphics.Shader.StructuredIr;
  3. using System;
  4. using static Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions.InstGenHelper;
  5. using static Ryujinx.Graphics.Shader.StructuredIr.InstructionInfo;
  6. namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
  7. {
  8. static class InstGen
  9. {
  10. public static string GetExpression(CodeGenContext context, IAstNode node)
  11. {
  12. if (node is AstOperation operation)
  13. {
  14. return GetExpression(context, operation);
  15. }
  16. else if (node is AstOperand operand)
  17. {
  18. return context.OperandManager.GetExpression(operand, context.Config.Stage);
  19. }
  20. throw new ArgumentException($"Invalid node type \"{node?.GetType().Name ?? "null"}\".");
  21. }
  22. private static string GetExpression(CodeGenContext context, AstOperation operation)
  23. {
  24. Instruction inst = operation.Inst;
  25. InstInfo info = GetInstructionInfo(inst);
  26. if ((info.Type & InstType.Call) != 0)
  27. {
  28. int arity = (int)(info.Type & InstType.ArityMask);
  29. string args = string.Empty;
  30. for (int argIndex = 0; argIndex < arity; argIndex++)
  31. {
  32. if (argIndex != 0)
  33. {
  34. args += ", ";
  35. }
  36. VariableType dstType = GetSrcVarType(inst, argIndex);
  37. args += GetSoureExpr(context, operation.GetSource(argIndex), dstType);
  38. }
  39. return info.OpName + "(" + args + ")";
  40. }
  41. else if ((info.Type & InstType.Op) != 0)
  42. {
  43. string op = info.OpName;
  44. int arity = (int)(info.Type & InstType.ArityMask);
  45. string[] expr = new string[arity];
  46. for (int index = 0; index < arity; index++)
  47. {
  48. IAstNode src = operation.GetSource(index);
  49. string srcExpr = GetSoureExpr(context, src, GetSrcVarType(inst, index));
  50. bool isLhs = arity == 2 && index == 0;
  51. expr[index] = Enclose(srcExpr, src, inst, info, isLhs);
  52. }
  53. switch (arity)
  54. {
  55. case 0:
  56. return op;
  57. case 1:
  58. return op + expr[0];
  59. case 2:
  60. return $"{expr[0]} {op} {expr[1]}";
  61. case 3:
  62. return $"{expr[0]} {op[0]} {expr[1]} {op[1]} {expr[2]}";
  63. }
  64. }
  65. else if ((info.Type & InstType.Special) != 0)
  66. {
  67. switch (inst)
  68. {
  69. case Instruction.ImageStore:
  70. return InstGenMemory.ImageStore(context, operation);
  71. case Instruction.LoadAttribute:
  72. return InstGenMemory.LoadAttribute(context, operation);
  73. case Instruction.LoadConstant:
  74. return InstGenMemory.LoadConstant(context, operation);
  75. case Instruction.LoadLocal:
  76. return InstGenMemory.LoadLocal(context, operation);
  77. case Instruction.LoadStorage:
  78. return InstGenMemory.LoadStorage(context, operation);
  79. case Instruction.PackHalf2x16:
  80. return InstGenPacking.PackHalf2x16(context, operation);
  81. case Instruction.StoreLocal:
  82. return InstGenMemory.StoreLocal(context, operation);
  83. case Instruction.StoreStorage:
  84. return InstGenMemory.StoreStorage(context, operation);
  85. case Instruction.TextureSample:
  86. return InstGenMemory.TextureSample(context, operation);
  87. case Instruction.TextureSize:
  88. return InstGenMemory.TextureSize(context, operation);
  89. case Instruction.UnpackHalf2x16:
  90. return InstGenPacking.UnpackHalf2x16(context, operation);
  91. }
  92. }
  93. return "0";
  94. throw new InvalidOperationException($"Unexpected instruction type \"{info.Type}\".");
  95. }
  96. }
  97. }