aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Gpu/NsGpuPBEntry.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics/Gpu/NsGpuPBEntry.cs')
-rw-r--r--Ryujinx.Graphics/Gpu/NsGpuPBEntry.cs79
1 files changed, 79 insertions, 0 deletions
diff --git a/Ryujinx.Graphics/Gpu/NsGpuPBEntry.cs b/Ryujinx.Graphics/Gpu/NsGpuPBEntry.cs
new file mode 100644
index 00000000..8063651a
--- /dev/null
+++ b/Ryujinx.Graphics/Gpu/NsGpuPBEntry.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+
+namespace Ryujinx.Graphics.Gpu
+{
+ public struct NsGpuPBEntry
+ {
+ public NsGpuRegister Register { get; private set; }
+
+ public int SubChannel { get; private set; }
+
+ private int[] m_Arguments;
+
+ public ReadOnlyCollection<int> Arguments => Array.AsReadOnly(m_Arguments);
+
+ public NsGpuPBEntry(NsGpuRegister Register, int SubChannel, params int[] Arguments)
+ {
+ this.Register = Register;
+ this.SubChannel = SubChannel;
+ this.m_Arguments = Arguments;
+ }
+
+ public static NsGpuPBEntry[] DecodePushBuffer(byte[] Data)
+ {
+ using (MemoryStream MS = new MemoryStream(Data))
+ {
+ BinaryReader Reader = new BinaryReader(MS);
+
+ List<NsGpuPBEntry> GpFifos = new List<NsGpuPBEntry>();
+
+ bool CanRead() => MS.Position + 4 <= MS.Length;
+
+ while (CanRead())
+ {
+ int Packed = Reader.ReadInt32();
+
+ int Reg = (Packed << 2) & 0x7ffc;
+ int SubC = (Packed >> 13) & 7;
+ int Args = (Packed >> 16) & 0x1fff;
+ int Mode = (Packed >> 29) & 7;
+
+ if (Mode == 4)
+ {
+ //Inline Mode.
+ GpFifos.Add(new NsGpuPBEntry((NsGpuRegister)Reg, SubC, Args));
+ }
+ else
+ {
+ //Word mode.
+ if (Mode == 1)
+ {
+ //Sequential Mode.
+ for (int Index = 0; Index < Args && CanRead(); Index++, Reg += 4)
+ {
+ GpFifos.Add(new NsGpuPBEntry((NsGpuRegister)Reg, SubC, Reader.ReadInt32()));
+ }
+ }
+ else
+ {
+ //Non-Sequential Mode.
+ int[] Arguments = new int[Args];
+
+ for (int Index = 0; Index < Args && CanRead(); Index++)
+ {
+ Arguments[Index] = Reader.ReadInt32();
+ }
+
+ GpFifos.Add(new NsGpuPBEntry((NsGpuRegister)Reg, SubC, Arguments));
+ }
+ }
+ }
+
+ return GpFifos.ToArray();
+ }
+ }
+ }
+} \ No newline at end of file