diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 77d06bb69d7..4ec3904a990 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -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 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)