aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Engine/GPFifo
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2021-06-23 20:51:41 -0300
committerGitHub <noreply@github.com>2021-06-24 01:51:41 +0200
commita10b2c5ff26886e9ffc6f19e3f0fe9505a503b2f (patch)
tree006d013c300fb56c94c5563c2c1409a189f794b2 /Ryujinx.Graphics.Gpu/Engine/GPFifo
parent12a7a2ead812d46deb9d978b6758731157be1cbc (diff)
Initial support for GPU channels (#2372)
* Ground work for separate GPU channels * Rename TextureManager to TextureCache * Decouple texture bindings management from the texture cache * Rename BufferManager to BufferCache * Decouple buffer bindings management from the buffer cache * More comments and proper disposal * PR feedback * Force host state update on channel switch * Typo * PR feedback * Missing using
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Engine/GPFifo')
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs36
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoProcessor.cs17
2 files changed, 43 insertions, 10 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs b/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs
index d0fcf142..0e284ac5 100644
--- a/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoDevice.cs
@@ -26,6 +26,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
private struct CommandBuffer
{
/// <summary>
+ /// Processor used to process the command buffer. Contains channel state.
+ /// </summary>
+ public GPFifoProcessor Processor;
+
+ /// <summary>
/// The type of the command buffer.
/// </summary>
public CommandBufferType Type;
@@ -60,11 +65,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
private readonly ConcurrentQueue<CommandBuffer> _commandBufferQueue;
private CommandBuffer _currentCommandBuffer;
+ private GPFifoProcessor _prevChannelProcessor;
private readonly bool _ibEnable;
private readonly GpuContext _context;
private readonly AutoResetEvent _event;
- private readonly GPFifoProcessor _processor;
private bool _interrupt;
@@ -78,8 +83,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
_ibEnable = true;
_context = context;
_event = new AutoResetEvent(false);
-
- _processor = new GPFifoProcessor(context);
}
/// <summary>
@@ -94,11 +97,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
/// Push a GPFIFO entry in the form of a prefetched command buffer.
/// It is intended to be used by nvservices to handle special cases.
/// </summary>
+ /// <param name="processor">Processor used to process <paramref name="commandBuffer"/></param>
/// <param name="commandBuffer">The command buffer containing the prefetched commands</param>
- public void PushHostCommandBuffer(int[] commandBuffer)
+ internal void PushHostCommandBuffer(GPFifoProcessor processor, int[] commandBuffer)
{
_commandBufferQueue.Enqueue(new CommandBuffer
{
+ Processor = processor,
Type = CommandBufferType.Prefetch,
Words = commandBuffer,
EntryAddress = ulong.MaxValue,
@@ -109,9 +114,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
/// <summary>
/// Create a CommandBuffer from a GPFIFO entry.
/// </summary>
+ /// <param name="processor">Processor used to process the command buffer pointed to by <paramref name="entry"/></param>
/// <param name="entry">The GPFIFO entry</param>
/// <returns>A new CommandBuffer based on the GPFIFO entry</returns>
- private CommandBuffer CreateCommandBuffer(GPEntry entry)
+ private static CommandBuffer CreateCommandBuffer(GPFifoProcessor processor, GPEntry entry)
{
CommandBufferType type = CommandBufferType.Prefetch;
@@ -124,6 +130,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
return new CommandBuffer
{
+ Processor = processor,
Type = type,
Words = null,
EntryAddress = startAddress,
@@ -134,8 +141,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
/// <summary>
/// Pushes GPFIFO entries.
/// </summary>
+ /// <param name="processor">Processor used to process the command buffers pointed to by <paramref name="entries"/></param>
/// <param name="entries">GPFIFO entries</param>
- public void PushEntries(ReadOnlySpan<ulong> entries)
+ internal void PushEntries(GPFifoProcessor processor, ReadOnlySpan<ulong> entries)
{
bool beforeBarrier = true;
@@ -143,7 +151,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
{
ulong entry = entries[index];
- CommandBuffer commandBuffer = CreateCommandBuffer(Unsafe.As<ulong, GPEntry>(ref entry));
+ CommandBuffer commandBuffer = CreateCommandBuffer(processor, Unsafe.As<ulong, GPEntry>(ref entry));
if (beforeBarrier && commandBuffer.Type == CommandBufferType.Prefetch)
{
@@ -173,12 +181,24 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
/// </summary>
public void DispatchCalls()
{
+ // Use this opportunity to also dispose any pending channels that were closed.
+ _context.DisposePendingChannels();
+
+ // Process command buffers.
while (_ibEnable && !_interrupt && _commandBufferQueue.TryDequeue(out CommandBuffer entry))
{
_currentCommandBuffer = entry;
_currentCommandBuffer.Fetch(_context);
- _processor.Process(_currentCommandBuffer.Words);
+ // If we are changing the current channel,
+ // we need to force all the host state to be updated.
+ if (_prevChannelProcessor != entry.Processor)
+ {
+ _prevChannelProcessor = entry.Processor;
+ entry.Processor.ForceAllDirty();
+ }
+
+ entry.Processor.Process(_currentCommandBuffer.Words);
}
_interrupt = false;
diff --git a/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoProcessor.cs b/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoProcessor.cs
index 78912bcc..dc8a1c75 100644
--- a/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoProcessor.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/GPFifo/GPFifoProcessor.cs
@@ -35,7 +35,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
/// Creates a new instance of the GPU General Purpose FIFO command processor.
/// </summary>
/// <param name="context">GPU context</param>
- public GPFifoProcessor(GpuContext context)
+ /// <param name="channel">Channel that the GPFIFO processor belongs to</param>
+ public GPFifoProcessor(GpuContext context, GpuChannel channel)
{
_context = context;
@@ -44,7 +45,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
for (int index = 0; index < _subChannels.Length; index++)
{
- _subChannels[index] = new GpuState();
+ _subChannels[index] = new GpuState(channel);
_context.Methods.RegisterCallbacks(_subChannels[index]);
}
@@ -186,5 +187,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
_subChannels[i].ShadowRamControl = control;
}
}
+
+ /// <summary>
+ /// Forces a full host state update by marking all state as modified,
+ /// and also requests all GPU resources in use to be rebound.
+ /// </summary>
+ public void ForceAllDirty()
+ {
+ for (int index = 0; index < _subChannels.Length; index++)
+ {
+ _subChannels[index].ForceAllDirty();
+ }
+ }
}
}