Implement LRU-based shader cache eviction and size limit in JIT engine

This commit is contained in:
jbm11208 2025-05-11 23:51:26 -04:00 committed by OpenSauce
parent 3e5e981c93
commit 2779da323b
2 changed files with 34 additions and 3 deletions

View File

@ -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<std::mutex> 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<JitShader>();
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 {

View File

@ -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 <list>
#include <memory>
#include <mutex>
#include <unordered_map>
#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<u64, std::unique_ptr<JitShader>> cache;
std::list<u64> lru_list; // Track LRU order of shaders
mutable std::mutex cache_mutex;
void EvictLRU();
void UpdateLRU(u64 key);
};
} // namespace Pica::Shader