mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 08:31:48 +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)
|
||||
|
||||
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);
|
||||
RIH(convert_depth_mode);
|
||||
RIH(force_early_z);
|
||||
@ -255,11 +255,18 @@ namespace skyline::gpu {
|
||||
return hash;
|
||||
}
|
||||
|
||||
vk::ShaderModule ShaderManager::CompileShader(Shader::RuntimeInfo &runtimeInfo, const std::shared_ptr<ShaderProgram> &program, Shader::Backend::Bindings &bindings) {
|
||||
auto it{shaderModuleCache.find(ShaderModuleState{program, bindings, runtimeInfo})};
|
||||
if (it != shaderModuleCache.end())
|
||||
return *it->second;
|
||||
ShaderManager::ShaderModule::ShaderModule(const vk::raii::Device &device, const vk::ShaderModuleCreateInfo &createInfo, Shader::Backend::Bindings bindings) : vkModule(device, createInfo), bindings(bindings) {}
|
||||
|
||||
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)};
|
||||
|
||||
vk::ShaderModuleCreateInfo createInfo{
|
||||
@ -267,7 +274,7 @@ namespace skyline::gpu {
|
||||
.codeSize = spirv.size() * sizeof(u32),
|
||||
};
|
||||
|
||||
auto shaderModule{shaderModuleCache.try_emplace(ShaderModuleState{program, bindings, runtimeInfo}, gpu.vkDevice, createInfo)};
|
||||
return *shaderModule.first->second;
|
||||
auto shaderModule{shaderModuleCache.try_emplace(shaderModuleState, gpu.vkDevice, createInfo, bindings)};
|
||||
return *(shaderModule.first->second.vkModule);
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ namespace skyline::gpu {
|
||||
*/
|
||||
struct ShaderModuleState {
|
||||
std::shared_ptr<ShaderProgram> program;
|
||||
Shader::Backend::Bindings bindings;
|
||||
Shader::Backend::Bindings bindings; //!< The bindings prior to the shader being compiled
|
||||
Shader::RuntimeInfo runtimeInfo;
|
||||
|
||||
bool operator==(const ShaderModuleState &) const;
|
||||
@ -79,7 +79,14 @@ namespace skyline::gpu {
|
||||
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:
|
||||
ShaderManager(const DeviceState &state, GPU &gpu);
|
||||
|
Loading…
Reference in New Issue
Block a user