[Bf-blender-cvs] [6fc1669] master: Cycles: Initial work towards selective nodes support compilation

Sergey Sharybin noreply at git.blender.org
Sat May 9 16:57:45 CEST 2015


Commit: 6fc166967989072bda085ae4cf54fc513f6f1daf
Author: Sergey Sharybin
Date:   Sat May 9 19:22:16 2015 +0500
Branches: master
https://developer.blender.org/rB6fc166967989072bda085ae4cf54fc513f6f1daf

Cycles: Initial work towards selective nodes support compilation

The goal is to be able to compile kernel with nodes which are actually needed
to render current scene, hence improving performance of the kernel,

The idea is:

- Have few node groups, starting with a group which contains nodes are used
  really often, and then couple of groups which will be extension of this one.

- Have feature-based nodes disabling, so it's possible to disable nodes related
  to features which are not used with the currently used nodes group.

This commit only lays down needed routines for this approach, actual split will
happen later after gathering statistics from bunch of production scenes.

===================================================================

M	intern/cycles/kernel/kernel_compat_cpu.h
M	intern/cycles/kernel/kernel_compat_cuda.h
M	intern/cycles/kernel/kernel_compat_opencl.h
M	intern/cycles/kernel/svm/svm.h
M	intern/cycles/kernel/svm/svm_types.h
M	intern/cycles/render/graph.h
M	intern/cycles/render/nodes.h
M	intern/cycles/render/shader.cpp
M	intern/cycles/render/shader.h

===================================================================

diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h
index 200667a..b209fff 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -26,6 +26,14 @@
 #  pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
 #endif
 
+/* Selective nodes compilation. */
+#ifndef __NODES_MAX_GROUP__
+#  define __NODES_MAX_GROUP__ NODE_GROUP_LEVEL_MAX
+#endif
+#ifndef __NODES_FEATURES__
+#  define __NODES_FEATURES__ NODE_FEATURE_ALL
+#endif
+
 #include "util_debug.h"
 #include "util_math.h"
 #include "util_simd.h"
diff --git a/intern/cycles/kernel/kernel_compat_cuda.h b/intern/cycles/kernel/kernel_compat_cuda.h
index 904736c..61e208f 100644
--- a/intern/cycles/kernel/kernel_compat_cuda.h
+++ b/intern/cycles/kernel/kernel_compat_cuda.h
@@ -22,6 +22,14 @@
 #define CCL_NAMESPACE_BEGIN
 #define CCL_NAMESPACE_END
 
+/* Selective nodes compilation. */
+#ifndef __NODES_MAX_GROUP__
+#  define __NODES_MAX_GROUP__ NODE_GROUP_LEVEL_MAX
+#endif
+#ifndef __NODES_FEATURES__
+#  define __NODES_FEATURES__ NODE_FEATURE_ALL
+#endif
+
 #include <cuda.h>
 #include <float.h>
 
diff --git a/intern/cycles/kernel/kernel_compat_opencl.h b/intern/cycles/kernel/kernel_compat_opencl.h
index d480ec0..12b0f11 100644
--- a/intern/cycles/kernel/kernel_compat_opencl.h
+++ b/intern/cycles/kernel/kernel_compat_opencl.h
@@ -37,6 +37,16 @@
 #define ccl_may_alias
 #define ccl_constant __constant
 #define ccl_global __global
+#define ccl_local __local
+#define ccl_private __private
+
+/* Selective nodes compilation. */
+#ifndef __NODES_MAX_GROUP__
+#  define __NODES_MAX_GROUP__ NODE_GROUP_LEVEL_MAX
+#endif
+#ifndef __NODES_FEATURES__
+#  define __NODES_FEATURES__ NODE_FEATURE_ALL
+#endif
 
 /* no assert in opencl */
 #define kernel_assert(cond)
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index c13fae7..b156196 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -182,8 +182,10 @@ CCL_NAMESPACE_END
 
 CCL_NAMESPACE_BEGIN
 
-/* Main Interpreter Loop */
+#define NODES_GROUP(group) ((group) <= __NODES_MAX_GROUP__)
+#define NODES_FEATURE(feature) (__NODES_FEATURES__ & (feature) != 0)
 
