[Bf-blender-cvs] [5234e9d] master: Cycles: add ConstantFolder class for constant folding boilerplate.

Alexander Gavrilov noreply at git.blender.org
Mon Jul 18 22:54:56 CEST 2016


Commit: 5234e9ddd3ecefcf3a48d1f41e4dc18b89627f72
Author: Alexander Gavrilov
Date:   Sat Jul 16 13:16:54 2016 +0200
Branches: master
https://developer.blender.org/rB5234e9ddd3ecefcf3a48d1f41e4dc18b89627f72

Cycles: add ConstantFolder class for constant folding boilerplate.

Reviewed By: brecht, sergey

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

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

M	intern/cycles/render/CMakeLists.txt
A	intern/cycles/render/constant_fold.cpp
A	intern/cycles/render/constant_fold.h
M	intern/cycles/render/graph.cpp
M	intern/cycles/render/graph.h
M	intern/cycles/render/nodes.cpp
M	intern/cycles/render/nodes.h

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

diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt
index b14da3e..a632ddc 100644
--- a/intern/cycles/render/CMakeLists.txt
+++ b/intern/cycles/render/CMakeLists.txt
@@ -22,6 +22,7 @@ set(SRC
 	bake.cpp
 	buffers.cpp
 	camera.cpp
+	constant_fold.cpp
 	film.cpp
 	graph.cpp
 	image.cpp
@@ -49,6 +50,7 @@ set(SRC_HEADERS
 	background.h
 	buffers.h
 	camera.h
+	constant_fold.h
 	film.h
 	graph.h
 	image.h
diff --git a/intern/cycles/render/constant_fold.cpp b/intern/cycles/render/constant_fold.cpp
new file mode 100644
index 0000000..1fee6b2
--- /dev/null
+++ b/intern/cycles/render/constant_fold.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2011-2013 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "constant_fold.h"
+#include "graph.h"
+
+#include "util_foreach.h"
+
+CCL_NAMESPACE_BEGIN
+
+ConstantFolder::ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output)
+: graph(graph), node(node), output(output)
+{
+}
+
+bool ConstantFolder::all_inputs_constant() const
+{
+	foreach(ShaderInput *input, node->inputs) {
+		if(input->link) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+void ConstantFolder::make_constant(float value) const
+{
+	foreach(ShaderInput *sock, output->links) {
+		sock->set(value);
+	}
+
+	graph->disconnect(output);
+}
+
+void ConstantFolder::make_constant(float3 value) const
+{
+	foreach(ShaderInput *sock, output->links) {
+		sock->set(value);
+	}
+
+	graph->disconnect(output);
+}
+
+void ConstantFolder::make_constant_clamp(float value, bool clamp) const
+{
+	make_constant(clamp ? saturate(value) : value);
+}
+
+void ConstantFolder::make_constant_clamp(float3 value, bool clamp) const
+{
+	if (clamp) {
+		value.x = saturate(value.x);
+		value.y = saturate(value.y);
+		value.z = saturate(value.z);
+	}
+
+	make_constant(value);
+}
+
+void ConstantFolder::bypass(ShaderOutput *new_output) const
+{
+	assert(new_output);
+
+	/* Remove all outgoing links from socket and connect them to new_output instead.
+	 * The graph->relink method affects node inputs, so it's not safe to use in constant
+	 * folding if the node has multiple outputs and will thus be folded multiple times. */
+	vector<ShaderInput*> outputs = output->links;
+
+	graph->disconnect(output);
+
+	foreach(ShaderInput *sock, outputs) {
+		graph->connect(new_output, sock);
+	}
+}
+
+void ConstantFolder::discard() const
+{
+	assert(output->type() == SocketType::CLOSURE);
+	graph->disconnect(output);
+}
+
+void ConstantFolder::bypass_or_discard(ShaderInput *input) const
+{
+	assert(input->type() == SocketType::CLOSURE);
+
+	if (input->link) {
+		bypass(input->link);
+	}
+	else {
+		discard();
+	}
+}
+
+bool ConstantFolder::try_bypass_or_make_constant(ShaderInput *input, float3 input_value, bool clamp) const
+{
+	if(!input->link) {
+		make_constant_clamp(input_value, clamp);
+		return true;
+	}
+	else if(!clamp) {
+		bypass(input->link);
+		return true;
+	}
+
+	return false;
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/render/constant_fold.h b/intern/cycles/render/constant_fold.h
new file mode 100644
index 0000000..978c8e5
--- /dev/null
+++ b/intern/cycles/render/constant_fold.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2011-2013 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONSTANT_FOLD_H__
+#define __CONSTANT_FOLD_H__
+
+#include "util_types.h"
+
+CCL_NAMESPACE_BEGIN
+
+class ShaderGraph;
+class ShaderInput;
+class ShaderNode;
+class ShaderOutput;
+
+class ConstantFolder {
+public:
+	ShaderGraph *const graph;
+	ShaderNode *const node;
+	ShaderOutput *const output;
+
+	ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output);
+
+	bool all_inputs_constant() const;
+
+	/* Constant folding helpers, always return true for convenience. */
+	void make_constant(float value) const;
+	void make_constant(float3 value) const;
+	void make_constant_clamp(float value, bool clamp) const;
+	void make_constant_clamp(float3 value, bool clamp) const;
+
+	/* Bypass node, relinking to another output socket. */
+	void bypass(ShaderOutput *output) const;
+
+	/* For closure nodes, discard node entirely or bypass to one of its inputs. */
+	void discard() const;
+	void bypass_or_discard(ShaderInput *input) const;
+
+	/* Bypass or make constant, unless we can't due to clamp being true. */
+	bool try_bypass_or_make_constant(ShaderInput *input, float3 input_value, bool clamp) const;
+};
+
+CCL_NAMESPACE_END
+
+#endif /* __CONSTANT_FOLD_H__ */
+
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index fd48bf2..ac78238 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011-2013 Blender Foundation
+ * Copyright 2011-2016 Blender Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
 #include "graph.h"
 #include "nodes.h"
 #include "shader.h"
+#include "constant_fold.h"
 
 #include "util_algorithm.h"
 #include "util_debug.h"
@@ -126,17 +127,6 @@ ShaderOutput *ShaderNode::output(ustring name)
 	return NULL;
 }
 
-bool ShaderNode::all_inputs_constant() const
-{
-	foreach(ShaderInput *input, inputs) {
-		if(input->link) {
-			return false;
-		}
-	}
-
-	return true;
-}
-
 void ShaderNode::attributes(Shader *shader, AttributeRequestSet *attributes)
 {
 	foreach(ShaderInput *input, inputs) {
@@ -278,6 +268,17 @@ void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to)
 	}
 }
 
+void ShaderGraph::disconnect(ShaderOutput *from)
+{
+	assert(!finalized);
+
+	foreach(ShaderInput *sock, from->links) {
+		sock->link = NULL;
+	}
+
+	from->links.clear();
+}
+
 void ShaderGraph::disconnect(ShaderInput *to)
 {
 	assert(!finalized);
@@ -525,15 +526,8 @@ void ShaderGraph::constant_fold()
 				}
 			}
 			/* Optimize current node. */
