EEVEE: Fix non-deterministic codegen preventing shader cache to work

used_libraries was iterated on to generate shader code depending on
pointers order, which was non-deterministic. It prevented shader caching
by graphics drivers to survive across reboots, as reported in
https://techgage.com/article/blender-3-5-performance-deep-dive-cycles-eevee-viewport/

Co-authored-by: Ray Molenkamp <github@lazydodo.com>

Pull Request: https://projects.blender.org/blender/blender/pulls/108289
This commit is contained in:
Xavier Hallade 2023-05-25 20:37:42 +02:00 committed by Xavier Hallade
parent dc33a8e974
commit 2533576802

@ -483,16 +483,26 @@ void GPUCodegen::generate_library()
GPUCodegenCreateInfo &info = *create_info;
void *value;
/* Iterate over libraries. We need to keep this struct intact in case
* it is required for the optimization pass. */
blender::Vector<std::string> source_files;
/* Iterate over libraries. We need to keep this struct intact in case it is required for the
* optimization pass. The first pass just collects the keys from the GSET, given items in a GSET
* are unordered this can cause order differences between invocations, so we collect the keys
* first, and sort them before doing actual work, to guarantee stable behavior while still
* having cheap insertions into the GSET */
GHashIterator *ihash = BLI_ghashIterator_new((GHash *)graph.used_libraries);
while (!BLI_ghashIterator_done(ihash)) {
value = BLI_ghashIterator_getKey(ihash);
auto deps = gpu_shader_dependency_get_resolved_source((const char *)value);
info.dependencies_generated.extend_non_duplicates(deps);
source_files.append((const char *)value);
BLI_ghashIterator_step(ihash);
}
BLI_ghashIterator_free(ihash);
std::sort(source_files.begin(), source_files.end());
for (auto &key : source_files) {
auto deps = gpu_shader_dependency_get_resolved_source(key.c_str());
info.dependencies_generated.extend_non_duplicates(deps);
}
}
void GPUCodegen::node_serialize(std::stringstream &eval_ss, const GPUNode *node)