2018-12-03 03:38:47 +01:00
|
|
|
using Ryujinx.Graphics.Memory;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
namespace Ryujinx.Graphics
|
|
|
|
{
|
|
|
|
public class CdmaProcessor
|
|
|
|
{
|
|
|
|
private const int MethSetMethod = 0x10;
|
|
|
|
private const int MethSetData = 0x11;
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
private NvGpu _gpu;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
public CdmaProcessor(NvGpu gpu)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
_gpu = gpu;
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
public void PushCommands(NvGpuVmm vmm, int[] cmdBuffer)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
List<ChCommand> commands = new List<ChCommand>();
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
ChClassId currentClass = 0;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
for (int index = 0; index < cmdBuffer.Length; index++)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
int cmd = cmdBuffer[index];
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
int value = (cmd >> 0) & 0xffff;
|
|
|
|
int methodOffset = (cmd >> 16) & 0xfff;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
ChSubmissionMode submissionMode = (ChSubmissionMode)((cmd >> 28) & 0xf);
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
switch (submissionMode)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
case ChSubmissionMode.SetClass: currentClass = (ChClassId)(value >> 6); break;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
|
|
|
case ChSubmissionMode.Incrementing:
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
int count = value;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
for (int argIdx = 0; argIdx < count; argIdx++)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
int argument = cmdBuffer[++index];
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
commands.Add(new ChCommand(currentClass, methodOffset + argIdx, argument));
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ChSubmissionMode.NonIncrementing:
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
int count = value;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
int[] arguments = new int[count];
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
for (int argIdx = 0; argIdx < count; argIdx++)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
arguments[argIdx] = cmdBuffer[++index];
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
commands.Add(new ChCommand(currentClass, methodOffset, arguments));
|
2018-12-03 03:38:47 +01:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
ProcessCommands(vmm, commands.ToArray());
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
private void ProcessCommands(NvGpuVmm vmm, ChCommand[] commands)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
int methodOffset = 0;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
foreach (ChCommand command in commands)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
switch (command.MethodOffset)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
case MethSetMethod: methodOffset = command.Arguments[0]; break;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
|
|
|
case MethSetData:
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
if (command.ClassId == ChClassId.NvDec)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
_gpu.VideoDecoder.Process(vmm, methodOffset, command.Arguments);
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
2019-03-04 02:45:25 +01:00
|
|
|
else if (command.ClassId == ChClassId.GraphicsVic)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
_gpu.VideoImageComposer.Process(vmm, methodOffset, command.Arguments);
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|