diff --git a/Ryujinx.Graphics.Vulkan/PipelineFull.cs b/Ryujinx.Graphics.Vulkan/PipelineFull.cs index 06336da2e..08c36a591 100644 --- a/Ryujinx.Graphics.Vulkan/PipelineFull.cs +++ b/Ryujinx.Graphics.Vulkan/PipelineFull.cs @@ -13,31 +13,33 @@ namespace Ryujinx.Graphics.Vulkan private readonly List _activeQueries; private CounterQueueEvent _activeConditionalRender; - private readonly List<(QueryPool Pool, BufferHolder Holder)> _pendingQueryCopies; + private readonly List _pendingQueryCopies; + private readonly List _pendingQueryResets; public PipelineFull(VulkanGraphicsDevice gd, Device device) : base(gd, device) { _activeQueries = new List(); _pendingQueryCopies = new(); + _pendingQueryResets = new List(); 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; } diff --git a/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs b/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs index dd2f348fe..2a5701579 100644 --- a/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs +++ b/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs @@ -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(); diff --git a/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs b/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs index d32ae2ec4..8ad2dd634 100644 --- a/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs +++ b/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs @@ -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); } } diff --git a/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs b/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs index 9f8612939..9a5a3bb69 100644 --- a/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs +++ b/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs @@ -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() diff --git a/Ryujinx.Graphics.Vulkan/Queries/Counters.cs b/Ryujinx.Graphics.Vulkan/Queries/Counters.cs index 79b56381e..43b44d2d4 100644 --- a/Ryujinx.Graphics.Vulkan/Queries/Counters.cs +++ b/Ryujinx.Graphics.Vulkan/Queries/Counters.cs @@ -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()