NsGpuPBEntry.cs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.IO;
  5. namespace Ryujinx.Graphics.Gpu
  6. {
  7. public struct NsGpuPBEntry
  8. {
  9. public NsGpuRegister Register { get; private set; }
  10. public int SubChannel { get; private set; }
  11. private int[] m_Arguments;
  12. public ReadOnlyCollection<int> Arguments => Array.AsReadOnly(m_Arguments);
  13. public NsGpuPBEntry(NsGpuRegister Register, int SubChannel, params int[] Arguments)
  14. {
  15. this.Register = Register;
  16. this.SubChannel = SubChannel;
  17. this.m_Arguments = Arguments;
  18. }
  19. public static NsGpuPBEntry[] DecodePushBuffer(byte[] Data)
  20. {
  21. using (MemoryStream MS = new MemoryStream(Data))
  22. {
  23. BinaryReader Reader = new BinaryReader(MS);
  24. List<NsGpuPBEntry> GpFifos = new List<NsGpuPBEntry>();
  25. bool CanRead() => MS.Position + 4 <= MS.Length;
  26. while (CanRead())
  27. {
  28. int Packed = Reader.ReadInt32();
  29. int Reg = (Packed << 2) & 0x7ffc;
  30. int SubC = (Packed >> 13) & 7;
  31. int Args = (Packed >> 16) & 0x1fff;
  32. int Mode = (Packed >> 29) & 7;
  33. if (Mode == 4)
  34. {
  35. //Inline Mode.
  36. GpFifos.Add(new NsGpuPBEntry((NsGpuRegister)Reg, SubC, Args));
  37. }
  38. else
  39. {
  40. //Word mode.
  41. if (Mode == 1)
  42. {
  43. //Sequential Mode.
  44. for (int Index = 0; Index < Args && CanRead(); Index++, Reg += 4)
  45. {
  46. GpFifos.Add(new NsGpuPBEntry((NsGpuRegister)Reg, SubC, Reader.ReadInt32()));
  47. }
  48. }
  49. else
  50. {
  51. //Non-Sequential Mode.
  52. int[] Arguments = new int[Args];
  53. for (int Index = 0; Index < Args && CanRead(); Index++)
  54. {
  55. Arguments[Index] = Reader.ReadInt32();
  56. }
  57. GpFifos.Add(new NsGpuPBEntry((NsGpuRegister)Reg, SubC, Arguments));
  58. }
  59. }
  60. }
  61. return GpFifos.ToArray();
  62. }
  63. }
  64. }
  65. }