vk_shader_cache: Small cleanup
This commit is contained in:
parent
93db0625f6
commit
dbb9e457ea
|
@ -161,16 +161,17 @@ void PipelineCache::RefreshGraphicsKey() {
|
|||
continue;
|
||||
}
|
||||
const auto stage = Shader::Stage{i};
|
||||
const GuestProgram guest_pgm{pgm, stage};
|
||||
std::tie(infos[i], modules[i], key.stage_hashes[i]) =
|
||||
shader_cache->GetProgram(pgm, stage, binding);
|
||||
shader_cache->GetProgram(guest_pgm, binding);
|
||||
}
|
||||
}
|
||||
|
||||
void PipelineCache::RefreshComputeKey() {
|
||||
u32 binding{};
|
||||
const auto* cs_pgm = &liverpool->regs.cs_program;
|
||||
std::tie(infos[0], modules[0], compute_key) =
|
||||
shader_cache->GetProgram(cs_pgm, Shader::Stage::Compute, binding);
|
||||
const GuestProgram guest_pgm{cs_pgm, Shader::Stage::Compute};
|
||||
std::tie(infos[0], modules[0], compute_key) = shader_cache->GetProgram(guest_pgm, binding);
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
|
|
|
@ -59,14 +59,13 @@ void BuildVsOutputs(Shader::Info& info, const AmdGpu::Liverpool::VsOutputControl
|
|||
: (ctl.IsCullDistEnabled(7) ? VsOutput::CullDist7 : VsOutput::None));
|
||||
}
|
||||
|
||||
Shader::Info MakeShaderInfo(Shader::Stage stage, std::span<const u32, 16> user_data, u64 pgm_base,
|
||||
u64 hash, const AmdGpu::Liverpool::Regs& regs) {
|
||||
Shader::Info MakeShaderInfo(const GuestProgram& pgm, const AmdGpu::Liverpool::Regs& regs) {
|
||||
Shader::Info info{};
|
||||
info.user_data = user_data;
|
||||
info.pgm_base = pgm_base;
|
||||
info.pgm_hash = hash;
|
||||
info.stage = stage;
|
||||
switch (stage) {
|
||||
info.user_data = pgm.user_data;
|
||||
info.pgm_base = VAddr(pgm.code.data());
|
||||
info.pgm_hash = pgm.hash;
|
||||
info.stage = pgm.stage;
|
||||
switch (pgm.stage) {
|
||||
case Shader::Stage::Vertex: {
|
||||
info.num_user_data = regs.vs_program.settings.num_user_regs;
|
||||
info.num_input_vgprs = regs.vs_program.settings.vgpr_comp_cnt;
|
||||
|
@ -101,6 +100,10 @@ Shader::Info MakeShaderInfo(Shader::Stage stage, std::span<const u32, 16> user_d
|
|||
return info;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline u64 HashCombine(const u64 seed, const u64 hash) {
|
||||
return seed ^ (hash + 0x9e3779b9 + (seed << 6) + (seed >> 2));
|
||||
}
|
||||
|
||||
ShaderCache::ShaderCache(const Instance& instance_, AmdGpu::Liverpool* liverpool_)
|
||||
: instance{instance_}, liverpool{liverpool_}, inst_pool{8192}, block_pool{512} {
|
||||
profile = Shader::Profile{
|
||||
|
@ -137,6 +140,43 @@ vk::ShaderModule ShaderCache::CompileModule(Shader::Info& info, std::span<const
|
|||
return module;
|
||||
}
|
||||
|
||||
Program* ShaderCache::CreateProgram(const GuestProgram& pgm, u32& binding) {
|
||||
Program* program = program_pool.Create(MakeShaderInfo(pgm, liverpool->regs));
|
||||
u32 start_binding = binding;
|
||||
const auto module = CompileModule(program->info, pgm.code, 0, binding);
|
||||
program->modules.emplace_back(module, StageSpecialization{program->info, start_binding});
|
||||
return program;
|
||||
}
|
||||
|
||||
std::tuple<const Shader::Info*, vk::ShaderModule, u64> ShaderCache::GetProgram(
|
||||
const GuestProgram& pgm, u32& binding) {
|
||||
auto [it_pgm, new_program] = program_cache.try_emplace(pgm.hash);
|
||||
if (new_program) {
|
||||
auto program = CreateProgram(pgm, binding);
|
||||
const auto module = program->modules.back().module;
|
||||
it_pgm.value() = program;
|
||||
return std::make_tuple(&program->info, module, HashCombine(pgm.hash, 0));
|
||||
}
|
||||
|
||||
Program* program = it_pgm->second;
|
||||
const auto& info = program->info;
|
||||
size_t perm_idx = program->modules.size();
|
||||
StageSpecialization spec{info, binding};
|
||||
vk::ShaderModule module{};
|
||||
|
||||
const auto it = std::ranges::find(program->modules, spec, &Program::Module::spec);
|
||||
if (it == program->modules.end()) {
|
||||
auto new_info = MakeShaderInfo(pgm, liverpool->regs);
|
||||
module = CompileModule(new_info, pgm.code, perm_idx, binding);
|
||||
program->modules.emplace_back(module, std::move(spec));
|
||||
} else {
|
||||
binding += info.NumBindings();
|
||||
module = it->module;
|
||||
perm_idx = std::distance(program->modules.begin(), it);
|
||||
}
|
||||
return std::make_tuple(&info, module, HashCombine(pgm.hash, perm_idx));
|
||||
}
|
||||
|
||||
void ShaderCache::DumpShader(std::span<const u32> code, u64 hash, Shader::Stage stage,
|
||||
size_t perm_idx, std::string_view ext) {
|
||||
using namespace Common::FS;
|
||||
|
|
|
@ -111,65 +111,37 @@ struct Program {
|
|||
|
||||
Shader::Info info;
|
||||
boost::container::small_vector<Module, 8> modules;
|
||||
|
||||
explicit Program(const Shader::Info& info_) : info{info_} {}
|
||||
};
|
||||
|
||||
Shader::Info MakeShaderInfo(Shader::Stage stage, std::span<const u32, 16> user_data, u64 pgm_base,
|
||||
u64 hash, const AmdGpu::Liverpool::Regs& regs);
|
||||
struct GuestProgram {
|
||||
Shader::Stage stage;
|
||||
std::span<const u32, AmdGpu::Liverpool::NumShaderUserData> user_data;
|
||||
std::span<const u32> code;
|
||||
u64 hash;
|
||||
|
||||
[[nodiscard]] inline u64 HashCombine(const u64 seed, const u64 hash) {
|
||||
return seed ^ (hash + 0x9e3779b9 + (seed << 6) + (seed >> 2));
|
||||
}
|
||||
explicit GuestProgram(const auto* pgm, Shader::Stage stage_)
|
||||
: stage{stage_}, user_data{pgm->user_data}, code{pgm->Code()} {
|
||||
const auto* bininfo = AmdGpu::Liverpool::GetBinaryInfo(*pgm);
|
||||
hash = bininfo->shader_hash;
|
||||
}
|
||||
};
|
||||
|
||||
class ShaderCache {
|
||||
public:
|
||||
explicit ShaderCache(const Instance& instance, AmdGpu::Liverpool* liverpool);
|
||||
~ShaderCache() = default;
|
||||
|
||||
std::tuple<const Shader::Info*, vk::ShaderModule, u64> GetProgram(const GuestProgram& pgm,
|
||||
u32& binding);
|
||||
|
||||
private:
|
||||
void DumpShader(std::span<const u32> code, u64 hash, Shader::Stage stage, size_t perm_idx,
|
||||
std::string_view ext);
|
||||
|
||||
vk::ShaderModule CompileModule(Shader::Info& info, std::span<const u32> code, size_t perm_idx,
|
||||
u32& binding);
|
||||
|
||||
std::tuple<const Shader::Info*, vk::ShaderModule, u64> GetProgram(const auto* pgm,
|
||||
Shader::Stage stage,
|
||||
u32& binding) {
|
||||
// Fetch program for binaryinfo hash.
|
||||
const auto* bininfo = AmdGpu::Liverpool::GetBinaryInfo(*pgm);
|
||||
const u64 hash = bininfo->shader_hash;
|
||||
auto [it_pgm, new_program] = program_cache.try_emplace(hash);
|
||||
u64 stage_key{};
|
||||
if (new_program) {
|
||||
const VAddr pgm_base = pgm->template Address<VAddr>();
|
||||
auto program = program_pool.Create();
|
||||
program->info = MakeShaderInfo(stage, pgm->user_data, pgm_base, hash, liverpool->regs);
|
||||
u32 start_binding = binding;
|
||||
const auto module = CompileModule(program->info, pgm->Code(), 0, binding);
|
||||
program->modules.emplace_back(module,
|
||||
StageSpecialization{program->info, start_binding});
|
||||
it_pgm.value() = program;
|
||||
return std::make_tuple(&program->info, module, HashCombine(hash, 0));
|
||||
}
|
||||
|
||||
Program* program = it_pgm->second;
|
||||
const auto& info = program->info;
|
||||
size_t perm_idx = program->modules.size();
|
||||
StageSpecialization spec{info, binding};
|
||||
vk::ShaderModule module{};
|
||||
|
||||
const auto it = std::ranges::find(program->modules, spec, &Program::Module::spec);
|
||||
if (it == program->modules.end()) {
|
||||
auto new_info = MakeShaderInfo(stage, pgm->user_data, info.pgm_base, info.pgm_hash,
|
||||
liverpool->regs);
|
||||
module = CompileModule(new_info, pgm->Code(), perm_idx, binding);
|
||||
program->modules.emplace_back(module, std::move(spec));
|
||||
} else {
|
||||
binding += info.NumBindings();
|
||||
module = it->module;
|
||||
perm_idx = std::distance(program->modules.begin(), it);
|
||||
}
|
||||
return std::make_tuple(&info, module, HashCombine(hash, perm_idx));
|
||||
}
|
||||
Program* CreateProgram(const GuestProgram& pgm, u32& binding);
|
||||
|
||||
private:
|
||||
const Instance& instance;
|
||||
|
|
Loading…
Reference in New Issue