diff options
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/BufferHolder.cs')
-rw-r--r-- | src/Ryujinx.Graphics.Vulkan/BufferHolder.cs | 64 |
1 files changed, 33 insertions, 31 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/BufferHolder.cs b/src/Ryujinx.Graphics.Vulkan/BufferHolder.cs index a93ced0e..d3a3cae1 100644 --- a/src/Ryujinx.Graphics.Vulkan/BufferHolder.cs +++ b/src/Ryujinx.Graphics.Vulkan/BufferHolder.cs @@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Vulkan private int _flushTemp; private int _lastFlushWrite = -1; - private readonly ReaderWriterLock _flushLock; + private readonly ReaderWriterLockSlim _flushLock; private FenceHolder _flushFence; private int _flushWaiting; @@ -85,7 +85,7 @@ namespace Ryujinx.Graphics.Vulkan _currentType = currentType; DesiredType = currentType; - _flushLock = new ReaderWriterLock(); + _flushLock = new ReaderWriterLockSlim(); _useMirrors = gd.IsTBDR; } @@ -106,7 +106,7 @@ namespace Ryujinx.Graphics.Vulkan _currentType = currentType; DesiredType = currentType; - _flushLock = new ReaderWriterLock(); + _flushLock = new ReaderWriterLockSlim(); } public bool TryBackingSwap(ref CommandBufferScoped? cbs) @@ -116,7 +116,7 @@ namespace Ryujinx.Graphics.Vulkan // Only swap if the buffer is not used in any queued command buffer. bool isRented = _buffer.HasRentedCommandBufferDependency(_gd.CommandBufferPool); - if (!isRented && _gd.CommandBufferPool.OwnedByCurrentThread && !_flushLock.IsReaderLockHeld && (_pendingData == null || cbs != null)) + if (!isRented && _gd.CommandBufferPool.OwnedByCurrentThread && !_flushLock.IsReadLockHeld && (_pendingData == null || cbs != null)) { var currentAllocation = _allocationAuto; var currentBuffer = _buffer; @@ -131,7 +131,7 @@ namespace Ryujinx.Graphics.Vulkan ClearMirrors(cbs.Value, 0, Size); } - _flushLock.AcquireWriterLock(Timeout.Infinite); + _flushLock.EnterWriteLock(); ClearFlushFence(); @@ -185,7 +185,7 @@ namespace Ryujinx.Graphics.Vulkan _gd.PipelineInternal.SwapBuffer(currentBuffer, _buffer); - _flushLock.ReleaseWriterLock(); + _flushLock.ExitWriteLock(); } _swapQueued = false; @@ -548,42 +548,44 @@ namespace Ryujinx.Graphics.Vulkan private void WaitForFlushFence() { - // Assumes the _flushLock is held as reader, returns in same state. - - if (_flushFence != null) + if (_flushFence == null) { - // If storage has changed, make sure the fence has been reached so that the data is in place. - - var cookie = _flushLock.UpgradeToWriterLock(Timeout.Infinite); + return; + } - if (_flushFence != null) - { - var fence = _flushFence; - Interlocked.Increment(ref _flushWaiting); + // If storage has changed, make sure the fence has been reached so that the data is in place. + _flushLock.ExitReadLock(); + _flushLock.EnterWriteLock(); - // Don't wait in the lock. + if (_flushFence != null) + { + var fence = _flushFence; + Interlocked.Increment(ref _flushWaiting); - var restoreCookie = _flushLock.ReleaseLock(); + // Don't wait in the lock. - fence.Wait(); + _flushLock.ExitWriteLock(); - _flushLock.RestoreLock(ref restoreCookie); + fence.Wait(); - if (Interlocked.Decrement(ref _flushWaiting) == 0) - { - fence.Put(); - } + _flushLock.EnterWriteLock(); - _flushFence = null; + if (Interlocked.Decrement(ref _flushWaiting) == 0) + { + fence.Put(); } - _flushLock.DowngradeFromWriterLock(ref cookie); + _flushFence = null; } + + // Assumes the _flushLock is held as reader, returns in same state. + _flushLock.ExitWriteLock(); + _flushLock.EnterReadLock(); } public PinnedSpan<byte> GetData(int offset, int size) { - _flushLock.AcquireReaderLock(Timeout.Infinite); + _flushLock.EnterReadLock(); WaitForFlushFence(); @@ -603,7 +605,7 @@ namespace Ryujinx.Graphics.Vulkan // Need to be careful here, the buffer can't be unmapped while the data is being used. _buffer.IncrementReferenceCount(); - _flushLock.ReleaseReaderLock(); + _flushLock.ExitReadLock(); return PinnedSpan<byte>.UnsafeFromSpan(result, _buffer.DecrementReferenceCount); } @@ -621,7 +623,7 @@ namespace Ryujinx.Graphics.Vulkan result = resource.GetFlushBuffer().GetBufferData(resource.GetPool(), this, offset, size); } - _flushLock.ReleaseReaderLock(); + _flushLock.ExitReadLock(); // Flush buffer is pinned until the next GetBufferData on the thread, which is fine for current uses. return PinnedSpan<byte>.UnsafeFromSpan(result); @@ -1073,11 +1075,11 @@ namespace Ryujinx.Graphics.Vulkan _allocationAuto.Dispose(); } - _flushLock.AcquireWriterLock(Timeout.Infinite); + _flushLock.EnterWriteLock(); ClearFlushFence(); - _flushLock.ReleaseWriterLock(); + _flushLock.ExitWriteLock(); } } } |