From f8d31d1ae18c27be37590a7d15e5e7b691bed14f Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow <fsahmkow27@gmail.com>
Date: Sun, 23 Apr 2023 21:03:50 +0200
Subject: [PATCH] Buffer Cache: Release stagging buffers on tick frame

---
 src/video_core/buffer_cache/buffer_cache.h    | 28 ++++++++++++++-----
 .../buffer_cache/buffer_cache_base.h          |  6 +---
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 8fed08dab9..e5c626c364 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -22,7 +22,7 @@ BufferCache<P>::BufferCache(VideoCore::RasterizerInterface& rasterizer_,
     void(slot_buffers.insert(runtime, NullBufferParams{}));
     common_ranges.clear();
 
-    active_async_buffers = IMPLEMENTS_ASYNC_DOWNLOADS && !Settings::IsGPULevelHigh();
+    active_async_buffers = !Settings::IsGPULevelHigh();
 
     if (!runtime.CanReportMemoryUsage()) {
         minimum_memory = DEFAULT_EXPECTED_MEMORY;
@@ -74,7 +74,7 @@ void BufferCache<P>::TickFrame() {
     uniform_cache_hits[0] = 0;
     uniform_cache_shots[0] = 0;
 
-    active_async_buffers = IMPLEMENTS_ASYNC_DOWNLOADS && !Settings::IsGPULevelHigh();
+    active_async_buffers = !Settings::IsGPULevelHigh();
 
     const bool skip_preferred = hits * 256 < shots * 251;
     uniform_buffer_skip_cache_size = skip_preferred ? DEFAULT_SKIP_CACHE_SIZE : 0;
@@ -88,6 +88,13 @@ void BufferCache<P>::TickFrame() {
     }
     ++frame_tick;
     delayed_destruction_ring.Tick();
+
+    if constexpr (IMPLEMENTS_ASYNC_DOWNLOADS) {
+        for (auto& buffer : async_buffers_death_ring) {
+            runtime.FreeDeferredStagingBuffer(buffer);
+        }
+        async_buffers_death_ring.clear();
+    }
 }
 
 template <class P>
@@ -468,8 +475,10 @@ void BufferCache<P>::CommitAsyncFlushesHigh() {
     AccumulateFlushes();
 
     if (committed_ranges.empty()) {
-        if (active_async_buffers) {
-            async_buffers.emplace_back(std::optional<Async_Buffer>{});
+        if constexpr (IMPLEMENTS_ASYNC_DOWNLOADS) {
+            if (active_async_buffers) {
+                async_buffers.emplace_back(std::optional<Async_Buffer>{});
+            }
         }
         return;
     }
@@ -529,8 +538,10 @@ void BufferCache<P>::CommitAsyncFlushesHigh() {
     }
     committed_ranges.clear();
     if (downloads.empty()) {
-        if (active_async_buffers) {
-            async_buffers.emplace_back(std::optional<Async_Buffer>{});
+        if constexpr (IMPLEMENTS_ASYNC_DOWNLOADS) {
+            if (active_async_buffers) {
+                async_buffers.emplace_back(std::optional<Async_Buffer>{});
+            }
         }
         return;
     }
@@ -555,6 +566,9 @@ void BufferCache<P>::CommitAsyncFlushesHigh() {
             runtime.PostCopyBarrier();
             pending_downloads.emplace_back(std::move(normalized_copies));
             async_buffers.emplace_back(download_staging);
+        } else {
+            committed_ranges.clear();
+            uncommitted_ranges.clear();
         }
     } else {
         if constexpr (USE_MEMORY_MAPS) {
@@ -629,7 +643,7 @@ void BufferCache<P>::PopAsyncBuffers() {
             const IntervalType subtract_interval{cpu_addr, cpu_addr + copy.size};
             RemoveEachInOverlapCounter(async_downloads, subtract_interval, -1);
         }
-        runtime.FreeDeferredStagingBuffer(*async_buffer);
+        async_buffers_death_ring.emplace_back(*async_buffer);
         async_buffers.pop_front();
         pending_downloads.pop_front();
     }
diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h
index acff22d4f4..75cb98ba3e 100644
--- a/src/video_core/buffer_cache/buffer_cache_base.h
+++ b/src/video_core/buffer_cache/buffer_cache_base.h
@@ -554,11 +554,7 @@ private:
     std::deque<boost::container::small_vector<BufferCopy, 4>> pending_downloads;
     std::optional<Async_Buffer> current_buffer;
 
-    // queries
-    boost::container::small_vector<std::pair<VAddr, size_t>, 8> pending_queries;
-    std::deque<boost::container::small_vector<BufferCopy, 8>> committed_queries;
-    boost::container::small_vector<u64, 8> flushed_queries;
-    std::deque<std::optional<Async_Buffer>> query_async_buffers;
+    std::deque<Async_Buffer> async_buffers_death_ring;
 
     size_t immediate_buffer_capacity = 0;
     Common::ScratchBuffer<u8> immediate_buffer_alloc;