diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index 11c60365c1d..48f31ebe298 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -415,24 +415,25 @@ void SVMCompiler::generate_svm_nodes(const ShaderNodeSet& nodes, CompilerState *state) { ShaderNodeSet& done = state->nodes_done; + vector& done_flag = state->nodes_done_flag; bool nodes_done; - do { nodes_done = true; foreach(ShaderNode *node, nodes) { - if(done.find(node) == done.end()) { + if(!done_flag[node->id]) { bool inputs_done = true; foreach(ShaderInput *input, node->inputs) if(!node_skip_input(node, input)) - if(input->link && done.find(input->link->parent) == done.end()) + if(input->link && !done_flag[input->link->parent->id]) inputs_done = false; if(inputs_done) { generate_node(node, done); done.insert(node); + done_flag[node->id] = true; } else nodes_done = false; @@ -697,7 +698,7 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty } if(generate) { - CompilerState state; + CompilerState state(graph); generate_multi_closure(clin->link->parent, clin->link->parent, &state); @@ -844,5 +845,16 @@ string SVMCompiler::Summary::full_report() const return report; } +/* Global state of the compiler. */ + +SVMCompiler::CompilerState::CompilerState(ShaderGraph *graph) +{ + int max_id = 0; + foreach(ShaderNode *node, graph->nodes) { + max_id = max(node->id, max_id); + } + nodes_done_flag.resize(max_id + 1, false); +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h index 4861de1f339..b86a00bf8ea 100644 --- a/intern/cycles/render/svm.h +++ b/intern/cycles/render/svm.h @@ -154,11 +154,26 @@ protected: /* Global state of the compiler accessible from the compilation routines. */ struct CompilerState { + CompilerState(ShaderGraph *graph); + + /* ** Global state, used by various compilation steps. ** */ + /* Set of nodes which were already compiled. */ ShaderNodeSet nodes_done; /* Set of closures which were already compiled. */ ShaderNodeSet closure_done; + + /* ** SVM nodes generation state ** */ + + /* Flag whether the node with corresponding ID was already compiled or + * not. Array element with index i corresponds to a node with such if. + * + * TODO(sergey): This is actually a copy of nodes_done just in another + * notation. We can de-duplicate this storage actually after switching + * all areas to use this flags array. + */ + vector nodes_done_flag; }; void stack_backup(StackBackup& backup, ShaderNodeSet& done);