aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs')
-rw-r--r--Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs59
1 files changed, 58 insertions, 1 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs b/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs
index 0e1025af..8b0ae30e 100644
--- a/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs
+++ b/Ryujinx.Graphics.OpenGL/Queries/CounterQueueEvent.cs
@@ -1,4 +1,5 @@
using OpenTK.Graphics.OpenGL;
+using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using System;
using System.Threading;
@@ -21,7 +22,11 @@ namespace Ryujinx.Graphics.OpenGL.Queries
private CounterQueue _queue;
private BufferedQuery _counter;
+ private bool _hostAccessReserved = false;
+ private int _refCount = 1; // Starts with a reference from the counter queue.
+
private object _lock = new object();
+ private ulong _result = ulong.MaxValue;
public CounterQueueEvent(CounterQueue queue, QueryTarget type, ulong drawIndex)
{
@@ -76,6 +81,8 @@ namespace Ryujinx.Graphics.OpenGL.Queries
result += (ulong)queryResult;
+ _result = result;
+
OnResult?.Invoke(this, result);
Dispose(); // Return the our resources to the pool.
@@ -95,10 +102,60 @@ namespace Ryujinx.Graphics.OpenGL.Queries
_queue.FlushTo(this);
}
+ public void DecrementRefCount()
+ {
+ if (Interlocked.Decrement(ref _refCount) == 0)
+ {
+ DisposeInternal();
+ }
+ }
+
+ public bool ReserveForHostAccess()
+ {
+ if (_hostAccessReserved)
+ {
+ return true;
+ }
+
+ if (IsValueAvailable())
+ {
+ return false;
+ }
+
+ if (Interlocked.Increment(ref _refCount) == 1)
+ {
+ Interlocked.Decrement(ref _refCount);
+
+ return false;
+ }
+
+ _hostAccessReserved = true;
+
+ return true;
+ }
+
+ public void ReleaseHostAccess()
+ {
+ _hostAccessReserved = false;
+
+ DecrementRefCount();
+ }
+
+ private void DisposeInternal()
+ {
+ _queue.ReturnQueryObject(_counter);
+ }
+
+ private bool IsValueAvailable()
+ {
+ return _result != ulong.MaxValue || _counter.TryGetResult(out _);
+ }
+
public void Dispose()
{
Disposed = true;
- _queue.ReturnQueryObject(_counter);
+
+ DecrementRefCount();
}
}
}