Cycles: fix issue with mix shaders, leading to use of uninitialized memory.
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 16 Sep 2011 13:00:09 +0000 (13:00 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 16 Sep 2011 13:00:09 +0000 (13:00 +0000)
intern/cycles/render/svm.cpp
intern/cycles/render/svm.h

index c4188fda421ac7f731d2dfc2d42f60bffbfd9d97..8f3682cc3495208fadac6085f57dd3468bbfa4ab 100644 (file)
@@ -230,6 +230,11 @@ void SVMCompiler::stack_clear_users(ShaderNode *node, set<ShaderNode*>& done)
 
                                for(int i = 0; i < size; i++)
                                        active_stack.users[output->stack_offset + i]--;
+
+                               output->stack_offset = SVM_STACK_INVALID;
+
+                               foreach(ShaderInput *in, output->links)
+                                       in->stack_offset = SVM_STACK_INVALID;
                        }
                }
        }
@@ -243,6 +248,8 @@ void SVMCompiler::stack_clear_temporary(ShaderNode *node)
 
                        for(int i = 0; i < size; i++)
                                active_stack.users[input->stack_offset + i]--;
+
+                       input->stack_offset = SVM_STACK_INVALID;
                }
        }
 }
@@ -397,6 +404,10 @@ void SVMCompiler::generate_closure(ShaderNode *node, set<ShaderNode*> done, Stac
                /* set jump for mix node, -1 because offset is already
                   incremented when this jump is added to it */
                svm_nodes[mix_offset].z = cl2_offset - mix_offset - 1;
+
+               done.insert(node);
+               stack_clear_users(node, done);
+               stack_clear_temporary(node);
        }
        else {
                /* execute dependencies for closure */
index 05fb85b057ff2ab031733cbc4cbb82a4d9287cd0..dfd78cf3c40a697a28093991466820fd059b8837 100644 (file)
@@ -78,6 +78,27 @@ public:
 protected:
        struct Stack {
                Stack() { memset(users, 0, sizeof(users)); }
+               Stack(const Stack& other) { memcpy(users, other.users, sizeof(users)); }
+               Stack& operator=(const Stack& other) { memcpy(users, other.users, sizeof(users)); return *this; }
+
+               bool empty()
+               {
+                       for(int i = 0; i < SVM_STACK_SIZE; i++)
+                               if(users[i])
+                                       return false;
+
+                       return true;
+               }
+
+               void print()
+               {
+                       printf("stack <");
+
+                       for(int i = 0; i < SVM_STACK_SIZE; i++)
+                               printf((users[i])? "*": " ");
+
+                       printf(">\n");
+               }
 
                int users[SVM_STACK_SIZE];
        };