From a2f93b0696b4c4d09af3dc53b027471f55b6a7e4 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 14 Jul 2021 01:34:00 +0300 Subject: [PATCH] rsx: Implement a simple cache eviction routine - Can remove all non-essential textures from the cache except those passed as an exclusion list --- rpcs3/Emu/RSX/Common/texture_cache.h | 49 ++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 24e5712d7d..030b3b6318 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -1453,6 +1453,55 @@ namespace rsx m_storage.trim_sections(); } + bool evict_unused(const std::set& exclusion_list) + { + // Manage synchronization externally. It is very likely for RSX to call this after failing to create a new texture while already owning the mutex + ensure(rsx::get_current_renderer()->is_current_thread()); + rsx_log.warning("[PERFORMANCE WARNING] Texture cache is running eviction routine. This will affect performance."); + + thrashed_set evicted_set; + const u32 type_to_evict = rsx::texture_upload_context::shader_read | rsx::texture_upload_context::blit_engine_src; + for (auto It = m_storage.begin(); It != m_storage.end(); ++It) + { + auto& block = *It; + if (block.empty()) + { + continue; + } + + for (auto& region : block) + { + if (region.is_dirty() || !(region.get_context() & type_to_evict)) + { + continue; + } + + ensure(region.is_locked()); + + const u32 this_address = region.get_section_base(); + if (exclusion_list.contains(this_address)) + { + continue; + } + + evicted_set.violation_handled = true; + region.set_dirty(true); + + if (region.is_locked(true)) + { + evicted_set.sections_to_unprotect.push_back(®ion); + } + else + { + region.discard(true); + } + } + } + + unprotect_set(evicted_set); + return evicted_set.violation_handled; + } + image_view_type create_temporary_subresource(commandbuffer_type &cmd, deferred_subresource& desc) { if (!desc.do_not_cache) [[likely]]