diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Engine/MME/Macro.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/MME/Macro.cs | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/MME/Macro.cs b/Ryujinx.Graphics.Gpu/Engine/MME/Macro.cs index 1a79afb9..9d1dbc8f 100644 --- a/Ryujinx.Graphics.Gpu/Engine/MME/Macro.cs +++ b/Ryujinx.Graphics.Gpu/Engine/MME/Macro.cs @@ -1,4 +1,6 @@ using Ryujinx.Graphics.Device; +using Ryujinx.Graphics.Gpu.Engine.GPFifo; +using Ryujinx.Graphics.Gpu.Memory; using System; namespace Ryujinx.Graphics.Gpu.Engine.MME @@ -13,10 +15,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME /// </summary> public int Position { get; } + private IMacroEE _executionEngine; private bool _executionPending; private int _argument; - - private readonly IMacroEE _executionEngine; + private MacroHLEFunctionName _hleFunction; /// <summary> /// Creates a new instance of the GPU cached macro program. @@ -26,28 +28,47 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME { Position = position; + _executionEngine = null; _executionPending = false; _argument = 0; - - if (GraphicsConfig.EnableMacroJit) - { - _executionEngine = new MacroJit(); - } - else - { - _executionEngine = new MacroInterpreter(); - } + _hleFunction = MacroHLEFunctionName.None; } /// <summary> /// Sets the first argument for the macro call. /// </summary> + /// <param name="context">GPU context where the macro code is being executed</param> + /// <param name="processor">GPU GP FIFO command processor</param> + /// <param name="code">Code to be executed</param> /// <param name="argument">First argument</param> - public void StartExecution(int argument) + public void StartExecution(GpuContext context, GPFifoProcessor processor, ReadOnlySpan<int> code, int argument) { _argument = argument; _executionPending = true; + + if (_executionEngine == null) + { + if (GraphicsConfig.EnableMacroHLE && MacroHLETable.TryGetMacroHLEFunction(code.Slice(Position), context.Capabilities, out _hleFunction)) + { + _executionEngine = new MacroHLE(processor, _hleFunction); + } + else if (GraphicsConfig.EnableMacroJit) + { + _executionEngine = new MacroJit(); + } + else + { + _executionEngine = new MacroInterpreter(); + } + } + + if (_hleFunction == MacroHLEFunctionName.MultiDrawElementsIndirectCount) + { + // We don't consume the parameter buffer value, so we don't need to flush it. + // Doing so improves performance if the value was written by a GPU shader. + context.GPFifo.SetFlushSkips(2); + } } /// <summary> @@ -60,7 +81,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME if (_executionPending) { _executionPending = false; - _executionEngine?.Execute(code.Slice(Position), state, _argument); } } @@ -68,10 +88,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME /// <summary> /// Pushes an argument to the macro call argument FIFO. /// </summary> + /// <param name="gpuVa">GPU virtual address where the command word is located</param> /// <param name="argument">Argument to be pushed</param> - public void PushArgument(int argument) + public void PushArgument(ulong gpuVa, int argument) { - _executionEngine?.Fifo.Enqueue(argument); + _executionEngine?.Fifo.Enqueue(new FifoWord(gpuVa, argument)); } } } |