diff --git a/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs b/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs index b3de738d6..cd29a9da0 100644 --- a/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs +++ b/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs @@ -51,16 +51,35 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo /// public uint EntryCount; + /// + /// Get the entries for the command buffer from memory. + /// + /// The memory manager used to fetch the data + /// If true, flushes potential GPU written data before reading the command buffer + /// The fetched data + private ReadOnlySpan GetWords(MemoryManager memoryManager, bool flush) + { + return MemoryMarshal.Cast(memoryManager.GetSpan(EntryAddress, (int)EntryCount * 4, flush)); + } + + /// + /// Prefetch the command buffer. + /// + /// The memory manager used to fetch the data + public void Prefetch(MemoryManager memoryManager) + { + Words = GetWords(memoryManager, true).ToArray(); + } + /// /// Fetch the command buffer. /// + /// The memory manager used to fetch the data /// If true, flushes potential GPU written data before reading the command buffer - public void Fetch(MemoryManager memoryManager, bool flush = true) + /// The command buffer words + public ReadOnlySpan Fetch(MemoryManager memoryManager, bool flush) { - if (Words == null) - { - Words = MemoryMarshal.Cast(memoryManager.GetSpan(EntryAddress, (int)EntryCount * 4, flush)).ToArray(); - } + return Words ?? GetWords(memoryManager, flush); } } @@ -158,7 +177,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo if (beforeBarrier && commandBuffer.Type == CommandBufferType.Prefetch) { - commandBuffer.Fetch(processor.MemoryManager); + commandBuffer.Prefetch(processor.MemoryManager); } if (commandBuffer.Type == CommandBufferType.NoPrefetch) @@ -199,7 +218,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo } _currentCommandBuffer = entry; - _currentCommandBuffer.Fetch(entry.Processor.MemoryManager, flushCommandBuffer); + ReadOnlySpan words = entry.Fetch(entry.Processor.MemoryManager, flushCommandBuffer); // If we are changing the current channel, // we need to force all the host state to be updated. @@ -209,7 +228,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo entry.Processor.ForceAllDirty(); } - entry.Processor.Process(entry.EntryAddress, _currentCommandBuffer.Words); + entry.Processor.Process(entry.EntryAddress, words); } _interrupt = false;