aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs73
-rw-r--r--Ryujinx.Graphics.Vulkan/PipelineBase.cs4
-rw-r--r--Ryujinx.Graphics.Vulkan/PipelineFull.cs16
3 files changed, 87 insertions, 6 deletions
diff --git a/Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs b/Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs
new file mode 100644
index 00000000..4ba689cc
--- /dev/null
+++ b/Ryujinx.Graphics.Vulkan/AutoFlushCounter.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Diagnostics;
+
+namespace Ryujinx.Graphics.Vulkan
+{
+ internal class AutoFlushCounter
+ {
+ // How often to flush on framebuffer change.
+ private readonly static long FramebufferFlushTimer = Stopwatch.Frequency / 1000;
+
+ private const int MinDrawCountForFlush = 10;
+ private const int InitialQueryCountForFlush = 32;
+
+ private long _lastFlush;
+ private ulong _lastDrawCount;
+ private bool _hasPendingQuery;
+ private int _queryCount;
+
+ public void RegisterFlush(ulong drawCount)
+ {
+ _lastFlush = Stopwatch.GetTimestamp();
+ _lastDrawCount = drawCount;
+
+ _hasPendingQuery = false;
+ }
+
+ public bool RegisterPendingQuery()
+ {
+ _hasPendingQuery = true;
+
+ // Interrupt render passes to flush queries, so that early results arrive sooner.
+ if (++_queryCount == InitialQueryCountForFlush)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public bool ShouldFlushQuery()
+ {
+ return _hasPendingQuery;
+ }
+
+ public bool ShouldFlush(ulong drawCount)
+ {
+ _queryCount = 0;
+
+ if (_hasPendingQuery)
+ {
+ return true;
+ }
+
+ long draws = (long)(drawCount - _lastDrawCount);
+
+ if (draws < MinDrawCountForFlush)
+ {
+ if (draws == 0)
+ {
+ _lastFlush = Stopwatch.GetTimestamp();
+ }
+
+ return false;
+ }
+
+ long flushTimeout = FramebufferFlushTimer;
+
+ long now = Stopwatch.GetTimestamp();
+
+ return now > _lastFlush + flushTimeout;
+ }
+ }
+}
diff --git a/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/Ryujinx.Graphics.Vulkan/PipelineBase.cs
index 769d4594..5c666b09 100644
--- a/Ryujinx.Graphics.Vulkan/PipelineBase.cs
+++ b/Ryujinx.Graphics.Vulkan/PipelineBase.cs
@@ -19,6 +19,8 @@ namespace Ryujinx.Graphics.Vulkan
protected readonly Device Device;
public readonly PipelineCache PipelineCache;
+ protected readonly AutoFlushCounter AutoFlush;
+
private PipelineDynamicState _dynamicState;
private PipelineState _newState;
private bool _stateDirty;
@@ -70,6 +72,8 @@ namespace Ryujinx.Graphics.Vulkan
Gd = gd;
Device = device;
+ AutoFlush = new AutoFlushCounter();
+
var pipelineCacheCreateInfo = new PipelineCacheCreateInfo()
{
SType = StructureType.PipelineCacheCreateInfo
diff --git a/Ryujinx.Graphics.Vulkan/PipelineFull.cs b/Ryujinx.Graphics.Vulkan/PipelineFull.cs
index ca3a33ef..c8692993 100644
--- a/Ryujinx.Graphics.Vulkan/PipelineFull.cs
+++ b/Ryujinx.Graphics.Vulkan/PipelineFull.cs
@@ -10,8 +10,6 @@ namespace Ryujinx.Graphics.Vulkan
{
private const ulong MinByteWeightForFlush = 256 * 1024 * 1024; // MB
- private bool _hasPendingQuery;
-
private readonly List<QueryPool> _activeQueries;
private CounterQueueEvent _activeConditionalRender;
@@ -158,9 +156,8 @@ namespace Ryujinx.Graphics.Vulkan
private void FlushPendingQuery()
{
- if (_hasPendingQuery)
+ if (AutoFlush.ShouldFlushQuery())
{
- _hasPendingQuery = false;
FlushCommandsImpl();
}
}
@@ -211,6 +208,7 @@ namespace Ryujinx.Graphics.Vulkan
public void FlushCommandsImpl()
{
+ AutoFlush.RegisterFlush(DrawCount);
EndRenderPass();
foreach (var queryPool in _activeQueries)
@@ -277,12 +275,18 @@ namespace Ryujinx.Graphics.Vulkan
{
_pendingQueryCopies.Add(query);
- _hasPendingQuery = true;
+ if (AutoFlush.RegisterPendingQuery())
+ {
+ FlushCommandsImpl();
+ }
}
protected override void SignalAttachmentChange()
{
- FlushPendingQuery();
+ if (AutoFlush.ShouldFlush(DrawCount))
+ {
+ FlushCommandsImpl();
+ }
}
protected override void SignalRenderPassEnd()