diff options
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs')
-rw-r--r-- | Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs b/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs index 5984a7ca..f4ab02fb 100644 --- a/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs +++ b/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs @@ -17,12 +17,14 @@ namespace Ryujinx.Graphics.OpenGL.Queries private CounterQueueEvent _current; private ulong _accumulatedCounter; + private int _waiterCount; private object _lock = new object(); private Queue<BufferedQuery> _queryPool; private AutoResetEvent _queuedEvent = new AutoResetEvent(false); private AutoResetEvent _wakeSignal = new AutoResetEvent(false); + private AutoResetEvent _eventConsumed = new AutoResetEvent(false); private Thread _consumerThread; @@ -63,7 +65,13 @@ namespace Ryujinx.Graphics.OpenGL.Queries } else { - evt.TryConsume(ref _accumulatedCounter, true, _wakeSignal); + // Spin-wait rather than sleeping if there are any waiters, by passing null instead of the wake signal. + evt.TryConsume(ref _accumulatedCounter, true, _waiterCount == 0 ? _wakeSignal : null); + } + + if (_waiterCount > 0) + { + _eventConsumed.Set(); } } } @@ -95,7 +103,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries } } - public CounterQueueEvent QueueReport(EventHandler<ulong> resultHandler, ulong lastDrawIndex) + public CounterQueueEvent QueueReport(EventHandler<ulong> resultHandler, ulong lastDrawIndex, bool hostReserved) { CounterQueueEvent result; ulong draws = lastDrawIndex - _current.DrawIndex; @@ -105,6 +113,12 @@ namespace Ryujinx.Graphics.OpenGL.Queries // A query's result only matters if more than one draw was performed during it. // Otherwise, dummy it out and return 0 immediately. + if (hostReserved) + { + // This counter event is guaranteed to be available for host conditional rendering. + _current.ReserveForHostAccess(); + } + if (draws > 0) { _current.Complete(true); @@ -175,25 +189,18 @@ namespace Ryujinx.Graphics.OpenGL.Queries public void FlushTo(CounterQueueEvent evt) { - lock (_lock) - { - if (evt.Disposed) - { - return; - } + // Flush the counter queue on the main thread. - // Tell the queue to process all events up to this one. - while (_events.Count > 0) - { - CounterQueueEvent flush = _events.Dequeue(); - flush.TryConsume(ref _accumulatedCounter, true); + Interlocked.Increment(ref _waiterCount); - if (flush == evt) - { - return; - } - } + _wakeSignal.Set(); + + while (!evt.Disposed) + { + _eventConsumed.WaitOne(1); } + + Interlocked.Decrement(ref _waiterCount); } public void Dispose() @@ -218,6 +225,10 @@ namespace Ryujinx.Graphics.OpenGL.Queries { query.Dispose(); } + + _queuedEvent.Dispose(); + _wakeSignal.Dispose(); + _eventConsumed.Dispose(); } } } |