aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Vulkan/Queries
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2023-01-24 16:32:56 +0000
committerGitHub <noreply@github.com>2023-01-24 13:32:56 -0300
commite7cf4e6eaf528aa72e27f6ba86259c00813bc776 (patch)
tree2d0a0c70a4e1cf20032b1b614452c7996e8f2dc8 /Ryujinx.Graphics.Vulkan/Queries
parenta1a4771ac1de95f2410c7fb8dfaf4a5986e5ebc6 (diff)
Vulkan: Reset queries on same command buffer (#4329)
* Reset queries on same command buffer Vulkan seems to complain when the queries are reset on another command buffer. No idea why, the spec really could be written better in this regard. This fixes complaints, and hopefully any implementations that care extensively about them. This change _guesses_ how many queries need to be reset and resets as many as possible at the same time to avoid splitting render passes. If it resets too many queries, we didn't waste too much time - if it runs out of resets it will batch reset 10 more. The number of queries reset is the maximum number of queries in the last 3 frames. This has been worked into the AutoFlushCounter so that it only resets up to 32 if it is yet to force a command buffer submission in this attachment. This is only done for samples passed queries right now, as they have by far the most resets. * Address Feedback
Diffstat (limited to 'Ryujinx.Graphics.Vulkan/Queries')
-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
4 files changed, 45 insertions, 9 deletions
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);