From ff2bac9c9042ef23437b19a32f3f2b6869cc1274 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Thu, 12 Mar 2020 22:30:26 -0300 Subject: Implement MME shadow RAM (#987) --- Ryujinx.Graphics.Gpu/MacroInterpreter.cs | 39 ++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 10 deletions(-) (limited to 'Ryujinx.Graphics.Gpu/MacroInterpreter.cs') diff --git a/Ryujinx.Graphics.Gpu/MacroInterpreter.cs b/Ryujinx.Graphics.Gpu/MacroInterpreter.cs index 4287f055..fa8a4a48 100644 --- a/Ryujinx.Graphics.Gpu/MacroInterpreter.cs +++ b/Ryujinx.Graphics.Gpu/MacroInterpreter.cs @@ -45,7 +45,7 @@ namespace Ryujinx.Graphics.Gpu BitwiseNotAnd = 12 } - public Queue Fifo { get; private set; } + public Queue Fifo { get; } private int[] _gprs; @@ -62,6 +62,8 @@ namespace Ryujinx.Graphics.Gpu private int _pc; + private ShadowRamControl _shadowCtrl; + /// /// Creates a new instance of the macro code interpreter. /// @@ -78,8 +80,10 @@ namespace Ryujinx.Graphics.Gpu /// Code of the program to execute /// Start position to execute /// Optional argument passed to the program, 0 if not used + /// Shadow RAM control register value /// Current GPU state - public void Execute(int[] mme, int position, int param, GpuState state) + /// Shadow GPU state + public void Execute(int[] mme, int position, int param, ShadowRamControl shadowCtrl, GpuState state, GpuState shadowState) { Reset(); @@ -87,13 +91,15 @@ namespace Ryujinx.Graphics.Gpu _pc = position; + _shadowCtrl = shadowCtrl; + FetchOpCode(mme); - while (Step(mme, state)); + while (Step(mme, state, shadowState)); // Due to the delay slot, we still need to execute // one more instruction before we actually exit. - Step(mme, state); + Step(mme, state, shadowState); } /// @@ -118,8 +124,9 @@ namespace Ryujinx.Graphics.Gpu /// /// Program code to execute /// Current GPU state + /// Shadow GPU state /// True to continue execution, false if the program exited - private bool Step(int[] mme, GpuState state) + private bool Step(int[] mme, GpuState state, GpuState shadowState) { int baseAddr = _pc - 1; @@ -165,7 +172,7 @@ namespace Ryujinx.Graphics.Gpu { SetDstGpr(FetchParam()); - Send(state, result); + Send(state, shadowState, result); break; } @@ -175,7 +182,7 @@ namespace Ryujinx.Graphics.Gpu { SetDstGpr(result); - Send(state, result); + Send(state, shadowState, result); break; } @@ -197,7 +204,7 @@ namespace Ryujinx.Graphics.Gpu SetMethAddr(result); - Send(state, FetchParam()); + Send(state, shadowState, FetchParam()); break; } @@ -209,7 +216,7 @@ namespace Ryujinx.Graphics.Gpu SetMethAddr(result); - Send(state, (result >> 12) & 0x3f); + Send(state, shadowState,(result >> 12) & 0x3f); break; } @@ -482,9 +489,21 @@ namespace Ryujinx.Graphics.Gpu /// Performs a GPU method call. /// /// Current GPU state + /// Shadow GPU state /// Call argument - private void Send(GpuState state, int value) + private void Send(GpuState state, GpuState shadowState, int value) { + // TODO: Figure out what TrackWithFilter does, compared to Track. + if (_shadowCtrl == ShadowRamControl.Track || + _shadowCtrl == ShadowRamControl.TrackWithFilter) + { + shadowState.Write(_methAddr, value); + } + else if (_shadowCtrl == ShadowRamControl.Replay) + { + value = shadowState.Read(_methAddr); + } + MethodParams meth = new MethodParams(_methAddr, value); state.CallMethod(meth); -- cgit v1.2.3