[Bf-blender-cvs] [dd356ec08d0] master: Cycles: Remove meaningless volume shaders

Sergey Sharybin noreply at git.blender.org
Tue Apr 18 11:32:54 CEST 2017


Commit: dd356ec08d07ac61c7cf1ddba3772b2df1e176a6
Author: Sergey Sharybin
Date:   Tue Mar 21 17:18:25 2017 +0100
Branches: master
https://developer.blender.org/rBdd356ec08d07ac61c7cf1ddba3772b2df1e176a6

Cycles: Remove meaningless volume shaders

This is possible to use surface-only nodes and connect them to volume output.
If there was something connected to surface output those extra connections
will not change anything visually but will force volume features to be included
into feature-adaptive kernels.

In fact, this exact reason seems to be causing slowdown of Barcelone file
comparing AMD OpenCL to NVidia CUDA.

Currently only supported by the final F12 renders because of the current design
of what gets optimized out when and how feature-adaptive kernel accesses
list of required features.

Reviewers: dingto, nirved, maiself, lukasstockner97, brecht

Reviewed By: brecht

Subscribers: bliblubli

Differential Revision: https://developer.blender.org/D2569

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

M	intern/cycles/render/graph.cpp
M	intern/cycles/render/graph.h
M	intern/cycles/render/nodes.h

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

diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 12fff8e5587..4dac078e151 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -423,7 +423,8 @@ void ShaderGraph::copy_nodes(ShaderNodeSet& nodes, ShaderNodeMap& nnodemap)
 /* Graph simplification */
 /* ******************** */
 
-/* Step 1: Remove proxy nodes.
+/* Remove proxy nodes.
+ *
  * These only exists temporarily when exporting groups, and we must remove them
  * early so that node->attributes() and default links do not see them.
  */
@@ -493,7 +494,8 @@ void ShaderGraph::remove_proxy_nodes()
 	}
 }
 
-/* Step 2: Constant folding.
+/* Constant folding.
+ *
  * Try to constant fold some nodes, and pipe result directly to
  * the input socket of connected nodes.
  */
@@ -554,7 +556,7 @@ void ShaderGraph::constant_fold()
 	}
 }
 
-/* Step 3: Simplification. */
+/* Simplification. */
 void ShaderGraph::simplify_settings(Scene *scene)
 {
 	foreach(ShaderNode *node, nodes) {
@@ -562,7 +564,7 @@ void ShaderGraph::simplify_settings(Scene *scene)
 	}
 }
 
-/* Step 4: Deduplicate nodes with same settings. */
+/* Deduplicate nodes with same settings. */
 void ShaderGraph::deduplicate_nodes()
 {
 	/* NOTES:
@@ -638,6 +640,48 @@ void ShaderGraph::deduplicate_nodes()
 	}
 }
 
+/* Check whether volume output has meaningful nodes, otherwise
+ * disconnect the output.
+ */
+void ShaderGraph::verify_volume_output()
+{
+	/* Check whether we can optimize the whole volume graph out. */
+	ShaderInput *volume_in = output()->input("Volume");
+	if(volume_in->link == NULL) {
+		return;
+	}
+	bool has_valid_volume = false;
+	ShaderNodeSet scheduled;
+	queue<ShaderNode*> traverse_queue;
+	/* Schedule volume output. */
+	traverse_queue.push(volume_in->link->parent);
+	scheduled.insert(volume_in->link->parent);
+	/* Traverse down the tree. */
+	while(!traverse_queue.empty()) {
+		ShaderNode *node = traverse_queue.front();
+		traverse_queue.pop();
+		/* Node is fully valid for volume, can't optimize anything out. */
+		if(node->has_volume_support()) {
+			has_valid_volume = true;
+			break;
+		}
+		foreach(ShaderInput *input, node->inputs) {
+			if(input->link == NULL) {
+				continue;
+			}
+			if(scheduled.find(input->link->parent) != scheduled.end()) {
+				continue;
+			}
+			traverse_queue.push(input->link->parent);
+			scheduled.insert(input->link->parent);
+		}
+	}
+	if(!has_valid_volume) {
+		VLOG(1) << "Disconnect meaningless volume output.";
+		disconnect(volume_in->link);
+	}
+}
+
 void ShaderGraph::break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack)
 {
 	visited[node->id] = true;
@@ -666,16 +710,11 @@ void ShaderGraph::clean(Scene *scene)
 {
 	/* Graph simplification */
 
-	/* 1: Remove proxy nodes was already done. */
-
-	/* 2: Constant folding. */
+	/* NOTE: Remove proxy nodes was already done. */
 	constant_fold();
-
-	/* 3: Simplification. */
 	simplify_settings(scene);
-
-	/* 4: De-duplication. */
 	deduplicate_nodes();
+	verify_volume_output();
 
 	/* we do two things here: find cycles and break them, and remove unused
 	 * nodes that don't feed into the output. how cycles are broken is
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index 09932695d1f..72e391991a7 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -155,7 +155,7 @@ public:
 	virtual bool has_spatial_varying() { return false; }
 	virtual bool has_object_dependency() { return false; }
 	virtual bool has_integrator_dependency() { return false; }
-
+	virtual bool has_volume_support() { return false; }
 	vector<ShaderInput*> inputs;
 	vector<ShaderOutput*> outputs;
 
@@ -284,6 +284,7 @@ protected:
 	void constant_fold();
 	void simplify_settings(Scene *scene);
 	void deduplicate_nodes();
+	void verify_volume_output();
 };
 
 CCL_NAMESPACE_END
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index a755b653a5b..cf68bd80458 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -445,6 +445,7 @@ public:
 	virtual ClosureType get_closure_type() { return CLOSURE_EMISSION_ID; }
 
 	bool has_surface_emission() { return true; }
+	bool has_volume_support() { return true; }
 
 	float3 color;
 	float strength;
@@ -496,6 +497,7 @@ public:
 		return ShaderNode::get_feature() | NODE_FEATURE_VOLUME;
 	}
 	virtual ClosureType get_closure_type() { return closure; }
+	virtual bool has_volume_support() { return true; }
 
 	float3 color;
 	float density;




More information about the Bf-blender-cvs mailing list