aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs')
-rw-r--r--Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs47
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();
}
}
}