BindlessToIndexed.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. public static void RunPass(BasicBlock block)
  9. {
  10. // We can turn a bindless texture access into a indexed access,
  11. // as long the following conditions are true:
  12. // - The handle is loaded using a LDC instruction.
  13. // - The handle is loaded from the constant buffer with the handles (CB2 for NVN).
  14. // - The load has a constant offset.
  15. // The base offset of the array of handles on the constant buffer is the constant offset.
  16. for (LinkedListNode<INode> node = block.Operations.First; node != null; node = node.Next)
  17. {
  18. if (!(node.Value is TextureOperation texOp))
  19. {
  20. continue;
  21. }
  22. if ((texOp.Flags & TextureFlags.Bindless) == 0)
  23. {
  24. continue;
  25. }
  26. if (!(texOp.GetSource(0).AsgOp is Operation handleAsgOp))
  27. {
  28. continue;
  29. }
  30. if (handleAsgOp.Inst != Instruction.LoadConstant)
  31. {
  32. continue;
  33. }
  34. Operand ldcSrc0 = handleAsgOp.GetSource(0);
  35. Operand ldcSrc1 = handleAsgOp.GetSource(1);
  36. if (ldcSrc0.Type != OperandType.Constant || ldcSrc0.Value != 2)
  37. {
  38. continue;
  39. }
  40. if (!(ldcSrc1.AsgOp is Operation addOp))
  41. {
  42. continue;
  43. }
  44. Operand addSrc1 = addOp.GetSource(1);
  45. if (addSrc1.Type != OperandType.Constant)
  46. {
  47. continue;
  48. }
  49. texOp.TurnIntoIndexed(addSrc1.Value);
  50. Operand index = Local();
  51. Operand source = addOp.GetSource(0);
  52. Operation shrBy1 = new Operation(Instruction.ShiftRightU32, index, source, Const(1));
  53. block.Operations.AddBefore(node, shrBy1);
  54. texOp.SetSource(0, index);
  55. }
  56. }
  57. }
  58. }