Lowering.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. using Ryujinx.Graphics.Shader.IntermediateRepresentation;
  2. using System.Collections.Generic;
  3. using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
  4. using static Ryujinx.Graphics.Shader.Translation.GlobalMemory;
  5. namespace Ryujinx.Graphics.Shader.Translation
  6. {
  7. static class Lowering
  8. {
  9. public static void RunPass(BasicBlock[] blocks, ShaderConfig config)
  10. {
  11. for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++)
  12. {
  13. BasicBlock block = blocks[blkIndex];
  14. for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next)
  15. {
  16. if (!(node.Value is Operation operation))
  17. {
  18. continue;
  19. }
  20. if (UsesGlobalMemory(operation.Inst))
  21. {
  22. node = LowerGlobal(node, config);
  23. }
  24. }
  25. }
  26. }
  27. private static LinkedListNode<INode> LowerGlobal(LinkedListNode<INode> node, ShaderConfig config)
  28. {
  29. Operation operation = (Operation)node.Value;
  30. Operation storageOp;
  31. Operand PrependOperation(Instruction inst, params Operand[] sources)
  32. {
  33. Operand local = Local();
  34. node.List.AddBefore(node, new Operation(inst, local, sources));
  35. return local;
  36. }
  37. Operand addrLow = operation.GetSource(0);
  38. Operand addrHigh = operation.GetSource(1);
  39. Operand sbBaseAddrLow = Const(0);
  40. Operand sbSlot = Const(0);
  41. for (int slot = 0; slot < StorageMaxCount; slot++)
  42. {
  43. int cbOffset = GetStorageCbOffset(config.Stage, slot);
  44. Operand baseAddrLow = Cbuf(0, cbOffset);
  45. Operand baseAddrHigh = Cbuf(0, cbOffset + 1);
  46. Operand size = Cbuf(0, cbOffset + 2);
  47. Operand offset = PrependOperation(Instruction.Subtract, addrLow, baseAddrLow);
  48. Operand borrow = PrependOperation(Instruction.CompareLessU32, addrLow, baseAddrLow);
  49. Operand inRangeLow = PrependOperation(Instruction.CompareLessU32, offset, size);
  50. Operand addrHighBorrowed = PrependOperation(Instruction.Add, addrHigh, borrow);
  51. Operand inRangeHigh = PrependOperation(Instruction.CompareEqual, addrHighBorrowed, baseAddrHigh);
  52. Operand inRange = PrependOperation(Instruction.BitwiseAnd, inRangeLow, inRangeHigh);
  53. sbBaseAddrLow = PrependOperation(Instruction.ConditionalSelect, inRange, baseAddrLow, sbBaseAddrLow);
  54. sbSlot = PrependOperation(Instruction.ConditionalSelect, inRange, Const(slot), sbSlot);
  55. }
  56. Operand alignMask = Const(-config.Capabilities.StorageBufferOffsetAlignment);
  57. Operand baseAddrTrunc = PrependOperation(Instruction.BitwiseAnd, sbBaseAddrLow, Const(-64));
  58. Operand byteOffset = PrependOperation(Instruction.Subtract, addrLow, baseAddrTrunc);
  59. Operand wordOffset = PrependOperation(Instruction.ShiftRightU32, byteOffset, Const(2));
  60. Operand[] sources = new Operand[operation.SourcesCount];
  61. sources[0] = sbSlot;
  62. sources[1] = wordOffset;
  63. for (int index = 2; index < operation.SourcesCount; index++)
  64. {
  65. sources[index] = operation.GetSource(index);
  66. }
  67. if (operation.Inst.IsAtomic())
  68. {
  69. Instruction inst = (operation.Inst & ~Instruction.MrMask) | Instruction.MrStorage;
  70. storageOp = new Operation(inst, operation.Dest, sources);
  71. }
  72. else if (operation.Inst == Instruction.LoadGlobal)
  73. {
  74. storageOp = new Operation(Instruction.LoadStorage, operation.Dest, sources);
  75. }
  76. else
  77. {
  78. storageOp = new Operation(Instruction.StoreStorage, null, sources);
  79. }
  80. for (int index = 0; index < operation.SourcesCount; index++)
  81. {
  82. operation.SetSource(index, null);
  83. }
  84. LinkedListNode<INode> oldNode = node;
  85. node = node.List.AddBefore(node, storageOp);
  86. node.List.Remove(oldNode);
  87. return node;
  88. }
  89. }
  90. }