From 655725b1ec46f1f6f42acd1944a0e0c1301bb644 Mon Sep 17 00:00:00 2001
From: yuzubot <yuzu@yuzu-emu.org>
Date: Sun, 25 Feb 2024 13:07:00 +0000
Subject: [PATCH] "Merge Tagged PR 13096"

---
 src/video_core/texture_cache/texture_cache.h | 30 +++++++++++++++-----
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 53b4876f2..67487b463 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -72,12 +72,19 @@ TextureCache<P>::TextureCache(Runtime& runtime_, Tegra::MaxwellDeviceMemoryManag
 
 template <class P>
 void TextureCache<P>::RunGarbageCollector() {
-    bool high_priority_mode = total_used_memory >= expected_memory;
-    bool aggressive_mode = total_used_memory >= critical_memory;
-    const u64 ticks_to_destroy = aggressive_mode ? 10ULL : high_priority_mode ? 25ULL : 50ULL;
-    size_t num_iterations = aggressive_mode ? 40 : (high_priority_mode ? 20 : 10);
-    const auto clean_up = [this, &num_iterations, &high_priority_mode,
-                           &aggressive_mode](ImageId image_id) {
+    bool high_priority_mode = false;
+    bool aggressive_mode = false;
+    u64 ticks_to_destroy = 0;
+    size_t num_iterations = 0;
+
+    const auto Configure = [&](bool allow_aggressive) {
+        high_priority_mode = total_used_memory >= expected_memory;
+        aggressive_mode = allow_aggressive && total_used_memory >= critical_memory;
+        ticks_to_destroy = aggressive_mode ? 10ULL : high_priority_mode ? 25ULL : 50ULL;
+        num_iterations = aggressive_mode ? 40 : (high_priority_mode ? 20 : 10);
+    };
+    const auto Cleanup = [this, &num_iterations, &high_priority_mode,
+                          &aggressive_mode](ImageId image_id) {
         if (num_iterations == 0) {
             return true;
         }
@@ -123,7 +130,16 @@ void TextureCache<P>::RunGarbageCollector() {
         }
         return false;
     };
-    lru_cache.ForEachItemBelow(frame_tick - ticks_to_destroy, clean_up);
+
+    // Try to remove anything old enough and not high priority.
+    Configure(false);
+    lru_cache.ForEachItemBelow(frame_tick - ticks_to_destroy, Cleanup);
+
+    // If pressure is still too high, prune aggressively.
+    if (total_used_memory >= critical_memory) {
+        Configure(true);
+        lru_cache.ForEachItemBelow(frame_tick - ticks_to_destroy, Cleanup);
+    }
 }
 
 template <class P>