mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-02-22 17:10:19 +00:00
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:
parent
eda65c8dd3
commit
4cc0c2132c
5 changed files with 77 additions and 25 deletions
|
@ -13,31 +13,33 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private readonly List<QueryPool> _activeQueries;
|
private readonly List<QueryPool> _activeQueries;
|
||||||
private CounterQueueEvent _activeConditionalRender;
|
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)
|
public PipelineFull(VulkanGraphicsDevice gd, Device device) : base(gd, device)
|
||||||
{
|
{
|
||||||
_activeQueries = new List<QueryPool>();
|
_activeQueries = new List<QueryPool>();
|
||||||
_pendingQueryCopies = new();
|
_pendingQueryCopies = new();
|
||||||
|
_pendingQueryResets = new List<BufferedQuery>();
|
||||||
|
|
||||||
CommandBuffer = (Cbs = gd.CommandBufferPool.Rent()).CommandBuffer;
|
CommandBuffer = (Cbs = gd.CommandBufferPool.Rent()).CommandBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CopyPendingQuery()
|
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(
|
lock (_pendingQueryResets)
|
||||||
CommandBuffer,
|
{
|
||||||
item.Pool,
|
foreach (var query in _pendingQueryResets)
|
||||||
0,
|
{
|
||||||
1,
|
query.PoolReset(CommandBuffer);
|
||||||
buffer,
|
}
|
||||||
0,
|
|
||||||
sizeof(long),
|
_pendingQueryResets.Clear();
|
||||||
QueryResultFlags.QueryResult64Bit | QueryResultFlags.QueryResultWaitBit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_pendingQueryCopies.Clear();
|
_pendingQueryCopies.Clear();
|
||||||
|
@ -295,18 +297,26 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
foreach (var queryPool in _activeQueries)
|
foreach (var queryPool in _activeQueries)
|
||||||
{
|
{
|
||||||
Gd.Api.CmdResetQueryPool(CommandBuffer, queryPool, 0, 1);
|
|
||||||
Gd.Api.CmdBeginQuery(CommandBuffer, queryPool, 0, 0);
|
Gd.Api.CmdBeginQuery(CommandBuffer, queryPool, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SignalCommandBufferChange();
|
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);
|
Gd.Api.CmdBeginQuery(CommandBuffer, pool, 0, 0);
|
||||||
|
|
||||||
_activeQueries.Add(pool);
|
_activeQueries.Add(pool);
|
||||||
|
@ -319,9 +329,17 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_activeQueries.Remove(pool);
|
_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;
|
_hasPendingQuery = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
private readonly PipelineFull _pipeline;
|
private readonly PipelineFull _pipeline;
|
||||||
|
|
||||||
private QueryPool _queryPool;
|
private QueryPool _queryPool;
|
||||||
|
private bool _isReset;
|
||||||
|
|
||||||
private readonly BufferHolder _buffer;
|
private readonly BufferHolder _buffer;
|
||||||
private readonly IntPtr _bufferMap;
|
private readonly IntPtr _bufferMap;
|
||||||
|
@ -73,7 +74,8 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
|
|
||||||
public void Begin()
|
public void Begin()
|
||||||
{
|
{
|
||||||
_pipeline.BeginQuery(_queryPool);
|
_pipeline.BeginQuery(this, _queryPool, !_isReset);
|
||||||
|
_isReset = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void End(bool withResult)
|
public unsafe void End(bool withResult)
|
||||||
|
@ -83,7 +85,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
if (withResult)
|
if (withResult)
|
||||||
{
|
{
|
||||||
Marshal.WriteInt64(_bufferMap, DefaultValue);
|
Marshal.WriteInt64(_bufferMap, DefaultValue);
|
||||||
_pipeline.CopyQueryResults(_queryPool, _buffer);
|
_pipeline.CopyQueryResults(this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -131,6 +133,27 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
return data;
|
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()
|
public unsafe void Dispose()
|
||||||
{
|
{
|
||||||
_buffer.Dispose();
|
_buffer.Dispose();
|
||||||
|
|
|
@ -105,6 +105,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
{
|
{
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
|
_pipeline.ResetQuery(query);
|
||||||
_queryPool.Enqueue(query);
|
_queryPool.Enqueue(query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,11 +141,13 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueueReset()
|
public void QueueReset(ulong lastDrawIndex)
|
||||||
{
|
{
|
||||||
|
ulong draws = lastDrawIndex - _current.DrawIndex;
|
||||||
|
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
_current.Clear();
|
_current.Clear(draws != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,9 +42,13 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
return _counter.GetBuffer();
|
return _counter.GetBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Clear()
|
internal void Clear(bool counterReset)
|
||||||
{
|
{
|
||||||
_counter.Reset();
|
if (counterReset)
|
||||||
|
{
|
||||||
|
_counter.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
ClearCounter = true;
|
ClearCounter = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,6 +114,10 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
{
|
{
|
||||||
DisposeInternal();
|
DisposeInternal();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ReserveForHostAccess()
|
public bool ReserveForHostAccess()
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
|
|
||||||
public void QueueReset(CounterType type)
|
public void QueueReset(CounterType type)
|
||||||
{
|
{
|
||||||
_counterQueues[(int)type].QueueReset();
|
_counterQueues[(int)type].QueueReset(_pipeline.DrawCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
|
|
Loading…
Reference in a new issue