mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-16 05:19:19 +01:00
Fix Shader Module Cache
As bindings weren't correctly handled due to the fact that `EmitSPIRV` would change the bindings, the shader module cache would not correctly function and have no cache hits in `find` and rather have them in `try_emplace` which negated any performance benefit of it. This has now been fixed by retaining the initial cache key for insertion into the cache while also storing the post-emit bindings and restoring them during a cache hit.
This commit is contained in:
parent
32fe01e145
commit
ddc9622b90
@ -235,7 +235,7 @@ namespace skyline::gpu {
|
|||||||
|
|
||||||
#define RIH(member) boost::hash_combine(hash, state.runtimeInfo.member)
|
#define RIH(member) boost::hash_combine(hash, state.runtimeInfo.member)
|
||||||
|
|
||||||
hash = XXH64(state.runtimeInfo.generic_input_types.data(), state.runtimeInfo.generic_input_types.size() * sizeof(u32), hash);
|
hash = XXH64(state.runtimeInfo.generic_input_types.data(), state.runtimeInfo.generic_input_types.size() * sizeof(Shader::AttributeType), hash);
|
||||||
hash = XXH64(&state.runtimeInfo.previous_stage_stores.mask, sizeof(state.runtimeInfo.previous_stage_stores.mask), hash);
|
hash = XXH64(&state.runtimeInfo.previous_stage_stores.mask, sizeof(state.runtimeInfo.previous_stage_stores.mask), hash);
|
||||||
RIH(convert_depth_mode);
|
RIH(convert_depth_mode);
|
||||||
RIH(force_early_z);
|
RIH(force_early_z);
|
||||||
@ -255,11 +255,18 @@ namespace skyline::gpu {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::ShaderModule ShaderManager::CompileShader(Shader::RuntimeInfo &runtimeInfo, const std::shared_ptr<ShaderProgram> &program, Shader::Backend::Bindings &bindings) {
|
ShaderManager::ShaderModule::ShaderModule(const vk::raii::Device &device, const vk::ShaderModuleCreateInfo &createInfo, Shader::Backend::Bindings bindings) : vkModule(device, createInfo), bindings(bindings) {}
|
||||||
auto it{shaderModuleCache.find(ShaderModuleState{program, bindings, runtimeInfo})};
|
|
||||||
if (it != shaderModuleCache.end())
|
|
||||||
return *it->second;
|
|
||||||
|
|
||||||
|
vk::ShaderModule ShaderManager::CompileShader(Shader::RuntimeInfo &runtimeInfo, const std::shared_ptr<ShaderProgram> &program, Shader::Backend::Bindings &bindings) {
|
||||||
|
ShaderModuleState shaderModuleState{program, bindings, runtimeInfo};
|
||||||
|
auto it{shaderModuleCache.find(shaderModuleState)};
|
||||||
|
if (it != shaderModuleCache.end()) {
|
||||||
|
const auto &entry{it->second};
|
||||||
|
bindings = entry.bindings;
|
||||||
|
return *entry.vkModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: EmitSPIRV will change bindings so we explicitly have pre/post emit bindings
|
||||||
auto spirv{Shader::Backend::SPIRV::EmitSPIRV(profile, runtimeInfo, program->program, bindings)};
|
auto spirv{Shader::Backend::SPIRV::EmitSPIRV(profile, runtimeInfo, program->program, bindings)};
|
||||||
|
|
||||||
vk::ShaderModuleCreateInfo createInfo{
|
vk::ShaderModuleCreateInfo createInfo{
|
||||||
@ -267,7 +274,7 @@ namespace skyline::gpu {
|
|||||||
.codeSize = spirv.size() * sizeof(u32),
|
.codeSize = spirv.size() * sizeof(u32),
|
||||||
};
|
};
|
||||||
|
|
||||||
auto shaderModule{shaderModuleCache.try_emplace(ShaderModuleState{program, bindings, runtimeInfo}, gpu.vkDevice, createInfo)};
|
auto shaderModule{shaderModuleCache.try_emplace(shaderModuleState, gpu.vkDevice, createInfo, bindings)};
|
||||||
return *shaderModule.first->second;
|
return *(shaderModule.first->second.vkModule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ namespace skyline::gpu {
|
|||||||
*/
|
*/
|
||||||
struct ShaderModuleState {
|
struct ShaderModuleState {
|
||||||
std::shared_ptr<ShaderProgram> program;
|
std::shared_ptr<ShaderProgram> program;
|
||||||
Shader::Backend::Bindings bindings;
|
Shader::Backend::Bindings bindings; //!< The bindings prior to the shader being compiled
|
||||||
Shader::RuntimeInfo runtimeInfo;
|
Shader::RuntimeInfo runtimeInfo;
|
||||||
|
|
||||||
bool operator==(const ShaderModuleState &) const;
|
bool operator==(const ShaderModuleState &) const;
|
||||||
@ -79,7 +79,14 @@ namespace skyline::gpu {
|
|||||||
constexpr size_t operator()(const ShaderModuleState &state) const;
|
constexpr size_t operator()(const ShaderModuleState &state) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_map<ShaderModuleState, vk::raii::ShaderModule, ShaderModuleStateHash> shaderModuleCache; //!< A map from shader module state to the corresponding Vulkan shader module
|
struct ShaderModule {
|
||||||
|
vk::raii::ShaderModule vkModule;
|
||||||
|
Shader::Backend::Bindings bindings; //!< The bindings after the shader has been compiled
|
||||||
|
|
||||||
|
ShaderModule(const vk::raii::Device& device, const vk::ShaderModuleCreateInfo& createInfo, Shader::Backend::Bindings bindings);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<ShaderModuleState, ShaderModule, ShaderModuleStateHash> shaderModuleCache; //!< A map from shader module state to the corresponding Vulkan shader module
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ShaderManager(const DeviceState &state, GPU &gpu);
|
ShaderManager(const DeviceState &state, GPU &gpu);
|
||||||
|
Loading…
Reference in New Issue
Block a user