Ryujinx/Ryujinx.Core/Gpu/NvGpuPushBuffer.cs
gdkchan 231fae1a4c
Texture/Vertex/Index data cache (#132)
* Initial implementation of the texture cache

* Cache vertex and index data aswell, some cleanup

* Improve handling of the cache by storing cached ranges on a list for each page

* Delete old data from the caches automatically, ensure that the cache is cleaned when the mapping/size changes, and some general cleanup
2018-06-08 21:15:56 -03:00

101 lines
No EOL
3.2 KiB
C#

using System.Collections.Generic;
using System.IO;
namespace Ryujinx.Core.Gpu
{
static class NvGpuPushBuffer
{
private enum SubmissionMode
{
Incrementing = 1,
NonIncrementing = 3,
Immediate = 4,
IncrementOnce = 5
}
public static NvGpuPBEntry[] Decode(byte[] Data)
{
using (MemoryStream MS = new MemoryStream(Data))
{
BinaryReader Reader = new BinaryReader(MS);
List<NvGpuPBEntry> PushBuffer = new List<NvGpuPBEntry>();
bool CanRead() => MS.Position + 4 <= MS.Length;
while (CanRead())
{
int Packed = Reader.ReadInt32();
int Meth = (Packed >> 0) & 0x1fff;
int SubC = (Packed >> 13) & 7;
int Args = (Packed >> 16) & 0x1fff;
int Mode = (Packed >> 29) & 7;
switch ((SubmissionMode)Mode)
{
case SubmissionMode.Incrementing:
{
for (int Index = 0; Index < Args && CanRead(); Index++, Meth++)
{
PushBuffer.Add(new NvGpuPBEntry(Meth, SubC, Reader.ReadInt32()));
}
break;
}
case SubmissionMode.NonIncrementing:
{
int[] Arguments = new int[Args];
for (int Index = 0; Index < Arguments.Length; Index++)
{
if (!CanRead())
{
break;
}
Arguments[Index] = Reader.ReadInt32();
}
PushBuffer.Add(new NvGpuPBEntry(Meth, SubC, Arguments));
break;
}
case SubmissionMode.Immediate:
{
PushBuffer.Add(new NvGpuPBEntry(Meth, SubC, Args));
break;
}
case SubmissionMode.IncrementOnce:
{
if (CanRead())
{
PushBuffer.Add(new NvGpuPBEntry(Meth, SubC, Reader.ReadInt32()));
}
if (CanRead() && Args > 1)
{
int[] Arguments = new int[Args - 1];
for (int Index = 0; Index < Arguments.Length && CanRead(); Index++)
{
Arguments[Index] = Reader.ReadInt32();
}
PushBuffer.Add(new NvGpuPBEntry(Meth + 1, SubC, Arguments));
}
break;
}
}
}
return PushBuffer.ToArray();
}
}
}
}