ShaderDecodeMem.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. using System;
  2. using static Ryujinx.Graphics.Gal.Shader.ShaderDecodeHelper;
  3. namespace Ryujinx.Graphics.Gal.Shader
  4. {
  5. static partial class ShaderDecode
  6. {
  7. public static void Ld_A(ShaderIrBlock Block, long OpCode)
  8. {
  9. ShaderIrNode[] Opers = GetOperAbuf20(OpCode);
  10. int Index = 0;
  11. foreach (ShaderIrNode OperA in Opers)
  12. {
  13. ShaderIrOperGpr OperD = GetOperGpr0(OpCode);
  14. OperD.Index += Index++;
  15. Block.AddNode(GetPredNode(new ShaderIrAsg(OperD, OperA), OpCode));
  16. }
  17. }
  18. public static void Ld_C(ShaderIrBlock Block, long OpCode)
  19. {
  20. int Type = (int)(OpCode >> 48) & 7;
  21. if (Type > 5)
  22. {
  23. throw new InvalidOperationException();
  24. }
  25. int Count = Type == 5 ? 2 : 1;
  26. for (int Index = 0; Index < Count; Index++)
  27. {
  28. ShaderIrOperCbuf OperA = GetOperCbuf36(OpCode);
  29. ShaderIrOperGpr OperD = GetOperGpr0 (OpCode);
  30. OperA.Pos += Index;
  31. OperD.Index += Index;
  32. ShaderIrNode Node = OperA;
  33. if (Type < 4)
  34. {
  35. //This is a 8 or 16 bits type.
  36. bool Signed = (Type & 1) != 0;
  37. int Size = 8 << (Type >> 1);
  38. Node = ExtendTo32(Node, Signed, Size);
  39. }
  40. Block.AddNode(GetPredNode(new ShaderIrAsg(OperD, Node), OpCode));
  41. }
  42. }
  43. public static void St_A(ShaderIrBlock Block, long OpCode)
  44. {
  45. ShaderIrNode[] Opers = GetOperAbuf20(OpCode);
  46. int Index = 0;
  47. foreach (ShaderIrNode OperA in Opers)
  48. {
  49. ShaderIrOperGpr OperD = GetOperGpr0(OpCode);
  50. OperD.Index += Index++;
  51. Block.AddNode(GetPredNode(new ShaderIrAsg(OperA, OperD), OpCode));
  52. }
  53. }
  54. public static void Texq(ShaderIrBlock Block, long OpCode)
  55. {
  56. ShaderIrNode OperD = GetOperGpr0(OpCode);
  57. ShaderIrNode OperA = GetOperGpr8(OpCode);
  58. ShaderTexqInfo Info = (ShaderTexqInfo)((OpCode >> 22) & 0x1f);
  59. ShaderIrMetaTexq Meta0 = new ShaderIrMetaTexq(Info, 0);
  60. ShaderIrMetaTexq Meta1 = new ShaderIrMetaTexq(Info, 1);
  61. ShaderIrNode OperC = GetOperImm13_36(OpCode);
  62. ShaderIrOp Op0 = new ShaderIrOp(ShaderIrInst.Texq, OperA, null, OperC, Meta0);
  63. ShaderIrOp Op1 = new ShaderIrOp(ShaderIrInst.Texq, OperA, null, OperC, Meta1);
  64. Block.AddNode(GetPredNode(new ShaderIrAsg(OperD, Op0), OpCode));
  65. Block.AddNode(GetPredNode(new ShaderIrAsg(OperA, Op1), OpCode)); //Is this right?
  66. }
  67. public static void Texs(ShaderIrBlock Block, long OpCode)
  68. {
  69. EmitTex(Block, OpCode, ShaderIrInst.Texs);
  70. }
  71. public static void Tlds(ShaderIrBlock Block, long OpCode)
  72. {
  73. EmitTex(Block, OpCode, ShaderIrInst.Txlf);
  74. }
  75. private static void EmitTex(ShaderIrBlock Block, long OpCode, ShaderIrInst Inst)
  76. {
  77. //TODO: Support other formats.
  78. ShaderIrNode OperA = GetOperGpr8 (OpCode);
  79. ShaderIrNode OperB = GetOperGpr20 (OpCode);
  80. ShaderIrNode OperC = GetOperImm13_36(OpCode);
  81. for (int Ch = 0; Ch < 4; Ch++)
  82. {
  83. //Assign it to a temp because the destination registers
  84. //may be used as texture coord input aswell.
  85. ShaderIrOperGpr Dst = new ShaderIrOperGpr(0x100 + Ch);
  86. ShaderIrMetaTex Meta = new ShaderIrMetaTex(Ch);
  87. ShaderIrOp Op = new ShaderIrOp(Inst, OperA, OperB, OperC, Meta);
  88. Block.AddNode(GetPredNode(new ShaderIrAsg(Dst, Op), OpCode));
  89. }
  90. for (int Ch = 0; Ch < 4; Ch++)
  91. {
  92. ShaderIrOperGpr Src = new ShaderIrOperGpr(0x100 + Ch);
  93. ShaderIrOperGpr Dst = (Ch >> 1) != 0
  94. ? GetOperGpr28(OpCode)
  95. : GetOperGpr0 (OpCode);
  96. Dst.Index += Ch & 1;
  97. if (Dst.Index >= ShaderIrOperGpr.ZRIndex)
  98. {
  99. continue;
  100. }
  101. Block.AddNode(GetPredNode(new ShaderIrAsg(Dst, Src), OpCode));
  102. }
  103. }
  104. }
  105. }