2018-09-08 18:51:50 +01:00
|
|
|
using Ryujinx.Graphics.Memory;
|
2018-04-08 20:17:35 +01:00
|
|
|
|
2018-09-08 18:51:50 +01:00
|
|
|
namespace Ryujinx.Graphics
|
2018-04-08 20:17:35 +01:00
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
class NvGpuFifo
|
2018-04-08 20:17:35 +01:00
|
|
|
{
|
|
|
|
private const int MacrosCount = 0x80;
|
|
|
|
private const int MacroIndexMask = MacrosCount - 1;
|
|
|
|
|
2018-06-18 05:32:11 +01:00
|
|
|
//Note: The size of the macro memory is unknown, we just make
|
|
|
|
//a guess here and use 256kb as the size. Increase if needed.
|
|
|
|
private const int MmeWords = 256 * 256;
|
|
|
|
|
NvServices refactoring (#120)
* Initial implementation of NvMap/NvHostCtrl
* More work on NvHostCtrl
* Refactoring of nvservices, move GPU Vmm, make Vmm per-process, refactor most gpu devices, move Gpu to Core, fix CbBind
* Implement GetGpuTime, support CancelSynchronization, fix issue on InsertWaitingMutex, proper double buffering support (again, not working properly for commercial games, only hb)
* Try to fix perf regression reading/writing textures, moved syncpts and events to a UserCtx class, delete global state when the process exits, other minor tweaks
* Remove now unused code, add comment about probably wrong result codes
2018-05-07 19:53:23 +01:00
|
|
|
private NvGpu Gpu;
|
2018-04-08 20:17:35 +01:00
|
|
|
|
|
|
|
private NvGpuEngine[] SubChannels;
|
|
|
|
|
|
|
|
private struct CachedMacro
|
|
|
|
{
|
2018-06-18 05:32:11 +01:00
|
|
|
public int Position { get; private set; }
|
2018-04-08 20:17:35 +01:00
|
|
|
|
2018-11-17 04:01:31 +00:00
|
|
|
private bool ExecutionPending;
|
|
|
|
private int Argument;
|
|
|
|
|
2018-04-08 20:17:35 +01:00
|
|
|
private MacroInterpreter Interpreter;
|
|
|
|
|
2018-06-18 05:32:11 +01:00
|
|
|
public CachedMacro(NvGpuFifo PFifo, INvGpuEngine Engine, int Position)
|
2018-04-08 20:17:35 +01:00
|
|
|
{
|
|
|
|
this.Position = Position;
|
|
|
|
|
2018-11-17 04:01:31 +00:00
|
|
|
ExecutionPending = false;
|
|
|
|
Argument = 0;
|
|
|
|
|
2018-04-08 20:17:35 +01:00
|
|
|
Interpreter = new MacroInterpreter(PFifo, Engine);
|
|
|
|
}
|
|
|
|
|
2018-11-17 04:01:31 +00:00
|
|
|
public void StartExecution(int Argument)
|
2018-04-08 20:17:35 +01:00
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
this.Argument = Argument;
|
|
|
|
|
|
|
|
ExecutionPending = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Execute(NvGpuVmm Vmm, int[] Mme)
|
|
|
|
{
|
|
|
|
if (ExecutionPending)
|
|
|
|
{
|
|
|
|
ExecutionPending = false;
|
|
|
|
|
|
|
|
Interpreter?.Execute(Vmm, Mme, Position, Argument);
|
|
|
|
}
|
2018-04-08 20:17:35 +01:00
|
|
|
}
|
|
|
|
|
2018-11-17 04:01:31 +00:00
|
|
|
public void PushArgument(int Argument)
|
2018-04-08 20:17:35 +01:00
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
Interpreter?.Fifo.Enqueue(Argument);
|
2018-04-08 20:17:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-18 05:32:11 +01:00
|
|
|
private int CurrMacroPosition;
|
|
|
|
private int CurrMacroBindIndex;
|
2018-04-08 20:17:35 +01:00
|
|
|
|
|
|
|
private CachedMacro[] Macros;
|
|
|
|
|
2018-06-18 05:32:11 +01:00
|
|
|
private int[] Mme;
|
|
|
|
|
NvServices refactoring (#120)
* Initial implementation of NvMap/NvHostCtrl
* More work on NvHostCtrl
* Refactoring of nvservices, move GPU Vmm, make Vmm per-process, refactor most gpu devices, move Gpu to Core, fix CbBind
* Implement GetGpuTime, support CancelSynchronization, fix issue on InsertWaitingMutex, proper double buffering support (again, not working properly for commercial games, only hb)
* Try to fix perf regression reading/writing textures, moved syncpts and events to a UserCtx class, delete global state when the process exits, other minor tweaks
* Remove now unused code, add comment about probably wrong result codes
2018-05-07 19:53:23 +01:00
|
|
|
public NvGpuFifo(NvGpu Gpu)
|
2018-04-08 20:17:35 +01:00
|
|
|
{
|
|
|
|
this.Gpu = Gpu;
|
|
|
|
|
|
|
|
SubChannels = new NvGpuEngine[8];
|
|
|
|
|
|
|
|
Macros = new CachedMacro[MacrosCount];
|
2018-06-18 05:32:11 +01:00
|
|
|
|
|
|
|
Mme = new int[MmeWords];
|
2018-04-08 20:17:35 +01:00
|
|
|
}
|
|
|
|
|
2018-11-17 04:01:31 +00:00
|
|
|
public void CallMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
2018-04-08 20:17:35 +01:00
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
if ((NvGpuFifoMeth)MethCall.Method == NvGpuFifoMeth.BindChannel)
|
2018-04-08 20:17:35 +01:00
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
NvGpuEngine Engine = (NvGpuEngine)MethCall.Argument;
|
2018-04-08 20:17:35 +01:00
|
|
|
|
2018-11-17 04:01:31 +00:00
|
|
|
SubChannels[MethCall.SubChannel] = Engine;
|
2018-09-18 05:30:35 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
switch (SubChannels[MethCall.SubChannel])
|
2018-09-18 05:30:35 +01:00
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
case NvGpuEngine._2d: Call2dMethod (Vmm, MethCall); break;
|
|
|
|
case NvGpuEngine._3d: Call3dMethod (Vmm, MethCall); break;
|
|
|
|
case NvGpuEngine.P2mf: CallP2mfMethod(Vmm, MethCall); break;
|
|
|
|
case NvGpuEngine.M2mf: CallM2mfMethod(Vmm, MethCall); break;
|
2018-09-18 05:30:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-04-08 20:17:35 +01:00
|
|
|
|
2018-11-17 04:01:31 +00:00
|
|
|
private void Call2dMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
2018-09-18 05:30:35 +01:00
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
Gpu.Engine2d.CallMethod(Vmm, MethCall);
|
2018-09-18 05:30:35 +01:00
|
|
|
}
|
2018-04-08 20:17:35 +01:00
|
|
|
|
2018-11-17 04:01:31 +00:00
|
|
|
private void Call3dMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
2018-09-18 05:30:35 +01:00
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
if (MethCall.Method < 0x80)
|
2018-09-18 05:30:35 +01:00
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
switch ((NvGpuFifoMeth)MethCall.Method)
|
2018-09-18 05:30:35 +01:00
|
|
|
{
|
2018-04-08 20:17:35 +01:00
|
|
|
case NvGpuFifoMeth.SetMacroUploadAddress:
|
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
CurrMacroPosition = MethCall.Argument;
|
2018-04-08 20:17:35 +01:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NvGpuFifoMeth.SendMacroCodeData:
|
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
Mme[CurrMacroPosition++] = MethCall.Argument;
|
|
|
|
|
2018-04-08 20:17:35 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NvGpuFifoMeth.SetMacroBindingIndex:
|
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
CurrMacroBindIndex = MethCall.Argument;
|
2018-04-08 20:17:35 +01:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NvGpuFifoMeth.BindMacro:
|
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
int Position = MethCall.Argument;
|
2018-04-08 20:17:35 +01:00
|
|
|
|
|
|
|
Macros[CurrMacroBindIndex] = new CachedMacro(this, Gpu.Engine3d, Position);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2018-11-17 04:01:31 +00:00
|
|
|
|
|
|
|
default: CallP2mfMethod(Vmm, MethCall); break;
|
2018-04-08 20:17:35 +01:00
|
|
|
}
|
|
|
|
}
|
2018-11-17 04:01:31 +00:00
|
|
|
else if (MethCall.Method < 0xe00)
|
2018-04-08 20:17:35 +01:00
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
Gpu.Engine3d.CallMethod(Vmm, MethCall);
|
2018-04-08 20:17:35 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
int MacroIndex = (MethCall.Method >> 1) & MacroIndexMask;
|
2018-04-08 20:17:35 +01:00
|
|
|
|
2018-11-17 04:01:31 +00:00
|
|
|
if ((MethCall.Method & 1) != 0)
|
2018-04-08 20:17:35 +01:00
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
Macros[MacroIndex].PushArgument(MethCall.Argument);
|
2018-04-08 20:17:35 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
Macros[MacroIndex].StartExecution(MethCall.Argument);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (MethCall.IsLastCall)
|
|
|
|
{
|
|
|
|
Macros[MacroIndex].Execute(Vmm, Mme);
|
2018-04-08 20:17:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-06-13 14:55:01 +01:00
|
|
|
|
2018-11-17 04:01:31 +00:00
|
|
|
private void CallP2mfMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
2018-09-18 05:30:35 +01:00
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
Gpu.EngineP2mf.CallMethod(Vmm, MethCall);
|
2018-09-18 05:30:35 +01:00
|
|
|
}
|
|
|
|
|
2018-11-17 04:01:31 +00:00
|
|
|
private void CallM2mfMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
|
2018-06-13 14:55:01 +01:00
|
|
|
{
|
2018-11-17 04:01:31 +00:00
|
|
|
Gpu.EngineM2mf.CallMethod(Vmm, MethCall);
|
2018-06-13 14:55:01 +01:00
|
|
|
}
|
2018-04-08 20:17:35 +01:00
|
|
|
}
|
|
|
|
}
|