From 2bb0f8acdf79816ae1c474c42e2b63dbaa4500e8 Mon Sep 17 00:00:00 2001 From: Takoroka <137927095+Takoroka@users.noreply.github.com> Date: Thu, 29 Oct 2026 00:54:03 -0400 Subject: texture_cache: Switch 2 collector thresholds follow the device memory budget Native titles' thresholds came from Eden's device memory figure, which is capped near 7 GB: on a tester's RTX 4070 SUPER (11.2 GB budget) title 1 kept evicting 800-1,600 textures per 600 frames with 3 GB unused. They now follow the budget (critical at budget - 768 MiB, expected at budget - 1536 MiB, re-read every 60 frames); the EDEN_NX2_TC_* overrides still win, and the thresholds are logged only when they move by 256 MiB. --- src/video_core/texture_cache/texture_cache.h | 27 ++++++++++++++++------- src/video_core/texture_cache/texture_cache_base.h | 2 +- 2 files changed, 20 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index ad1804877a..13dfbba20e 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -175,7 +175,7 @@ void TextureCache
::RunGarbageCollector() {
}
template ::ApplyThresholdOverrides() {
+void TextureCache ::ApplyThresholdOverrides(bool log) {
// EDEN_NX2_TC_EXPECTED_MIB / EDEN_NX2_TC_CRITICAL_MIB override the collector's thresholds.
for (const auto& [name, target] : {std::pair{"EDEN_NX2_TC_EXPECTED_MIB", &expected_memory},
std::pair{"EDEN_NX2_TC_CRITICAL_MIB", &critical_memory}}) {
@@ -183,8 +183,10 @@ void TextureCache ::ApplyThresholdOverrides() {
*target = std::strtoull(value, nullptr, 10) << 20;
}
}
- LOG_INFO(HW_GPU, "Texture cache thresholds: expected {} MiB, critical {} MiB, minimum {} MiB",
- expected_memory >> 20, critical_memory >> 20, minimum_memory >> 20);
+ if (log) {
+ LOG_INFO(HW_GPU, "Texture cache thresholds: expected {} MiB, critical {} MiB, minimum {} MiB",
+ expected_memory >> 20, critical_memory >> 20, minimum_memory >> 20);
+ }
}
template ::TickFrame() {
native_critical_memory = critical_memory;
native_expected_memory = expected_memory;
}
- // The budget shrinks when other programs use VRAM (another game: 7.0 -> 6.4 GB), and
- // collecting only past it means the driver pages textures out. Re-read it now and then.
+ // Follow the driver's budget (re-read now and then): it shrinks when other programs use
+ // VRAM (another game: 7.0 -> 6.4 GB), and collecting only past it means the driver pages
+ // textures out. It is also the room to use: Eden's device memory figure is capped near
+ // 7 GB, which on a 12 GB card (11.2 GB budget) kept title 1 evicting textures with 3 GB
+ // unused. EDEN_NX2_TC_*_MIB overrides still win.
if constexpr (requires { runtime.GetDeviceMemoryBudget(); }) {
- if (native_thresholds_applied && ++budget_check_frames % 60 == 0) {
+ if (native_thresholds_applied && budget_check_frames++ % 60 == 0) {
const u64 budget = runtime.GetDeviceMemoryBudget();
if (budget > 2_GiB) {
- critical_memory = (std::min)(native_critical_memory, budget - 512_MiB);
- expected_memory = (std::min)(native_expected_memory, budget - 1280_MiB);
+ const u64 old_critical = critical_memory;
+ critical_memory = budget - 768_MiB;
+ expected_memory = budget - 1536_MiB;
+ // Log only real changes (the budget moves by a few MiB all the time).
+ const u64 change = critical_memory > old_critical
+ ? critical_memory - old_critical
+ : old_critical - critical_memory;
+ ApplyThresholdOverrides(change >= 256_MiB);
}
}
}
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index ce1de8e867..3c96c91a93 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -467,7 +467,7 @@ private:
DAddr virtual_invalid_space{};
/// Applies EDEN_NX2_TC_EXPECTED_MIB / EDEN_NX2_TC_CRITICAL_MIB and logs the thresholds.
- void ApplyThresholdOverrides();
+ void ApplyThresholdOverrides(bool log = true);
/// The CPU address an image at gpu_addr is keyed by: its backing, or a fixed stand-in.
[[nodiscard]] std::optional