From 2779da323b3364da9464c8653b1991d7419b9527 Mon Sep 17 00:00:00 2001 From: jbm11208 <81182113+jbm11208@users.noreply.github.com> Date: Sun, 11 May 2025 23:51:26 -0400 Subject: [PATCH] Implement LRU-based shader cache eviction and size limit in JIT engine --- src/video_core/shader/shader_jit.cpp | 27 +++++++++++++++++++++++++-- src/video_core/shader/shader_jit.h | 10 +++++++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/video_core/shader/shader_jit.cpp b/src/video_core/shader/shader_jit.cpp index 644586226..3f34e568d 100644 --- a/src/video_core/shader/shader_jit.cpp +++ b/src/video_core/shader/shader_jit.cpp @@ -1,4 +1,4 @@ -// Copyright 2016 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -28,19 +28,42 @@ void JitEngine::SetupBatch(ShaderSetup& setup, u32 entry_point) { const u64 code_hash = setup.GetProgramCodeHash(); const u64 swizzle_hash = setup.GetSwizzleDataHash(); - const u64 cache_key = Common::HashCombine(code_hash, swizzle_hash); + + std::lock_guard lock(cache_mutex); auto iter = cache.find(cache_key); if (iter != cache.end()) { setup.cached_shader = iter->second.get(); + UpdateLRU(cache_key); } else { + if (cache.size() >= MAX_CACHE_SIZE) { + EvictLRU(); + } auto shader = std::make_unique(); shader->Compile(&setup.program_code, &setup.swizzle_data); setup.cached_shader = shader.get(); cache.emplace_hint(iter, cache_key, std::move(shader)); + lru_list.push_front(cache_key); } } +void JitEngine::EvictLRU() { + if (lru_list.empty()) { + return; + } + const u64 key = lru_list.back(); + lru_list.pop_back(); + cache.erase(key); +} + +void JitEngine::UpdateLRU(u64 key) { + auto it = std::find(lru_list.begin(), lru_list.end(), key); + if (it != lru_list.end()) { + lru_list.erase(it); + } + lru_list.push_front(key); +} + MICROPROFILE_DECLARE(GPU_Shader); void JitEngine::Run(const ShaderSetup& setup, ShaderUnit& state) const { diff --git a/src/video_core/shader/shader_jit.h b/src/video_core/shader/shader_jit.h index 2f3e77b02..912fc5fe2 100644 --- a/src/video_core/shader/shader_jit.h +++ b/src/video_core/shader/shader_jit.h @@ -1,4 +1,4 @@ -// Copyright 2016 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -7,7 +7,9 @@ #include "common/arch.h" #if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64) +#include #include +#include #include #include "common/common_types.h" #include "video_core/shader/shader.h" @@ -25,7 +27,13 @@ public: void Run(const ShaderSetup& setup, ShaderUnit& state) const override; private: + static constexpr size_t MAX_CACHE_SIZE = 1000; // Maximum number of shaders to cache std::unordered_map> cache; + std::list lru_list; // Track LRU order of shaders + mutable std::mutex cache_mutex; + + void EvictLRU(); + void UpdateLRU(u64 key); }; } // namespace Pica::Shader