diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-11-25 11:07:29 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-11-25 11:07:32 +0300 |
commit | 443b159f023a872472d8e61c7270dab472a3d8ee (patch) | |
tree | 011015dbde30f6adc8b95c2710e2e5a5f13ca528 /intern/cycles/render/svm.cpp | |
parent | de35827612f85511aed50b9f05953ad857fe7e1c (diff) |
Cycles: Ensure order of shader nodes in the dependnecies set
The issue was than nodes dependencies were stored as set<ShaderNode*> which
is actually a so called "strict weak ordered", meaning order of nodes in
the set is strictly defined, but based on the ShaderNode pointer. This means
that between different render invokations order of original nodes could be
different due to different pointers allocated for ShaderNode.
This commit makes it so dependencies and maps used for ShaderNodes are based
on the node->id which has much more predictable order. It's still possible
to trick the system by doing some crazy edits during viewport rendfer and
cause difference between viewport and final render stacks.
Reviewers: brecht
Reviewed By: brecht
Subscribers: LazyDodo
Differential Revision: https://developer.blender.org/D1630
Diffstat (limited to 'intern/cycles/render/svm.cpp')
-rw-r--r-- | intern/cycles/render/svm.cpp | 36 |
1 files changed, 18 insertions, 18 deletions
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index ad0ef959d22..fa22287d342 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -180,7 +180,7 @@ void SVMCompiler::stack_clear_offset(ShaderSocketType type, int offset) active_stack.users[offset + i]--; } -void SVMCompiler::stack_backup(StackBackup& backup, set<ShaderNode*>& done) +void SVMCompiler::stack_backup(StackBackup& backup, ShaderNodeSet& done) { backup.done = done; backup.stack = active_stack; @@ -193,7 +193,7 @@ void SVMCompiler::stack_backup(StackBackup& backup, set<ShaderNode*>& done) } } -void SVMCompiler::stack_restore(StackBackup& backup, set<ShaderNode*>& done) +void SVMCompiler::stack_restore(StackBackup& backup, ShaderNodeSet& done) { int i = 0; @@ -263,7 +263,7 @@ void SVMCompiler::stack_link(ShaderInput *input, ShaderOutput *output) } } -void SVMCompiler::stack_clear_users(ShaderNode *node, set<ShaderNode*>& done) +void SVMCompiler::stack_clear_users(ShaderNode *node, ShaderNodeSet& done) { /* optimization we should add: * find and lower user counts for outputs for which all inputs are done. @@ -366,8 +366,8 @@ bool SVMCompiler::node_skip_input(ShaderNode * /*node*/, ShaderInput *input) return false; } -void SVMCompiler::find_dependencies(set<ShaderNode*>& dependencies, - const set<ShaderNode*>& done, +void SVMCompiler::find_dependencies(ShaderNodeSet& dependencies, + const ShaderNodeSet& done, ShaderInput *input, ShaderNode *skip_node) { @@ -382,7 +382,7 @@ void SVMCompiler::find_dependencies(set<ShaderNode*>& dependencies, } } -void SVMCompiler::generate_node(ShaderNode *node, set<ShaderNode*>& done) +void SVMCompiler::generate_node(ShaderNode *node, ShaderNodeSet& done) { node->compile(*this); stack_clear_users(node, done); @@ -402,7 +402,7 @@ void SVMCompiler::generate_node(ShaderNode *node, set<ShaderNode*>& done) } } -void SVMCompiler::generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNode*>& done) +void SVMCompiler::generate_svm_nodes(const ShaderNodeSet& nodes, ShaderNodeSet& done) { bool nodes_done; @@ -429,12 +429,12 @@ void SVMCompiler::generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNo } while(!nodes_done); } -void SVMCompiler::generate_closure_node(ShaderNode *node, set<ShaderNode*>& done) +void SVMCompiler::generate_closure_node(ShaderNode *node, ShaderNodeSet& done) { /* execute dependencies for closure */ foreach(ShaderInput *in, node->inputs) { if(!node_skip_input(node, in) && in->link) { - set<ShaderNode*> dependencies; + ShaderNodeSet dependencies; find_dependencies(dependencies, done, in); generate_svm_nodes(dependencies, done); } @@ -471,9 +471,9 @@ void SVMCompiler::generate_closure_node(ShaderNode *node, set<ShaderNode*>& done void SVMCompiler::generated_shared_closure_nodes(ShaderNode *root_node, ShaderNode *node, - set<ShaderNode*>& done, - set<ShaderNode*>& closure_done, - const set<ShaderNode*>& shared) + ShaderNodeSet& done, + ShaderNodeSet& closure_done, + const ShaderNodeSet& shared) { if(shared.find(node) != shared.end()) { generate_multi_closure(root_node, node, done, closure_done); @@ -489,8 +489,8 @@ void SVMCompiler::generated_shared_closure_nodes(ShaderNode *root_node, void SVMCompiler::generate_multi_closure(ShaderNode *root_node, ShaderNode *node, - set<ShaderNode*>& done, - set<ShaderNode*>& closure_done) + ShaderNodeSet& done, + ShaderNodeSet& closure_done) { /* only generate once */ if(closure_done.find(node) != closure_done.end()) @@ -510,7 +510,7 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node, if(facin && facin->link) { /* mix closure: generate instructions to compute mix weight */ - set<ShaderNode*> dependencies; + ShaderNodeSet dependencies; find_dependencies(dependencies, done, facin); generate_svm_nodes(dependencies, done); @@ -519,7 +519,7 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node, /* execute shared dependencies. this is needed to allow skipping * of zero weight closures and their dependencies later, so we * ensure that they only skip dependencies that are unique to them */ - set<ShaderNode*> cl1deps, cl2deps, shareddeps; + ShaderNodeSet cl1deps, cl2deps, shareddeps; find_dependencies(cl1deps, done, cl1in); find_dependencies(cl2deps, done, cl2in); @@ -534,7 +534,7 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node, * node or so */ if(root_node != node) { foreach(ShaderInput *in, root_node->inputs) { - set<ShaderNode*> rootdeps; + ShaderNodeSet rootdeps; find_dependencies(rootdeps, done, in, node); set_intersection(rootdeps.begin(), rootdeps.end(), cl1deps.begin(), cl1deps.end(), @@ -676,7 +676,7 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty } if(generate) { - set<ShaderNode*> done, closure_done; + ShaderNodeSet done, closure_done; generate_multi_closure(clin->link->parent, clin->link->parent, done, closure_done); } |