-			if(node->constant_fold(this, output, output->links[0])) {
-				/* Apply optimized value to other connected sockets and disconnect. */
-				vector<ShaderInput*> links(output->links);
-				for(size_t i = 0; i < links.size(); i++) {
-					if(i > 0)
-						links[i]->parent->copy_value(links[i]->socket_type, *links[0]->parent, links[0]->socket_type);
-					disconnect(links[i]);
-				}
-			}
+			ConstantFolder folder(this, node, output);
+			node->constant_fold(folder);
 		}
 	}
 }
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index 61100cd..b35be48 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011-2013 Blender Foundation
+ * Copyright 2011-2016 Blender Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -41,6 +41,7 @@ class ShaderGraph;
 class SVMCompiler;
 class OSLCompiler;
 class OutputNode;
+class ConstantFolder;
 
 /* Bump
  *
@@ -140,9 +141,7 @@ public:
 
 	/* ** Node optimization ** */
 	/* Check whether the node can be replaced with single constant. */
-	virtual bool constant_fold(ShaderGraph * /*graph*/, ShaderOutput * /*socket*/, ShaderInput * /*optimized*/) { return false; }
-
-	bool all_inputs_constant() const;
+	virtual void constant_fold(const ConstantFolder& /*folder*/) {}
 
 	/* Simplify settings used by artists to the ones which are simpler to
 	 * evaluate in the kernel but keep the final result unchanged.
@@ -251,6 +250,7 @@ public:
 	OutputNode *output();
 
 	void connect(ShaderOutput *from, ShaderInput *to);
+	void disconnect(ShaderOutput *from);
 	void disconnect(ShaderInput *to);
 	void relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to);
 
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index a8fd9da..66c92bd 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -22,6 +22,7 @@
 #include "svm_color_util.h"
 #include "svm_math_util.h"
 #include "osl.h"
+#include "constant_fold.h"
 
 #include "util_sky_model.h"
 #include "util_foreach.h"
@@ -1576,16 +1577,11 @@ RGBToBWNode::RGBToBWNode()
 {
 }
 
-bool RGBToBWNode::constant_fold(ShaderGraph * /*graph*/,
-                                ShaderOutput * /*socket*/,
-                                ShaderInput *optimized)
+void RGBToBWNode::constant_fold(const ConstantFolder& folder)
 {
-	if(all_inputs_constant()) {
-		optimized->set(linear_rgb_to_gray(color));
-		return true;
+	if(folder.all_inputs_constant()) {
+		folder.make_constant(linear_rgb_to_gray(color));
 	}
-
-	return false;
 }
 
 void RGBToBWNode::compile(SVMCompiler& compiler)
@@ -1663,40 +1659,35 @@ ConvertNode::ConvertNode(SocketType::Type from_, SocketType::Type to_, bool auto
 		special_type = SHADER_SPECIAL_TYPE_AUTOCONVERT;
 }
 
-bool ConvertNode::constant_fold(ShaderGraph * /*graph*/,
-                                ShaderOutput * /*socket*/,
-                                ShaderInput *optimized)
+void ConvertNode::constant_fold(const ConstantFolder& folder)
 {
 	/* proxy nodes should have been removed at this point */
 	assert(special_type != SHADER_SPECIAL_TYPE_PROXY);
 
 	/* TODO(DingTo): conversion from/to int is not supported yet, don't fol

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list