ShaderDecodeMem.cs 3.4 KB

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