diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index be9b80c39b..ceb08ed7d9 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -109,10 +109,21 @@ void BufferCache
::TickFrame() { runtime.TickFrame(slot_buffers); native_indirect_uniforms_this_frame.clear(); if (frame_tick % 600 == 0 && !uploaded_buffer_ranges.empty()) { - for (const auto& [address, size] : uploaded_buffer_ranges) { - device_memory.HintCold(address, size); + // A range uploaded repeatedly in this window is still actively used by the guest. + // Avoid evicting it from the working set only to fault it back in shortly after. + auto& ranges = uploaded_buffer_ranges; + std::sort(ranges.begin(), ranges.end()); + for (size_t i = 0; i < ranges.size();) { + size_t next = i + 1; + while (next < ranges.size() && ranges[next] == ranges[i]) { + ++next; + } + if (next - i == 1) { + device_memory.HintCold(ranges[i].first, ranges[i].second); + } + i = next; } - uploaded_buffer_ranges.clear(); + ranges.clear(); } if (static u64 frames{}; ++frames % 600 == 0) { u64 total{}; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 1d4b4c82d0..c9cb4af90b 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -467,10 +467,21 @@ void TextureCache
::TickFrame() { TickAsyncDecode(); TickAsyncUnswizzle(); if (frame_tick % 600 == 0 && !uploaded_ranges.empty()) { - for (const auto& [address, size] : uploaded_ranges) { - device_memory.HintCold(address, size); + // A range uploaded repeatedly in this window is still actively used by the guest. + // Avoid evicting it from the working set only to fault it back in shortly after. + auto& ranges = uploaded_ranges; + std::sort(ranges.begin(), ranges.end()); + for (size_t i = 0; i < ranges.size();) { + size_t next = i + 1; + while (next < ranges.size() && ranges[next] == ranges[i]) { + ++next; + } + if (next - i == 1) { + device_memory.HintCold(ranges[i].first, ranges[i].second); + } + i = next; } - uploaded_ranges.clear(); + ranges.clear(); } runtime.TickFrame();