mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-12-20 10:02:00 +00:00
Create command buffers when rented rather than in advance (#31)
* Make it less likely to freeze, but the creation of the command buffer should probably be moved * Create command buffers as they're rented rather than in advance
This commit is contained in:
parent
2511bf1e4c
commit
6f6ccb7898
3 changed files with 13 additions and 26 deletions
|
@ -26,7 +26,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
if (_pool == null)
|
if (_pool == null)
|
||||||
{
|
{
|
||||||
MTLCommandQueue queue = _renderer.BackgroundQueue;
|
MTLCommandQueue queue = _renderer.BackgroundQueue;
|
||||||
_pool = new CommandBufferPool(queue);
|
_pool = new CommandBufferPool(queue, true);
|
||||||
_pool.Initialize(null); // TODO: Proper encoder factory for background render/compute
|
_pool.Initialize(null); // TODO: Proper encoder factory for background render/compute
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,22 +33,21 @@ namespace Ryujinx.Graphics.Metal
|
||||||
public List<IAuto> Dependants;
|
public List<IAuto> Dependants;
|
||||||
public List<MultiFenceHolder> Waitables;
|
public List<MultiFenceHolder> Waitables;
|
||||||
|
|
||||||
public void Reinitialize(MTLCommandQueue queue, IEncoderFactory stateManager)
|
public void Use(MTLCommandQueue queue, IEncoderFactory stateManager)
|
||||||
{
|
{
|
||||||
CommandBuffer = queue.CommandBuffer();
|
CommandBuffer = queue.CommandBuffer();
|
||||||
|
Fence = new FenceHolder(CommandBuffer);
|
||||||
|
|
||||||
Encoders.Initialize(CommandBuffer, stateManager);
|
Encoders.Initialize(CommandBuffer, stateManager);
|
||||||
|
|
||||||
|
InUse = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(MTLCommandQueue queue, IEncoderFactory stateManager)
|
public void Initialize()
|
||||||
{
|
{
|
||||||
CommandBuffer = queue.CommandBuffer();
|
|
||||||
|
|
||||||
Dependants = new List<IAuto>();
|
Dependants = new List<IAuto>();
|
||||||
Waitables = new List<MultiFenceHolder>();
|
Waitables = new List<MultiFenceHolder>();
|
||||||
Encoders = new CommandBufferEncoder();
|
Encoders = new CommandBufferEncoder();
|
||||||
|
|
||||||
Encoders.Initialize(CommandBuffer, stateManager);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,12 +58,12 @@ namespace Ryujinx.Graphics.Metal
|
||||||
private int _queuedCount;
|
private int _queuedCount;
|
||||||
private int _inUseCount;
|
private int _inUseCount;
|
||||||
|
|
||||||
public CommandBufferPool(MTLCommandQueue queue)
|
public CommandBufferPool(MTLCommandQueue queue, bool isLight = false)
|
||||||
{
|
{
|
||||||
_queue = queue;
|
_queue = queue;
|
||||||
_owner = Thread.CurrentThread;
|
_owner = Thread.CurrentThread;
|
||||||
|
|
||||||
_totalCommandBuffers = MaxCommandBuffers;
|
_totalCommandBuffers = isLight ? 2 : MaxCommandBuffers;
|
||||||
_totalCommandBuffersMask = _totalCommandBuffers - 1;
|
_totalCommandBuffersMask = _totalCommandBuffers - 1;
|
||||||
|
|
||||||
_commandBuffers = new ReservedCommandBuffer[_totalCommandBuffers];
|
_commandBuffers = new ReservedCommandBuffer[_totalCommandBuffers];
|
||||||
|
@ -80,7 +79,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
for (int i = 0; i < _totalCommandBuffers; i++)
|
for (int i = 0; i < _totalCommandBuffers; i++)
|
||||||
{
|
{
|
||||||
_commandBuffers[i].Initialize(_queue, _defaultEncoderFactory);
|
_commandBuffers[i].Initialize();
|
||||||
WaitAndDecrementRef(i);
|
WaitAndDecrementRef(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,7 +206,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
if (!entry.InUse && !entry.InConsumption)
|
if (!entry.InUse && !entry.InConsumption)
|
||||||
{
|
{
|
||||||
entry.InUse = true;
|
entry.Use(_queue, _defaultEncoderFactory);
|
||||||
|
|
||||||
_inUseCount++;
|
_inUseCount++;
|
||||||
|
|
||||||
|
@ -242,16 +241,13 @@ namespace Ryujinx.Graphics.Metal
|
||||||
var commandBuffer = entry.CommandBuffer;
|
var commandBuffer = entry.CommandBuffer;
|
||||||
commandBuffer.Commit();
|
commandBuffer.Commit();
|
||||||
|
|
||||||
// Replace entry with new MTLCommandBuffer
|
|
||||||
entry.Reinitialize(_queue, _defaultEncoderFactory);
|
|
||||||
|
|
||||||
int ptr = (_queuedIndexesPtr + _queuedCount) % _totalCommandBuffers;
|
int ptr = (_queuedIndexesPtr + _queuedCount) % _totalCommandBuffers;
|
||||||
_queuedIndexes[ptr] = cbIndex;
|
_queuedIndexes[ptr] = cbIndex;
|
||||||
_queuedCount++;
|
_queuedCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WaitAndDecrementRef(int cbIndex, bool refreshFence = true)
|
private void WaitAndDecrementRef(int cbIndex)
|
||||||
{
|
{
|
||||||
ref var entry = ref _commandBuffers[cbIndex];
|
ref var entry = ref _commandBuffers[cbIndex];
|
||||||
|
|
||||||
|
@ -275,22 +271,13 @@ namespace Ryujinx.Graphics.Metal
|
||||||
entry.Dependants.Clear();
|
entry.Dependants.Clear();
|
||||||
entry.Waitables.Clear();
|
entry.Waitables.Clear();
|
||||||
entry.Fence?.Dispose();
|
entry.Fence?.Dispose();
|
||||||
|
|
||||||
if (refreshFence)
|
|
||||||
{
|
|
||||||
entry.Fence = new FenceHolder(entry.CommandBuffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entry.Fence = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _totalCommandBuffers; i++)
|
for (int i = 0; i < _totalCommandBuffers; i++)
|
||||||
{
|
{
|
||||||
WaitAndDecrementRef(i, refreshFence: false);
|
WaitAndDecrementRef(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
throw new NotSupportedException("Metal backend requires Tier 2 Argument Buffer support.");
|
throw new NotSupportedException("Metal backend requires Tier 2 Argument Buffer support.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_queue = _device.NewCommandQueue(CommandBufferPool.MaxCommandBuffers);
|
_queue = _device.NewCommandQueue(CommandBufferPool.MaxCommandBuffers + 1);
|
||||||
BackgroundQueue = _device.NewCommandQueue(CommandBufferPool.MaxCommandBuffers);
|
BackgroundQueue = _device.NewCommandQueue(CommandBufferPool.MaxCommandBuffers);
|
||||||
|
|
||||||
_getMetalLayer = metalLayer;
|
_getMetalLayer = metalLayer;
|
||||||
|
|
Loading…
Reference in a new issue