Rework Query stuff a bit to avoid render pass end

Tries to reset returned queries in background when possible, rather than ending the render pass.

Still ends render pass when resetting a counter after draws, but maybe that can be solved too. (by just pulling an empty object off the pool?)
This commit is contained in:
riperiperi 2022-03-13 01:32:10 +00:00
parent eda65c8dd3
commit 4cc0c2132c
5 changed files with 77 additions and 25 deletions

View file

@ -13,31 +13,33 @@ namespace Ryujinx.Graphics.Vulkan
private readonly List<QueryPool> _activeQueries;
private CounterQueueEvent _activeConditionalRender;
private readonly List<(QueryPool Pool, BufferHolder Holder)> _pendingQueryCopies;
private readonly List<BufferedQuery> _pendingQueryCopies;
private readonly List<BufferedQuery> _pendingQueryResets;
public PipelineFull(VulkanGraphicsDevice gd, Device device) : base(gd, device)
{
_activeQueries = new List<QueryPool>();
_pendingQueryCopies = new();
_pendingQueryResets = new List<BufferedQuery>();
CommandBuffer = (Cbs = gd.CommandBufferPool.Rent()).CommandBuffer;
}
private void CopyPendingQuery()
{
foreach (var item in _pendingQueryCopies)
foreach (var query in _pendingQueryCopies)
{
var buffer = item.Holder.GetBuffer(CommandBuffer, true).Get(Cbs, 0, sizeof(long)).Value;
query.PoolCopy(Cbs);
}
Gd.Api.CmdCopyQueryPoolResults(
CommandBuffer,
item.Pool,
0,
1,
buffer,
0,
sizeof(long),
QueryResultFlags.QueryResult64Bit | QueryResultFlags.QueryResultWaitBit);
lock (_pendingQueryResets)
{
foreach (var query in _pendingQueryResets)
{
query.PoolReset(CommandBuffer);
}
_pendingQueryResets.Clear();
}
_pendingQueryCopies.Clear();
@ -295,18 +297,26 @@ namespace Ryujinx.Graphics.Vulkan
foreach (var queryPool in _activeQueries)
{
Gd.Api.CmdResetQueryPool(CommandBuffer, queryPool, 0, 1);
Gd.Api.CmdBeginQuery(CommandBuffer, queryPool, 0, 0);
}
SignalCommandBufferChange();
}
public void BeginQuery(QueryPool pool)
public void BeginQuery(BufferedQuery query, QueryPool pool, bool needsReset)
{
EndRenderPass();
if (needsReset)
{
EndRenderPass();
Gd.Api.CmdResetQueryPool(CommandBuffer, pool, 0, 1);
lock (_pendingQueryResets)
{
_pendingQueryResets.Remove(query); // Might be present on here.
}
}
Gd.Api.CmdResetQueryPool(CommandBuffer, pool, 0, 1);
Gd.Api.CmdBeginQuery(CommandBuffer, pool, 0, 0);
_activeQueries.Add(pool);
@ -319,9 +329,17 @@ namespace Ryujinx.Graphics.Vulkan
_activeQueries.Remove(pool);
}
public void CopyQueryResults(QueryPool pool, BufferHolder holder)
public void ResetQuery(BufferedQuery query)
{
_pendingQueryCopies.Add((pool, holder));
lock (_pendingQueryResets)
{
_pendingQueryResets.Add(query);
}
}
public void CopyQueryResults(BufferedQuery query)
{
_pendingQueryCopies.Add(query);
_hasPendingQuery = true;
}

View file

@ -17,6 +17,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
private readonly PipelineFull _pipeline;
private QueryPool _queryPool;
private bool _isReset;
private readonly BufferHolder _buffer;
private readonly IntPtr _bufferMap;
@ -73,7 +74,8 @@ namespace Ryujinx.Graphics.Vulkan.Queries
public void Begin()
{
_pipeline.BeginQuery(_queryPool);
_pipeline.BeginQuery(this, _queryPool, !_isReset);
_isReset = false;
}
public unsafe void End(bool withResult)
@ -83,7 +85,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
if (withResult)
{
Marshal.WriteInt64(_bufferMap, DefaultValue);
_pipeline.CopyQueryResults(_queryPool, _buffer);
_pipeline.CopyQueryResults(this);
}
else
{
@ -131,6 +133,27 @@ namespace Ryujinx.Graphics.Vulkan.Queries
return data;
}
public void PoolReset(CommandBuffer cmd)
{
_api.CmdResetQueryPool(cmd, _queryPool, 0, 1);
_isReset = true;
}
public void PoolCopy(CommandBufferScoped cbs)
{
var buffer = _buffer.GetBuffer(cbs.CommandBuffer, true).Get(cbs, 0, sizeof(long)).Value;
_api.CmdCopyQueryPoolResults(
cbs.CommandBuffer,
_queryPool,
0,
1,
buffer,
0,
sizeof(long),
QueryResultFlags.QueryResult64Bit | QueryResultFlags.QueryResultWaitBit);
}
public unsafe void Dispose()
{
_buffer.Dispose();

View file

@ -105,6 +105,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
{
lock (_lock)
{
_pipeline.ResetQuery(query);
_queryPool.Enqueue(query);
}
}
@ -140,11 +141,13 @@ namespace Ryujinx.Graphics.Vulkan.Queries
return result;
}
public void QueueReset()
public void QueueReset(ulong lastDrawIndex)
{
ulong draws = lastDrawIndex - _current.DrawIndex;
lock (_lock)
{
_current.Clear();
_current.Clear(draws != 0);
}
}

View file

@ -42,9 +42,13 @@ namespace Ryujinx.Graphics.Vulkan.Queries
return _counter.GetBuffer();
}
internal void Clear()
internal void Clear(bool counterReset)
{
_counter.Reset();
if (counterReset)
{
_counter.Reset();
}
ClearCounter = true;
}
@ -110,6 +114,10 @@ namespace Ryujinx.Graphics.Vulkan.Queries
{
DisposeInternal();
}
else
{
}
}
public bool ReserveForHostAccess()

View file

@ -31,7 +31,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
public void QueueReset(CounterType type)
{
_counterQueues[(int)type].QueueReset();
_counterQueues[(int)type].QueueReset(_pipeline.DrawCount);
}
public void Update()