video_core: vulkan: Only store hashes in shader cache maps (#1710)
Some checks failed
citra-build / source (push) Has been cancelled
citra-build / linux (appimage) (push) Has been cancelled
citra-build / linux (appimage-wayland) (push) Has been cancelled
citra-build / linux (fresh) (push) Has been cancelled
citra-build / macos (arm64) (push) Has been cancelled
citra-build / macos (x86_64) (push) Has been cancelled
citra-build / windows (msvc) (push) Has been cancelled
citra-build / windows (msys2) (push) Has been cancelled
citra-build / android (googleplay) (push) Has been cancelled
citra-build / android (vanilla) (push) Has been cancelled
citra-build / docker (push) Has been cancelled
citra-format / clang-format (push) Has been cancelled
citra-transifex / transifex (push) Has been cancelled
citra-build / macos-universal (push) Has been cancelled

This commit is contained in:
PabloMK7 2026-02-02 18:25:03 +01:00 committed by GitHub
parent dd65ef4749
commit f010863ece
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 48 additions and 10 deletions

View File

@ -6,6 +6,7 @@
#include <cstddef>
#include <cstring>
#include <string>
#include <xxhash.h>
#include "cityhash.h"
#include "common/common_types.h"
@ -99,4 +100,38 @@ struct HashableStruct {
}
};
/// Helper struct that provides a hashable string with basic string API
template <typename Hasher = HashAlgo64::XXH3>
struct HashableString {
std::string value;
HashableString() = default;
HashableString(const std::string& s) : value(s) {}
HashableString(std::string&& s) noexcept : value(std::move(s)) {}
std::size_t Hash() const noexcept {
return ComputeHash64<Hasher>(value.data(), value.size());
}
bool empty() const noexcept {
return value.empty();
}
std::size_t size() const noexcept {
return value.size();
}
const char* data() const noexcept {
return value.data();
}
operator std::string_view() const noexcept {
return value;
}
operator std::string&&() && noexcept {
return std::move(value);
}
};
} // namespace Common

View File

@ -408,16 +408,18 @@ bool PipelineCache::UseProgrammableVertexShader(const Pica::RegsInternal& regs,
}
}
const auto [it, new_config] = programmable_vertex_map.try_emplace(config);
const auto config_hash = config.Hash();
const auto [it, new_config] = programmable_vertex_map.try_emplace(config_hash);
if (new_config) {
auto program = GLSL::GenerateVertexShader(setup, config, true);
auto program = Common::HashableString(GLSL::GenerateVertexShader(setup, config, true));
if (program.empty()) {
LOG_ERROR(Render_Vulkan, "Failed to retrieve programmable vertex shader");
programmable_vertex_map[config] = nullptr;
programmable_vertex_map[config_hash] = nullptr;
return false;
}
auto [iter, new_program] = programmable_vertex_cache.try_emplace(program, instance);
auto [iter, new_program] = programmable_vertex_cache.try_emplace(program.Hash(), instance);
auto& shader = iter->second;
if (new_program) {
@ -456,7 +458,7 @@ bool PipelineCache::UseFixedGeometryShader(const Pica::RegsInternal& regs) {
}
const PicaFixedGSConfig gs_config{regs, instance.IsShaderClipDistanceSupported()};
auto [it, new_shader] = fixed_geometry_shaders.try_emplace(gs_config, instance);
auto [it, new_shader] = fixed_geometry_shaders.try_emplace(gs_config.Hash(), instance);
auto& shader = it->second;
if (new_shader) {
@ -481,7 +483,7 @@ void PipelineCache::UseTrivialGeometryShader() {
void PipelineCache::UseFragmentShader(const Pica::RegsInternal& regs,
const Pica::Shader::UserConfig& user) {
const FSConfig fs_config{regs, user, profile};
const auto [it, new_shader] = fragment_shaders.try_emplace(fs_config, instance);
const auto [it, new_shader] = fragment_shaders.try_emplace(fs_config.Hash(), instance);
auto& shader = it->second;
if (new_shader) {

View File

@ -135,10 +135,11 @@ private:
std::array<u64, MAX_SHADER_STAGES> shader_hashes;
std::array<Shader*, MAX_SHADER_STAGES> current_shaders;
std::unordered_map<Pica::Shader::Generator::PicaVSConfig, Shader*> programmable_vertex_map;
std::unordered_map<std::string, Shader> programmable_vertex_cache;
std::unordered_map<Pica::Shader::Generator::PicaFixedGSConfig, Shader> fixed_geometry_shaders;
std::unordered_map<Pica::Shader::FSConfig, Shader> fragment_shaders;
std::unordered_map<size_t, Shader*> programmable_vertex_map;
std::unordered_map<size_t, Shader> programmable_vertex_cache;
std::unordered_map<size_t, Shader> fixed_geometry_shaders;
std::unordered_map<size_t, Shader> fragment_shaders;
Shader trivial_vertex_shader;
u64 current_program_id{0};