Preload command speedup, Texture/buffer data flush, blit shader fix (#30)

* Move encoder state to be tied to command buffer, so preload and background cbs have their own encoder state

* Texture buffer/data flush, blit shader fix
This commit is contained in:
riperiperi 2024-06-30 17:23:53 +01:00 committed by Isaac Marovitz
parent 80f9a5d0da
commit 2511bf1e4c
13 changed files with 414 additions and 204 deletions

View file

@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.Versioning;
using System.Threading;
namespace Ryujinx.Graphics.Metal
{
@ -14,6 +15,10 @@ namespace Ryujinx.Graphics.Metal
private readonly int _totalCommandBuffers;
private readonly int _totalCommandBuffersMask;
private readonly MTLCommandQueue _queue;
private readonly Thread _owner;
private IEncoderFactory _defaultEncoderFactory;
public bool OwnedByCurrentThread => _owner == Thread.CurrentThread;
[SupportedOSPlatform("macos")]
private struct ReservedCommandBuffer
@ -22,22 +27,28 @@ namespace Ryujinx.Graphics.Metal
public bool InConsumption;
public int SubmissionCount;
public MTLCommandBuffer CommandBuffer;
public CommandBufferEncoder Encoders;
public FenceHolder Fence;
public List<IAuto> Dependants;
public List<MultiFenceHolder> Waitables;
public void Reinitialize(MTLCommandQueue queue)
public void Reinitialize(MTLCommandQueue queue, IEncoderFactory stateManager)
{
CommandBuffer = queue.CommandBuffer();
Encoders.Initialize(CommandBuffer, stateManager);
}
public void Initialize(MTLCommandQueue queue)
public void Initialize(MTLCommandQueue queue, IEncoderFactory stateManager)
{
CommandBuffer = queue.CommandBuffer();
Dependants = new List<IAuto>();
Waitables = new List<MultiFenceHolder>();
Encoders = new CommandBufferEncoder();
Encoders.Initialize(CommandBuffer, stateManager);
}
}
@ -51,6 +62,7 @@ namespace Ryujinx.Graphics.Metal
public CommandBufferPool(MTLCommandQueue queue)
{
_queue = queue;
_owner = Thread.CurrentThread;
_totalCommandBuffers = MaxCommandBuffers;
_totalCommandBuffersMask = _totalCommandBuffers - 1;
@ -60,10 +72,15 @@ namespace Ryujinx.Graphics.Metal
_queuedIndexes = new int[_totalCommandBuffers];
_queuedIndexesPtr = 0;
_queuedCount = 0;
}
public void Initialize(IEncoderFactory encoderFactory)
{
_defaultEncoderFactory = encoderFactory;
for (int i = 0; i < _totalCommandBuffers; i++)
{
_commandBuffers[i].Initialize(_queue);
_commandBuffers[i].Initialize(_queue, _defaultEncoderFactory);
WaitAndDecrementRef(i);
}
}
@ -194,7 +211,7 @@ namespace Ryujinx.Graphics.Metal
_inUseCount++;
return new CommandBufferScoped(this, entry.CommandBuffer, cursor);
return new CommandBufferScoped(this, entry.CommandBuffer, entry.Encoders, cursor);
}
cursor = (cursor + 1) & _totalCommandBuffersMask;
@ -206,6 +223,9 @@ namespace Ryujinx.Graphics.Metal
public void Return(CommandBufferScoped cbs)
{
// Ensure the encoder is committed.
cbs.Encoders.EndCurrentPass();
lock (_commandBuffers)
{
int cbIndex = cbs.CommandBufferIndex;
@ -223,7 +243,7 @@ namespace Ryujinx.Graphics.Metal
commandBuffer.Commit();
// Replace entry with new MTLCommandBuffer
entry.Reinitialize(_queue);
entry.Reinitialize(_queue, _defaultEncoderFactory);
int ptr = (_queuedIndexesPtr + _queuedCount) % _totalCommandBuffers;
_queuedIndexes[ptr] = cbIndex;