BindlessToIndexed.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. using Ryujinx.Graphics.Shader.IntermediateRepresentation;
  2. using System.Collections.Generic;
  3. using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
  4. namespace Ryujinx.Graphics.Shader.Translation.Optimizations
  5. {
  6. static class BindlessToIndexed
  7. {
  8. private const int StorageDescsBaseOffset = 0x44; // In words.
  9. private const int UbeStorageDescsBaseOffset = 0x84; // In words.
  10. private const int UbeStorageMaxCount = 14;
  11. private const int StorageDescSize = 4; // In words.
  12. private const int StorageMaxCount = 16;
  13. private const int StorageDescsSize = StorageDescSize * StorageMaxCount;
  14. public static void RunPass(BasicBlock block)
  15. {
  16. // We can turn a bindless texture access into a indexed access,
  17. // as long the following conditions are true:
  18. // - The handle is loaded using a LDC instruction.
  19. // - The handle is loaded from the constant buffer with the handles (CB2 for NVN).
  20. // - The load has a constant offset.
  21. // The base offset of the array of handles on the constant buffer is the constant offset.
  22. for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next)
  23. {
  24. if (!(node.Value is TextureOperation texOp))
  25. {
  26. continue;
  27. }
  28. if ((texOp.Flags & TextureFlags.Bindless) == 0)
  29. {
  30. continue;
  31. }
  32. if (!(texOp.GetSource(0).AsgOp is Operation handleAsgOp))
  33. {
  34. continue;
  35. }
  36. if (handleAsgOp.Inst != Instruction.LoadConstant)
  37. {
  38. continue;
  39. }
  40. Operand ldcSrc0 = handleAsgOp.GetSource(0);
  41. Operand ldcSrc1 = handleAsgOp.GetSource(1);
  42. if (ldcSrc0.Type != OperandType.Constant || ldcSrc0.Value != 2)
  43. {
  44. continue;
  45. }
  46. if (!(ldcSrc1.AsgOp is Operation addOp))
  47. {
  48. continue;
  49. }
  50. Operand addSrc1 = addOp.GetSource(1);
  51. if (addSrc1.Type != OperandType.Constant)
  52. {
  53. continue;
  54. }
  55. texOp.TurnIntoIndexed(addSrc1.Value);
  56. Operand index = Local();
  57. Operand source = addOp.GetSource(0);
  58. Operation shrBy1 = new Operation(Instruction.ShiftRightU32, index, source, Const(1));
  59. block.Operations.AddBefore(node, shrBy1);
  60. texOp.SetSource(0, index);
  61. }
  62. }
  63. }
  64. }