aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs32
-rw-r--r--Ryujinx.Graphics.Vulkan/PipelineBase.cs2
-rw-r--r--Ryujinx.Graphics.Vulkan/PipelineFull.cs30
-rw-r--r--Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs16
-rw-r--r--Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs23
-rw-r--r--Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs2
-rw-r--r--Ryujinx.Graphics.Vulkan/Queries/Counters.cs13
-rw-r--r--Ryujinx.Graphics.Vulkan/VulkanRenderer.cs10
-rw-r--r--Ryujinx.Graphics.Vulkan/Window.cs2
9 files changed, 97 insertions, 33 deletions
diff --git a/Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs b/Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs
index 4ba689cc..2a4cbd52 100644
--- a/Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs
+++ b/Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
+using System.Linq;
namespace Ryujinx.Graphics.Vulkan
{
@@ -16,6 +17,10 @@ namespace Ryujinx.Graphics.Vulkan
private bool _hasPendingQuery;
private int _queryCount;
+ private int[] _queryCountHistory = new int[3];
+ private int _queryCountHistoryIndex;
+ private int _remainingQueries;
+
public void RegisterFlush(ulong drawCount)
{
_lastFlush = Stopwatch.GetTimestamp();
@@ -27,6 +32,9 @@ namespace Ryujinx.Graphics.Vulkan
public bool RegisterPendingQuery()
{
_hasPendingQuery = true;
+ _remainingQueries--;
+
+ _queryCountHistory[_queryCountHistoryIndex]++;
// Interrupt render passes to flush queries, so that early results arrive sooner.
if (++_queryCount == InitialQueryCountForFlush)
@@ -37,6 +45,21 @@ namespace Ryujinx.Graphics.Vulkan
return false;
}
+ public int GetRemainingQueries()
+ {
+ if (_remainingQueries <= 0)
+ {
+ _remainingQueries = 16;
+ }
+
+ if (_queryCount < InitialQueryCountForFlush)
+ {
+ return Math.Min(InitialQueryCountForFlush - _queryCount, _remainingQueries);
+ }
+
+ return _remainingQueries;
+ }
+
public bool ShouldFlushQuery()
{
return _hasPendingQuery;
@@ -69,5 +92,14 @@ namespace Ryujinx.Graphics.Vulkan
return now > _lastFlush + flushTimeout;
}
+
+ public void Present()
+ {
+ _queryCountHistoryIndex = (_queryCountHistoryIndex + 1) % 3;
+
+ _remainingQueries = _queryCountHistory.Max() + 10;
+
+ _queryCountHistory[_queryCountHistoryIndex] = 0;
+ }
}
}
diff --git a/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/Ryujinx.Graphics.Vulkan/PipelineBase.cs
index 1c0c836b..c53acfe1 100644
--- a/Ryujinx.Graphics.Vulkan/PipelineBase.cs
+++ b/Ryujinx.Graphics.Vulkan/PipelineBase.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Vulkan
protected readonly Device Device;
public readonly PipelineCache PipelineCache;
- protected readonly AutoFlushCounter AutoFlush;
+ public readonly AutoFlushCounter AutoFlush;
protected PipelineDynamicState DynamicState;
private PipelineState _newState;
diff --git a/Ryujinx.Graphics.Vulkan/PipelineFull.cs b/Ryujinx.Graphics.Vulkan/PipelineFull.cs
index 5b4f4a6e..94fd2441 100644
--- a/Ryujinx.Graphics.Vulkan/PipelineFull.cs
+++ b/Ryujinx.Graphics.Vulkan/PipelineFull.cs
@@ -14,7 +14,6 @@ namespace Ryujinx.Graphics.Vulkan
private CounterQueueEvent _activeConditionalRender;
private readonly List<BufferedQuery> _pendingQueryCopies;
- private readonly List<BufferedQuery> _pendingQueryResets;
private ulong _byteWeight;
@@ -22,7 +21,6 @@ namespace Ryujinx.Graphics.Vulkan
{
_activeQueries = new List<QueryPool>();
_pendingQueryCopies = new();
- _pendingQueryResets = new List<BufferedQuery>();
CommandBuffer = (Cbs = gd.CommandBufferPool.Rent()).CommandBuffer;
}
@@ -34,16 +32,6 @@ namespace Ryujinx.Graphics.Vulkan
query.PoolCopy(Cbs);
}
- lock (_pendingQueryResets)
- {
- foreach (var query in _pendingQueryResets)
- {
- query.PoolReset(CommandBuffer);
- }
-
- _pendingQueryResets.Clear();
- }
-
_pendingQueryCopies.Clear();
}
@@ -238,10 +226,12 @@ namespace Ryujinx.Graphics.Vulkan
Gd.Api.CmdBeginQuery(CommandBuffer, queryPool, 0, Gd.Capabilities.SupportsPreciseOcclusionQueries ? QueryControlFlags.PreciseBit : 0);
}
+ Gd.ResetCounterPool();
+
Restore();
}
- public void BeginQuery(BufferedQuery query, QueryPool pool, bool needsReset)
+ public void BeginQuery(BufferedQuery query, QueryPool pool, bool needsReset, bool fromSamplePool)
{
if (needsReset)
{
@@ -249,9 +239,11 @@ namespace Ryujinx.Graphics.Vulkan
Gd.Api.CmdResetQueryPool(CommandBuffer, pool, 0, 1);
- lock (_pendingQueryResets)
+ if (fromSamplePool)
{
- _pendingQueryResets.Remove(query); // Might be present on here.
+ // Try reset some additional queries in advance.
+
+ Gd.ResetFutureCounters(CommandBuffer, AutoFlush.GetRemainingQueries());
}
}
@@ -267,14 +259,6 @@ namespace Ryujinx.Graphics.Vulkan
_activeQueries.Remove(pool);
}
- public void ResetQuery(BufferedQuery query)
- {
- lock (_pendingQueryResets)
- {
- _pendingQueryResets.Add(query);
- }
- }
-
public void CopyQueryResults(BufferedQuery query)
{
_pendingQueryCopies.Add(query);
diff --git a/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs b/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs
index 4cf258eb..a1a5eb27 100644
--- a/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs
+++ b/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs
@@ -18,7 +18,6 @@ namespace Ryujinx.Graphics.Vulkan.Queries
private readonly PipelineFull _pipeline;
private QueryPool _queryPool;
- private bool _isReset;
private readonly BufferHolder _buffer;
private readonly IntPtr _bufferMap;
@@ -27,6 +26,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
private bool _isSupported;
private long _defaultValue;
+ private int? _resetSequence;
public unsafe BufferedQuery(VulkanRenderer gd, Device device, PipelineFull pipeline, CounterType type, bool result32Bit)
{
@@ -92,16 +92,17 @@ namespace Ryujinx.Graphics.Vulkan.Queries
public void Reset()
{
End(false);
- Begin();
+ Begin(null);
}
- public void Begin()
+ public void Begin(int? resetSequence)
{
if (_isSupported)
{
- _pipeline.BeginQuery(this, _queryPool, !_isReset);
+ bool needsReset = resetSequence == null || _resetSequence == null || resetSequence.Value != _resetSequence.Value;
+ _pipeline.BeginQuery(this, _queryPool, needsReset, _type == CounterType.SamplesPassed && resetSequence != null);
}
- _isReset = false;
+ _resetSequence = null;
}
public unsafe void End(bool withResult)
@@ -162,13 +163,14 @@ namespace Ryujinx.Graphics.Vulkan.Queries
return data;
}
- public void PoolReset(CommandBuffer cmd)
+ public void PoolReset(CommandBuffer cmd, int resetSequence)
{
if (_isSupported)
{
_api.CmdResetQueryPool(cmd, _queryPool, 0, 1);
}
- _isReset = true;
+
+ _resetSequence = resetSequence;
}
public void PoolCopy(CommandBufferScoped cbs)
diff --git a/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs b/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs
index 7ee3c15a..c47f95ea 100644
--- a/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs
+++ b/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs
@@ -3,6 +3,7 @@ using Silk.NET.Vulkan;
using System;
using System.Collections.Generic;
using System.Threading;
+using System.Linq;
namespace Ryujinx.Graphics.Vulkan.Queries
{
@@ -32,6 +33,8 @@ namespace Ryujinx.Graphics.Vulkan.Queries
private Thread _consumerThread;
+ public int ResetSequence { get; private set; }
+
internal CounterQueue(VulkanRenderer gd, Device device, PipelineFull pipeline, CounterType type)
{
_gd = gd;
@@ -53,6 +56,24 @@ namespace Ryujinx.Graphics.Vulkan.Queries
_consumerThread.Start();
}
+ public void ResetCounterPool()
+ {
+ ResetSequence++;
+ }
+
+ public void ResetFutureCounters(CommandBuffer cmd, int count)
+ {
+ // Pre-emptively reset queries to avoid render pass splitting.
+ lock (_queryPool)
+ {
+ count = Math.Min(count, _queryPool.Count);
+ for (int i = 0; i < count; i++)
+ {
+ _queryPool.ElementAt(i).PoolReset(cmd, ResetSequence);
+ }
+ }
+ }
+
private void EventConsumer()
{
while (!Disposed)
@@ -106,7 +127,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
{
lock (_lock)
{
- _pipeline.ResetQuery(query);
+ // The query will be reset when it dequeues.
_queryPool.Enqueue(query);
}
}
diff --git a/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs b/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs
index 241fe1ee..6b780ba3 100644
--- a/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs
+++ b/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs
@@ -34,7 +34,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
DrawIndex = drawIndex;
- _counter.Begin();
+ _counter.Begin(_queue.ResetSequence);
}
public Auto<DisposableBuffer> GetBuffer()
diff --git a/Ryujinx.Graphics.Vulkan/Queries/Counters.cs b/Ryujinx.Graphics.Vulkan/Queries/Counters.cs
index 63581e42..7113d060 100644
--- a/Ryujinx.Graphics.Vulkan/Queries/Counters.cs
+++ b/Ryujinx.Graphics.Vulkan/Queries/Counters.cs
@@ -24,6 +24,19 @@ namespace Ryujinx.Graphics.Vulkan.Queries
}
}
+ public void ResetCounterPool()
+ {
+ foreach (var queue in _counterQueues)
+ {
+ queue.ResetCounterPool();
+ }
+ }
+
+ public void ResetFutureCounters(CommandBuffer cmd, int count)
+ {
+ _counterQueues[(int)CounterType.SamplesPassed].ResetFutureCounters(cmd, count);
+ }
+
public CounterQueueEvent QueueReport(CounterType type, EventHandler<ulong> resultHandler, bool hostReserved)
{
return _counterQueues[(int)type].QueueReport(resultHandler, _pipeline.DrawCount, hostReserved);
diff --git a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
index bec7b847..f53f7940 100644
--- a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
+++ b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
@@ -679,6 +679,16 @@ namespace Ryujinx.Graphics.Vulkan
_counters.Update();
}
+ public void ResetCounterPool()
+ {
+ _counters.ResetCounterPool();
+ }
+
+ public void ResetFutureCounters(CommandBuffer cmd, int count)
+ {
+ _counters?.ResetFutureCounters(cmd, count);
+ }
+
public void BackgroundContextAction(Action action, bool alwaysBackground = false)
{
action();
diff --git a/Ryujinx.Graphics.Vulkan/Window.cs b/Ryujinx.Graphics.Vulkan/Window.cs
index edc7d716..7412ad90 100644
--- a/Ryujinx.Graphics.Vulkan/Window.cs
+++ b/Ryujinx.Graphics.Vulkan/Window.cs
@@ -225,6 +225,8 @@ namespace Ryujinx.Graphics.Vulkan
public unsafe override void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
{
+ _gd.PipelineInternal.AutoFlush.Present();
+
uint nextImage = 0;
while (true)