diff options
| author | mpnico <mpnico@gmail.com> | 2021-08-26 23:50:28 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-26 23:50:28 +0200 |
| commit | 8e1adb95cf7f67b976f105f4cac26d3ff2986057 (patch) | |
| tree | f56ee0f92495fc1bd1e307c3bd51a2d1240d197b /Ryujinx.Graphics.Gpu/Engine/GPFifo | |
| parent | 5cab8ea4ad2388bd035150e79f241ae5df95ab3b (diff) | |
Add support for HLE macros and accelerate MultiDrawElementsIndirectCount #2 (#2557)
* Add support for HLE macros and accelerate MultiDrawElementsIndirectCount
* Add missing barrier
* Fix index buffer count
* Add support check for each macro hle before use
* Add missing xml doc
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Engine/GPFifo')
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClass.cs | 9 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs | 30 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoProcessor.cs | 19 |
3 files changed, 46 insertions, 12 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClass.cs b/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClass.cs index 28822f4e..fe49b0f2 100644 --- a/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClass.cs +++ b/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoClass.cs @@ -161,6 +161,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo /// <param name="argument">Method call argument</param> public void SetReference(int argument) { + _context.Renderer.Pipeline.CommandBufferBarrier(); + _context.CreateHostSyncIfNeeded(); } @@ -195,10 +197,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo /// Pushes an argument to a macro. /// </summary> /// <param name="index">Index of the macro</param> + /// <param name="gpuVa">GPU virtual address where the command word is located</param> /// <param name="argument">Argument to be pushed to the macro</param> - public void MmePushArgument(int index, int argument) + public void MmePushArgument(int index, ulong gpuVa, int argument) { - _macros[index].PushArgument(argument); + _macros[index].PushArgument(gpuVa, argument); } /// <summary> @@ -208,7 +211,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo /// <param name="argument">Initial argument passed to the macro</param> public void MmeStart(int index, int argument) { - _macros[index].StartExecution(argument); + _macros[index].StartExecution(_context, _parent, _macroCode, argument); } /// <summary> diff --git a/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs b/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs index ada3bc4b..b3de738d 100644 --- a/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs +++ b/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs @@ -54,11 +54,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo /// <summary> /// Fetch the command buffer. /// </summary> - public void Fetch(MemoryManager memoryManager) + /// <param name="flush">If true, flushes potential GPU written data before reading the command buffer</param> + public void Fetch(MemoryManager memoryManager, bool flush = true) { if (Words == null) { - Words = MemoryMarshal.Cast<byte, int>(memoryManager.GetSpan(EntryAddress, (int)EntryCount * 4, true)).ToArray(); + Words = MemoryMarshal.Cast<byte, int>(memoryManager.GetSpan(EntryAddress, (int)EntryCount * 4, flush)).ToArray(); } } } @@ -73,6 +74,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo private readonly AutoResetEvent _event; private bool _interrupt; + private int _flushSkips; /// <summary> /// Creates a new instance of the GPU General Purpose FIFO device. @@ -188,8 +190,16 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo // Process command buffers. while (_ibEnable && !_interrupt && _commandBufferQueue.TryDequeue(out CommandBuffer entry)) { + bool flushCommandBuffer = true; + + if (_flushSkips != 0) + { + _flushSkips--; + flushCommandBuffer = false; + } + _currentCommandBuffer = entry; - _currentCommandBuffer.Fetch(entry.Processor.MemoryManager); + _currentCommandBuffer.Fetch(entry.Processor.MemoryManager, flushCommandBuffer); // If we are changing the current channel, // we need to force all the host state to be updated. @@ -199,13 +209,25 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo entry.Processor.ForceAllDirty(); } - entry.Processor.Process(_currentCommandBuffer.Words); + entry.Processor.Process(entry.EntryAddress, _currentCommandBuffer.Words); } _interrupt = false; } /// <summary> + /// Sets the number of flushes that should be skipped for subsequent command buffers. + /// </summary> + /// <remarks> + /// This can improve performance when command buffer data only needs to be consumed by the GPU. + /// </remarks> + /// <param name="count">The amount of flushes that should be skipped</param> + internal void SetFlushSkips(int count) + { + _flushSkips = count; + } + + /// <summary> /// Interrupts command processing. This will break out of the DispatchCalls loop. /// </summary> public void Interrupt() diff --git a/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoProcessor.cs b/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoProcessor.cs index ea34d6cd..096b795c 100644 --- a/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoProcessor.cs +++ b/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoProcessor.cs @@ -29,6 +29,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo public MemoryManager MemoryManager => _channel.MemoryManager; /// <summary> + /// 3D Engine. + /// </summary> + public ThreedClass ThreedClass => _3dClass; + + /// <summary> /// Internal GPFIFO state. /// </summary> private struct DmaState @@ -70,13 +75,16 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo /// <summary> /// Processes a command buffer. /// </summary> + /// <param name="baseGpuVa">Base GPU virtual address of the command buffer</param> /// <param name="commandBuffer">Command buffer</param> - public void Process(ReadOnlySpan<int> commandBuffer) + public void Process(ulong baseGpuVa, ReadOnlySpan<int> commandBuffer) { for (int index = 0; index < commandBuffer.Length; index++) { int command = commandBuffer[index]; + ulong gpuVa = baseGpuVa + (ulong)index * 4; + if (_state.MethodCount != 0) { if (TryFastI2mBufferUpdate(commandBuffer, ref index)) @@ -84,7 +92,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo continue; } - Send(_state.Method, command, _state.SubChannel, _state.MethodCount <= 1); + Send(gpuVa, _state.Method, command, _state.SubChannel, _state.MethodCount <= 1); if (!_state.NonIncrementing) { @@ -120,7 +128,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo _state.NonIncrementing = meth.SecOp == SecOp.NonIncMethod; break; case SecOp.ImmdDataMethod: - Send(meth.MethodAddress, meth.ImmdData, meth.MethodSubchannel, true); + Send(gpuVa, meth.MethodAddress, meth.ImmdData, meth.MethodSubchannel, true); break; } } @@ -198,8 +206,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo /// <summary> /// Sends a uncompressed method for processing by the graphics pipeline. /// </summary> + /// <param name="gpuVa">GPU virtual address where the command word is located</param> /// <param name="meth">Method to be processed</param> - private void Send(int offset, int argument, int subChannel, bool isLastCall) + private void Send(ulong gpuVa, int offset, int argument, int subChannel, bool isLastCall) { if (offset < 0x60) { @@ -243,7 +252,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo if ((offset & 1) != 0) { - _fifoClass.MmePushArgument(macroIndex, argument); + _fifoClass.MmePushArgument(macroIndex, gpuVa, argument); } else { |
