1
0
Fork 0
mirror of https://github.com/Ryujinx/Ryujinx.git synced 2024-10-01 12:30:00 +02:00

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:
riperiperi 2023-02-09 01:03:41 +00:00 committed by GitHub
parent f614d2c435
commit b3f0978869
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 10 additions and 3 deletions

View file

@ -10,11 +10,13 @@ namespace Ryujinx.Graphics.Vulkan
private readonly static long FramebufferFlushTimer = Stopwatch.Frequency / 1000;
private const int MinDrawCountForFlush = 10;
private const int MinConsecutiveQueryForFlush = 10;
private const int InitialQueryCountForFlush = 32;
private long _lastFlush;
private ulong _lastDrawCount;
private bool _hasPendingQuery;
private int _consecutiveQueries;
private int _queryCount;
private int[] _queryCountHistory = new int[3];
@ -27,11 +29,13 @@ namespace Ryujinx.Graphics.Vulkan
_lastDrawCount = drawCount;
_hasPendingQuery = false;
_consecutiveQueries = 0;
}
public bool RegisterPendingQuery()
{
_hasPendingQuery = true;
_consecutiveQueries++;
_remainingQueries--;
_queryCountHistory[_queryCountHistoryIndex]++;
@ -65,15 +69,18 @@ namespace Ryujinx.Graphics.Vulkan
return _hasPendingQuery;
}
public bool ShouldFlush(ulong drawCount)
public bool ShouldFlushAttachmentChange(ulong drawCount)
{
_queryCount = 0;
if (_hasPendingQuery)
// Flush when there's an attachment change out of a large block of queries.
if (_consecutiveQueries > MinConsecutiveQueryForFlush)
{
return true;
}
_consecutiveQueries = 0;
long draws = (long)(drawCount - _lastDrawCount);
if (draws < MinDrawCountForFlush)

View file

@ -281,7 +281,7 @@ namespace Ryujinx.Graphics.Vulkan
protected override void SignalAttachmentChange()
{
if (AutoFlush.ShouldFlush(DrawCount))
if (AutoFlush.ShouldFlushAttachmentChange(DrawCount))
{
FlushCommandsImpl();
}