Vulkan: Periodically free regions of the staging buffer (#5572)

* Vulkan: Periodically free regions of the staging buffer

There was an edge case where a game could submit tens of thousands of small copies over the course of over half a minute to unique fences. This could result in a large stutter when the staging buffer became full and it tried to check and free thousands of completed fences.

This became visible with some games and mirrors on Windows, as they don't submit any buffer data via the staging buffer, but may submit copies of the support buffer.

This change makes the Vulkan backend check for staging buffer completion on each command buffer submit, so it can't get backed up with 1000s of copies to check.

* Add comment
This commit is contained in:
riperiperi 2023-08-16 22:06:46 +01:00 committed by GitHub
parent 511b558ddc
commit 0c445184c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 4 additions and 1 deletions

View file

@ -246,7 +246,7 @@ namespace Ryujinx.Graphics.Vulkan
return true;
}
private void FreeCompleted()
public void FreeCompleted()
{
FenceHolder signalledFence = null;
while (_pendingCopies.TryPeek(out var pc) && (pc.Fence == signalledFence || pc.Fence.IsSignaled()))

View file

@ -475,6 +475,9 @@ namespace Ryujinx.Graphics.Vulkan
internal void RegisterFlush()
{
SyncManager.RegisterFlush();
// Periodically free unused regions of the staging buffer to avoid doing it all at once.
BufferManager.StagingBuffer.FreeCompleted();
}
public PinnedSpan<byte> GetBufferData(BufferHandle buffer, int offset, int size)