ShaderDecoder.cs 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. namespace Ryujinx.Graphics.Gal.Shader
  2. {
  3. static class ShaderDecoder
  4. {
  5. private const bool AddDbgComments = true;
  6. public static ShaderIrBlock DecodeBasicBlock(int[] Code, int Offset)
  7. {
  8. ShaderIrBlock Block = new ShaderIrBlock();
  9. while (Offset + 2 <= Code.Length)
  10. {
  11. int InstPos = Offset * 4;
  12. Block.Position = InstPos;
  13. Block.MarkLabel(InstPos);
  14. //Ignore scheduling instructions, which are written every 32 bytes.
  15. if ((Offset & 7) == 0)
  16. {
  17. Offset += 2;
  18. continue;
  19. }
  20. uint Word0 = (uint)Code[Offset++];
  21. uint Word1 = (uint)Code[Offset++];
  22. long OpCode = Word0 | (long)Word1 << 32;
  23. ShaderDecodeFunc Decode = ShaderOpCodeTable.GetDecoder(OpCode);
  24. if (AddDbgComments)
  25. {
  26. string DbgOpCode = $"0x{InstPos:x8}: 0x{OpCode:x16} ";
  27. Block.AddNode(new ShaderIrCmnt(DbgOpCode + (Decode?.Method.Name ?? "???")));
  28. }
  29. if (Decode == null)
  30. {
  31. continue;
  32. }
  33. Decode(Block, OpCode);
  34. if (Block.GetLastNode() is ShaderIrOp Op && Op.Inst == ShaderIrInst.Exit)
  35. {
  36. break;
  37. }
  38. }
  39. return Block;
  40. }
  41. private static bool IsFlowChange(ShaderIrInst Inst)
  42. {
  43. return Inst == ShaderIrInst.Exit;
  44. }
  45. }
  46. }