forked from Mirror/Ryujinx
Vulkan: Flush command buffers for queries less aggressively (#4387)
The AutoFlushCounter would flush command buffers on any attachment change (write mask or bindings change) if there was a pending query. This is to get query results as soon as possible for draw skips, but it's assuming that a full occlusion query _pass_ happened, that we want to flush it's data before getting onto draws, rather than the queries being randomly interspersed throughout a pass that also draws. Xenoblade 2 repeatedly switches between performing a samples passed query and outputting to a render target on each draw, and flips the write mask to do so. Flushing the command buffer every 2 draws isn't ideal, so it's best that we only do this if the pattern matches the large block style of occlusion query. This change makes this flush only happen after a few consecutive query reports. "Consecutive" is interrupted by attachment changes or command buffer flush. This doesn't really solve the issue where it resets more queries than it uses, it just stops the game doing it as often. I'm not sure of the best way to do that. The cost of resetting could probably be reduced by using query pools with more than one element and resetting in bulk.
This commit is contained in:
parent
f614d2c435
commit
b3f0978869
2 changed files with 10 additions and 3 deletions
|
@ -10,11 +10,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private readonly static long FramebufferFlushTimer = Stopwatch.Frequency / 1000;
|
private readonly static long FramebufferFlushTimer = Stopwatch.Frequency / 1000;
|
||||||
|
|
||||||
private const int MinDrawCountForFlush = 10;
|
private const int MinDrawCountForFlush = 10;
|
||||||
|
private const int MinConsecutiveQueryForFlush = 10;
|
||||||
private const int InitialQueryCountForFlush = 32;
|
private const int InitialQueryCountForFlush = 32;
|
||||||
|
|
||||||
private long _lastFlush;
|
private long _lastFlush;
|
||||||
private ulong _lastDrawCount;
|
private ulong _lastDrawCount;
|
||||||
private bool _hasPendingQuery;
|
private bool _hasPendingQuery;
|
||||||
|
private int _consecutiveQueries;
|
||||||
private int _queryCount;
|
private int _queryCount;
|
||||||
|
|
||||||
private int[] _queryCountHistory = new int[3];
|
private int[] _queryCountHistory = new int[3];
|
||||||
|
@ -27,11 +29,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_lastDrawCount = drawCount;
|
_lastDrawCount = drawCount;
|
||||||
|
|
||||||
_hasPendingQuery = false;
|
_hasPendingQuery = false;
|
||||||
|
_consecutiveQueries = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RegisterPendingQuery()
|
public bool RegisterPendingQuery()
|
||||||
{
|
{
|
||||||
_hasPendingQuery = true;
|
_hasPendingQuery = true;
|
||||||
|
_consecutiveQueries++;
|
||||||
_remainingQueries--;
|
_remainingQueries--;
|
||||||
|
|
||||||
_queryCountHistory[_queryCountHistoryIndex]++;
|
_queryCountHistory[_queryCountHistoryIndex]++;
|
||||||
|
@ -65,15 +69,18 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return _hasPendingQuery;
|
return _hasPendingQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ShouldFlush(ulong drawCount)
|
public bool ShouldFlushAttachmentChange(ulong drawCount)
|
||||||
{
|
{
|
||||||
_queryCount = 0;
|
_queryCount = 0;
|
||||||
|
|
||||||
if (_hasPendingQuery)
|
// Flush when there's an attachment change out of a large block of queries.
|
||||||
|
if (_consecutiveQueries > MinConsecutiveQueryForFlush)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_consecutiveQueries = 0;
|
||||||
|
|
||||||
long draws = (long)(drawCount - _lastDrawCount);
|
long draws = (long)(drawCount - _lastDrawCount);
|
||||||
|
|
||||||
if (draws < MinDrawCountForFlush)
|
if (draws < MinDrawCountForFlush)
|
||||||
|
|
|
@ -281,7 +281,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
protected override void SignalAttachmentChange()
|
protected override void SignalAttachmentChange()
|
||||||
{
|
{
|
||||||
if (AutoFlush.ShouldFlush(DrawCount))
|
if (AutoFlush.ShouldFlushAttachmentChange(DrawCount))
|
||||||
{
|
{
|
||||||
FlushCommandsImpl();
|
FlushCommandsImpl();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue