diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2024-07-07 19:33:28 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-07 19:33:28 -0300 |
| commit | a830eb666b058df38f734c6369eb18cc7212f36c (patch) | |
| tree | 5c23278f5452153405975825f640659cb5f7e5bd /src/Ryujinx.Graphics.Vulkan/FenceHolder.cs | |
| parent | cfc75d7e78a63fe3bde06b6e4896a42e8dedaf82 (diff) | |
Disallow concurrent fence waits on Adreno (#7001)
* Disallow concurrent fence waits on Adreno
* Ensure locks are released if exceptions are thrown
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/FenceHolder.cs')
| -rw-r--r-- | src/Ryujinx.Graphics.Vulkan/FenceHolder.cs | 79 |
1 files changed, 70 insertions, 9 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/FenceHolder.cs b/src/Ryujinx.Graphics.Vulkan/FenceHolder.cs index 4f0a8716..0cdb93f2 100644 --- a/src/Ryujinx.Graphics.Vulkan/FenceHolder.cs +++ b/src/Ryujinx.Graphics.Vulkan/FenceHolder.cs @@ -10,12 +10,15 @@ namespace Ryujinx.Graphics.Vulkan private readonly Device _device; private Fence _fence; private int _referenceCount; + private int _lock; + private readonly bool _concurrentWaitUnsupported; private bool _disposed; - public unsafe FenceHolder(Vk api, Device device) + public unsafe FenceHolder(Vk api, Device device, bool concurrentWaitUnsupported) { _api = api; _device = device; + _concurrentWaitUnsupported = concurrentWaitUnsupported; var fenceCreateInfo = new FenceCreateInfo { @@ -47,6 +50,11 @@ namespace Ryujinx.Graphics.Vulkan } while (Interlocked.CompareExchange(ref _referenceCount, lastValue + 1, lastValue) != lastValue); + if (_concurrentWaitUnsupported) + { + AcquireLock(); + } + fence = _fence; return true; } @@ -57,6 +65,16 @@ namespace Ryujinx.Graphics.Vulkan return _fence; } + public void PutLock() + { + Put(); + + if (_concurrentWaitUnsupported) + { + ReleaseLock(); + } + } + public void Put() { if (Interlocked.Decrement(ref _referenceCount) == 0) @@ -66,24 +84,67 @@ namespace Ryujinx.Graphics.Vulkan } } + private void AcquireLock() + { + while (!TryAcquireLock()) + { + Thread.SpinWait(32); + } + } + + private bool TryAcquireLock() + { + return Interlocked.Exchange(ref _lock, 1) == 0; + } + + private void ReleaseLock() + { + Interlocked.Exchange(ref _lock, 0); + } + public void Wait() { - Span<Fence> fences = stackalloc Fence[] + if (_concurrentWaitUnsupported) { - _fence, - }; + AcquireLock(); - FenceHelper.WaitAllIndefinitely(_api, _device, fences); + try + { + FenceHelper.WaitAllIndefinitely(_api, _device, stackalloc Fence[] { _fence }); + } + finally + { + ReleaseLock(); + } + } + else + { + FenceHelper.WaitAllIndefinitely(_api, _device, stackalloc Fence[] { _fence }); + } } public bool IsSignaled() { - Span<Fence> fences = stackalloc Fence[] + if (_concurrentWaitUnsupported) { - _fence, - }; + if (!TryAcquireLock()) + { + return false; + } - return FenceHelper.AllSignaled(_api, _device, fences); + try + { + return FenceHelper.AllSignaled(_api, _device, stackalloc Fence[] { _fence }); + } + finally + { + ReleaseLock(); + } + } + else + { + return FenceHelper.AllSignaled(_api, _device, stackalloc Fence[] { _fence }); + } } public void Dispose() |
