Cycles: Make all #include statements relative to cycles source directory
[blender.git] / intern / cycles / render / svm.h
index f61ceb5d7703b6dbd8039db3bd19be2ba9770271..abbd9e50610419b92d159e96bf11fcb875a976c2 100644 (file)
 #ifndef __SVM_H__
 #define __SVM_H__
 
-#include "attribute.h"
-#include "graph.h"
-#include "shader.h"
+#include "render/attribute.h"
+#include "render/graph.h"
+#include "render/shader.h"
 
-#include "util_set.h"
-#include "util_string.h"
+#include "util/util_set.h"
+#include "util/util_string.h"
+#include "util/util_thread.h"
 
 CCL_NAMESPACE_BEGIN
 
@@ -46,6 +47,15 @@ public:
 
        void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
        void device_free(Device *device, DeviceScene *dscene, Scene *scene);
+
+protected:
+       /* Lock used to synchronize threaded nodes compilation. */
+       thread_spin_lock nodes_lock_;
+
+       void device_update_shader(Scene *scene,
+                                 Shader *shader,
+                                 Progress *progress,
+                                 vector<int4> *global_svm_nodes);
 };
 
 /* Graph Compiler */
@@ -95,17 +105,19 @@ public:
                     int index,
                     Summary *summary = NULL);
 
-       void stack_assign(ShaderOutput *output);
-       void stack_assign(ShaderInput *input);
-       int stack_find_offset(ShaderSocketType type);
-       void stack_clear_offset(ShaderSocketType type, int offset);
+       int stack_assign(ShaderOutput *output);
+       int stack_assign(ShaderInput *input);
+       int stack_assign_if_linked(ShaderInput *input);
+       int stack_assign_if_linked(ShaderOutput *output);
+       int stack_find_offset(int size);
+       int stack_find_offset(SocketType::Type type);
+       void stack_clear_offset(SocketType::Type type, int offset);
        void stack_link(ShaderInput *input, ShaderOutput *output);
 
-       void add_node(NodeType type, int a = 0, int b = 0, int c = 0);
+       void add_node(ShaderNodeType type, int a = 0, int b = 0, int c = 0);
        void add_node(int a = 0, int b = 0, int c = 0, int d = 0);
-       void add_node(NodeType type, const float3& f);
+       void add_node(ShaderNodeType type, const float3& f);
        void add_node(const float4& f);
-       void add_array(float4 *f, int num);
        uint attribute(ustring name);
        uint attribute(AttributeStandard std);
        uint encode_uchar4(uint x, uint y = 0, uint z = 0, uint w = 0);
@@ -146,17 +158,32 @@ protected:
                int users[SVM_STACK_SIZE];
        };
 
-       struct StackBackup {
-               Stack stack;
-               vector<int> offsets;
-               ShaderNodeSet done;
-       };
+       /* Global state of the compiler accessible from the compilation routines. */
+       struct CompilerState {
+               explicit CompilerState(ShaderGraph *graph);
+
+               /* ** Global state, used by various compilation steps. ** */
 
-       void stack_backup(StackBackup& backup, ShaderNodeSet& done);
-       void stack_restore(StackBackup& backup, ShaderNodeSet& done);
+               /* 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<bool> nodes_done_flag;
+       };
 
        void stack_clear_temporary(ShaderNode *node);
-       int stack_size(ShaderSocketType type);
+       int stack_size(SocketType::Type type);
        void stack_clear_users(ShaderNode *node, ShaderNodeSet& done);
 
        bool node_skip_input(ShaderNode *node, ShaderInput *input);
@@ -167,23 +194,23 @@ protected:
                               ShaderInput *input,
                               ShaderNode *skip_node = NULL);
        void generate_node(ShaderNode *node, ShaderNodeSet& done);
-       void generate_closure_node(ShaderNode *node, ShaderNodeSet& done);
-       void generated_shared_closure_nodes(ShaderNode *root_node, ShaderNode *node,
-                                           ShaderNodeSet& done,
-                                           ShaderNodeSet& closure_done,
+       void generate_closure_node(ShaderNode *node, CompilerState *state);
+       void generated_shared_closure_nodes(ShaderNode *root_node,
+                                           ShaderNode *node,
+                                           CompilerState *state,
                                            const ShaderNodeSet& shared);
-       void generate_svm_nodes(const ShaderNodeSet& nodes, ShaderNodeSet& done);
+       void generate_svm_nodes(const ShaderNodeSet& nodes,
+                               CompilerState *state);
 
        /* multi closure */
        void generate_multi_closure(ShaderNode *root_node,
                                    ShaderNode *node,
-                                   ShaderNodeSet& done,
-                                   ShaderNodeSet& closure_done);
+                                   CompilerState *state);
 
        /* compile */
        void compile_type(Shader *shader, ShaderGraph *graph, ShaderType type);
 
-       vector<int4> svm_nodes;
+       vector<int4> current_svm_nodes;
        ShaderType current_type;
        Shader *current_shader;
        ShaderGraph *current_graph;