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(IGalMemory Memory, long Position)
  7. {
  8. ShaderIrBlock Block = new ShaderIrBlock();
  9. while (true)
  10. {
  11. Block.Position = Position;
  12. Block.MarkLabel(Position);
  13. //Ignore scheduling instructions, which are written every 32 bytes.
  14. if ((Position & 0x1f) == 0)
  15. {
  16. Position += 8;
  17. continue;
  18. }
  19. uint Word0 = (uint)Memory.ReadInt32(Position + 0);
  20. uint Word1 = (uint)Memory.ReadInt32(Position + 4);
  21. Position += 8;
  22. long OpCode = Word0 | (long)Word1 << 32;
  23. ShaderDecodeFunc Decode = ShaderOpCodeTable.GetDecoder(OpCode);
  24. if (AddDbgComments)
  25. {
  26. string DbgOpCode = $"0x{Position:x16}: 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. }