+/* Main Interpreter Loop */
 ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderType type, int path_flag)
 {
 	float stack[SVM_STACK_SIZE];
@@ -193,6 +195,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
 		uint4 node = read_node(kg, &offset);
 
 		switch(node.x) {
+#if NODES_GROUP(NODE_GROUP_LEVEL_0)
 			case NODE_SHADER_JUMP: {
 				if(type == SHADER_TYPE_SURFACE) offset = node.y;
 				else if(type == SHADER_TYPE_VOLUME) offset = node.z;
@@ -215,9 +218,11 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
 			case NODE_CLOSURE_AMBIENT_OCCLUSION:
 				svm_node_closure_ambient_occlusion(sd, stack, node);
 				break;
+#if NODES_FEATURE(NODE_FEATURE_VOLUME)
 			case NODE_CLOSURE_VOLUME:
 				svm_node_closure_volume(kg, sd, stack, node, path_flag);
 				break;
+#endif  /* NODES_FEATURE(NODE_FEATURE_VOLUME) */
 			case NODE_CLOSURE_SET_WEIGHT:
 				svm_node_closure_set_weight(sd, node.y, node.z, node.w);
 				break;
@@ -230,6 +235,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
 			case NODE_MIX_CLOSURE:
 				svm_node_mix_closure(sd, stack, node);
 				break;
+#endif  /* NODES_GROUP(NODE_GROUP_LEVEL_0) */
 			case NODE_JUMP_IF_ZERO:
 				if(stack_load_float(stack, node.z) == 0.0f)
 					offset += node.y;
@@ -299,9 +305,11 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
 				svm_node_particle_info(kg, sd, stack, node.y, node.z);
 				break;
 #ifdef __HAIR__
+#  if NODES_FEATURE(NODE_FEATURE_HAIR)
 			case NODE_HAIR_INFO:
 				svm_node_hair_info(kg, sd, stack, node.y, node.z);
 				break;
+#  endif  /* NODES_FEATURE(NODE_FEATURE_HAIR) */
 #endif  /* __HAIR__ */
 
 #endif  /* __EXTRA_NODES__ */
@@ -434,6 +442,9 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
 	}
 }
 
+#undef NODES_GROUP
+#undef NODES_FEATURE
+
 CCL_NAMESPACE_END
 
 #endif /* __SVM_H__ */
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 848c16b..4f2117a 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -28,6 +28,23 @@ CCL_NAMESPACE_BEGIN
 
 /* Nodes */
 
+/* Known frequencies of used nodes, used for selective nodes compilation
+ * in the kernel. Currently only affects split OpenCL kernel.
+ *
+ * Keep as defines so it's easy to check which nodes are to be compiled
+ * from preprocessor.
+ *
+ * Lower the number of group more often the node is used.
+ */
+#define NODE_GROUP_LEVEL_0    0
+#define NODE_GROUP_LEVEL_1    1
+#define NODE_GROUP_LEVEL_2    2
+#define NODE_GROUP_LEVEL_MAX  NODE_GROUP_LEVEL_2
+
+#define NODE_FEATURE_VOLUME     (1 << 0)
+#define NODE_FEATURE_HAIR       (1 << 1)
+#define NODE_FEATURE_ALL        (NODE_FEATURE_VOLUME|NODE_FEATURE_HAIR)
+
 typedef enum NodeType {
 	NODE_END = 0,
 	NODE_CLOSURE_BSDF,
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index 6744804..e627100 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -207,6 +207,24 @@ public:
 	ShaderBump bump; /* for bump mapping utility */
 	
 	ShaderNodeSpecialType special_type;	/* special node type */
+
+	/* ** Selective nodes compilation ** */
+
+	/* TODO(sergey): More explicitly mention in the function names
+	 * that those functions are for selective compilation only?
+	 */
+
+	/* Nodes are split into several groups, group of level 0 contains
+	 * nodes which are most commonly used, further levels are extension
+	 * of previous one and includes less commonly used nodes.
+	 */
+	virtual int get_group() { return NODE_GROUP_LEVEL_0; }
+
+	/* Node feature are used to disable huge nodes inside the group,
+	 * so it's possible to disable huge nodes inside of the required
+	 * nodes group.
+	 */
+	virtual int get_feature() { return 0; }
 };
 
 
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 686fb5e..ac7bbaf 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -415,6 +415,7 @@ public:
 
 	void attributes(Shader *shader, AttributeRequestSet *attributes);
 	bool has_spatial_varying() { return true; }
+	virtual int get_feature() { return NODE_FEATURE_HAIR; }
 };
 
 class ValueNode : public ShaderNode {
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 971cd50..2eaba3f 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -480,5 +480,24 @@ void ShaderManager::add_default(Scene *scene)
 	}
 }
 
+void ShaderManager::get_requested_features(Scene *scene, int& max_group, int& features)
+{
+	max_group = NODE_GROUP_LEVEL_0;
+	features = 0;
+	for(int i = 0; i < scene->shaders.size(); i++) {
+		Shader *shader = scene->shaders[i];
+		foreach(ShaderNode *node, shader->graph->nodes) {
+			max_group = min(max_group, node->get_group());
+			features |= node->get_feature();
+			if(node->special_type == SHADER_SPECIAL_TYPE_CLOSURE) {
+				BsdfNode *bsdf_node = static_cast<BsdfNode*>(node);
+				if(CLOSURE_IS_VOLUME(bsdf_node->closure)) {
+					features |= NODE_FEATURE_VOLUME;
+				}
+			}
+		}
+	}
+}
+
 CCL_NAMESPACE_END
 
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index 5bcb2c4..27b2396 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -165,6 +165,9 @@ public:
 	 * have any shader assigned explicitly */
 	static void add_default(Scene *scene);
 
+	/* Selective nodes compilation. */
+	void get_requested_features(Scene *scene, int& max_group, int& features);
+
 protected:
 	ShaderManager();




More information about the Bf-blender-cvs mailing list