[Bf-blender-cvs] [138362a] master: Cycles: add unit tests for supported constant folding rules.

Alexander Gavrilov noreply at git.blender.org
Mon Aug 1 17:55:08 CEST 2016


Commit: 138362a3c928af5a23a6069fff541341ece7b025
Author: Alexander Gavrilov
Date:   Mon Aug 1 18:53:20 2016 +0300
Branches: master
https://developer.blender.org/rB138362a3c928af5a23a6069fff541341ece7b025

Cycles: add unit tests for supported constant folding rules.

Code coverage of different combinations of secondary conditions
is obviously not complete because there are so many of them, but
all main rules should be there.

The reason for CORRECT vs INVALID is that both words have the same
number of characters so calls line up, but look quite different.

Reviewers: #cycles, sergey

Reviewed By: #cycles, sergey

Subscribers: dingto, sergey, brecht

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

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

M	intern/cycles/render/constant_fold.cpp
M	intern/cycles/test/CMakeLists.txt
M	intern/cycles/test/render_graph_finalize_test.cpp

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

diff --git a/intern/cycles/render/constant_fold.cpp b/intern/cycles/render/constant_fold.cpp
index 073bafc..200a4c4 100644
--- a/intern/cycles/render/constant_fold.cpp
+++ b/intern/cycles/render/constant_fold.cpp
@@ -40,7 +40,8 @@ bool ConstantFolder::all_inputs_constant() const
 
 void ConstantFolder::make_constant(float value) const
 {
-	VLOG(1) << "Replacing " << node->name << " with constant " << value << ".";
+	VLOG(1) << "Folding " << node->name << "::" << output->name() << " to constant (" << value << ").";
+
 	foreach(ShaderInput *sock, output->links) {
 		sock->set(value);
 	}
@@ -50,6 +51,8 @@ void ConstantFolder::make_constant(float value) const
 
 void ConstantFolder::make_constant(float3 value) const
 {
+	VLOG(1) << "Folding " << node->name << "::" << output->name() << " to constant " << value << ".";
+
 	foreach(ShaderInput *sock, output->links) {
 		sock->set(value);
 	}
@@ -90,6 +93,8 @@ void ConstantFolder::bypass(ShaderOutput *new_output) const
 {
 	assert(new_output);
 
+	VLOG(1) << "Folding " << node->name << "::" << output->name() << " to socket " << new_output->parent->name << "::" << new_output->name() << ".";
+
 	/* 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. */
@@ -105,6 +110,9 @@ void ConstantFolder::bypass(ShaderOutput *new_output) const
 void ConstantFolder::discard() const
 {
 	assert(output->type() == SocketType::CLOSURE);
+
+	VLOG(1) << "Discarding closure " << node->name << ".";
+
 	graph->disconnect(output);
 }
 
diff --git a/intern/cycles/test/CMakeLists.txt b/intern/cycles/test/CMakeLists.txt
index a6bcf98..80fe893 100644
--- a/intern/cycles/test/CMakeLists.txt
+++ b/intern/cycles/test/CMakeLists.txt
@@ -26,12 +26,12 @@ set(ALL_CYCLES_LIBRARIES
 	cycles_device
 	cycles_bvh
 	cycles_graph
-	cycles_kernel_osl
 	cycles_util
 	${OPENIMAGEIO_LIBRARIES}
 )
 if(WITH_CYCLES_OSL)
 	list(APPEND ALL_CYCLES_LIBRARIES
+		cycles_kernel_osl
 		${OSL_LIBRARIES}
 		${LLVM_LIBRARIES}
 	)
diff --git a/intern/cycles/test/render_graph_finalize_test.cpp b/intern/cycles/test/render_graph_finalize_test.cpp
index 4566894..e329384 100644
--- a/intern/cycles/test/render_graph_finalize_test.cpp
+++ b/intern/cycles/test/render_graph_finalize_test.cpp
@@ -40,6 +40,7 @@ public:
 	  : name_(name)
 	{
 		node_ = new T();
+		node_->name = name;
 	}
 
 	const string& name() const {
@@ -59,6 +60,13 @@ public:
 		return *this;
 	}
 
+	template<typename T2, typename V>
+	ShaderNodeBuilder& set(V T2::*pfield, V value)
+	{
+		static_cast<T*>(node_)->*pfield = value;
+		return *this;
+	}
+
 protected:
 	string name_;
 	ShaderNode *node_;
@@ -69,6 +77,7 @@ public:
 	explicit ShaderGraphBuilder(ShaderGraph *graph)
 	  : graph_(graph)
 	{
+		node_map_["Output"] = graph->output();
 	}
 
 	ShaderNode *find_node(const string& name)
@@ -110,6 +119,27 @@ public:
 		return *this;
 	}
 
+	/* Common input/output boilerplate. */
+	ShaderGraphBuilder& add_attribute(const string &name)
+	{
+		return (*this)
+			.add_node(ShaderNodeBuilder<AttributeNode>(name)
+			          .set(&AttributeNode::attribute, ustring(name)));
+	}
+
+	ShaderGraphBuilder& output_closure(const string& from)
+	{
+		return (*this).add_connection(from, "Output::Surface");
+	}
+
+	ShaderGraphBuilder& output_color(const string& from)
+	{
+		return (*this)
+			.add_node(ShaderNodeBuilder<EmissionNode>("EmissionNode"))
+			.add_connection(from, "EmissionNode::Color")
+			.output_closure("EmissionNode::Emission");
+	}
+
 protected:
 	ShaderGraph *graph_;
 	map<string, ShaderNode *> node_map_;
@@ -127,21 +157,1297 @@ protected:
 	ShaderGraph graph; \
 	ShaderGraphBuilder builder(&graph); \
 
+#define EXPECT_ANY_MESSAGE(log) \
+	EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber()); \
+
+#define CORRECT_INFO_MESSAGE(log, message) \
+	EXPECT_CALL(log, Log(google::INFO, _, HasSubstr(message)));
+
+#define INVALID_INFO_MESSAGE(log, message) \
+	EXPECT_CALL(log, Log(google::INFO, _, HasSubstr(message))).Times(0);
+
+/*
+ * Test deduplication of nodes that have inputs, some of them folded.
+ */
+TEST(render_graph, deduplicate_deep)
+{
+	DEFINE_COMMON_VARIABLES(builder, log);
+
+	EXPECT_ANY_MESSAGE(log);
+	CORRECT_INFO_MESSAGE(log, "Folding Value1::Value to constant (0.8).");
+	CORRECT_INFO_MESSAGE(log, "Folding Value2::Value to constant (0.8).");
+
+	builder
+		.add_node(ShaderNodeBuilder<GeometryNode>("Geometry1"))
+		.add_node(ShaderNodeBuilder<GeometryNode>("Geometry2"))
+		.add_node(ShaderNodeBuilder<ValueNode>("Value1")
+		          .set(&ValueNode::value, 0.8f))
+		.add_node(ShaderNodeBuilder<ValueNode>("Value2")
+		          .set(&ValueNode::value, 0.8f))
+		.add_node(ShaderNodeBuilder<NoiseTextureNode>("Noise1"))
+		.add_node(ShaderNodeBuilder<NoiseTextureNode>("Noise2"))
+		.add_node(ShaderNodeBuilder<MixNode>("Mix")
+		          .set(&MixNode::type, NODE_MIX_BLEND)
+		          .set("Fac", 0.5f))
+		.add_connection("Geometry1::Parametric", "Noise1::Vector")
+		.add_connection("Value1::Value", "Noise1::Scale")
+		.add_connection("Noise1::Color", "Mix::Color1")
+		.add_connection("Geometry2::Parametric", "Noise2::Vector")
+		.add_connection("Value2::Value", "Noise2::Scale")
+		.add_connection("Noise2::Color", "Mix::Color2")
+		.output_color("Mix::Color");
+
+	graph.finalize(&scene);
+
+	EXPECT_EQ(graph.nodes.size(), 5);
+}
+
+/*
+ * Test RGB to BW node.
+ */
 TEST(render_graph, constant_fold_rgb_to_bw)
 {
 	DEFINE_COMMON_VARIABLES(builder, log);
 
-	EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
-	EXPECT_CALL(log, Log(google::INFO, _,
-	                     HasSubstr("Replacing rgb_to_bw with constant 0.8.")));
+	EXPECT_ANY_MESSAGE(log);
+	CORRECT_INFO_MESSAGE(log, "Folding RGBToBWNodeNode::Val to constant (0.8).");
+	CORRECT_INFO_MESSAGE(log, "Folding convert_float_to_color::value_color to constant (0.8, 0.8, 0.8).");
 
 	builder
-		.add_node(ShaderNodeBuilder<OutputNode>("OutputNode"))
-		.add_node(ShaderNodeBuilder<EmissionNode>("EmissionNode"))
 		.add_node(ShaderNodeBuilder<RGBToBWNode>("RGBToBWNodeNode")
 		          .set("Color", make_float3(0.8f, 0.8f, 0.8f)))
-		.add_connection("RGBToBWNodeNode::Val", "EmissionNode::Color")
-		.add_connection("EmissionNode::Emission", "OutputNode::Surface");
+		.output_color("RGBToBWNodeNode::Val");
+
+	graph.finalize(&scene);
+}
+
+/*
+ * Tests:
+ *  - folding of Emission nodes that don't emit to nothing.
+ */
+TEST(render_graph, constant_fold_emission1)
+{
+	DEFINE_COMMON_VARIABLES(builder, log);
+
+	EXPECT_ANY_MESSAGE(log);
+	CORRECT_INFO_MESSAGE(log, "Discarding closure Emission.");
+
+	builder
+		.add_node(ShaderNodeBuilder<EmissionNode>("Emission")
+		          .set("Color", make_float3(0.0f, 0.0f, 0.0f)))
+		.output_closure("Emission::Emission");
+
+	graph.finalize(&scene);
+}
+
+TEST(render_graph, constant_fold_emission2)
+{
+	DEFINE_COMMON_VARIABLES(builder, log);
+
+	EXPECT_ANY_MESSAGE(log);
+	CORRECT_INFO_MESSAGE(log, "Discarding closure Emission.");
+
+	builder
+		.add_node(ShaderNodeBuilder<EmissionNode>("Emission")
+		          .set("Strength", 0.0f))
+		.output_closure("Emission::Emission");
+
+	graph.finalize(&scene);
+}
+
+/*
+ * Tests:
+ *  - folding of Background nodes that don't emit to nothing.
+ */
+TEST(render_graph, constant_fold_background1)
+{
+	DEFINE_COMMON_VARIABLES(builder, log);
+
+	EXPECT_ANY_MESSAGE(log);
+	CORRECT_INFO_MESSAGE(log, "Discarding closure Background.");
+
+	builder
+		.add_node(ShaderNodeBuilder<BackgroundNode>("Background")
+		          .set("Color", make_float3(0.0f, 0.0f, 0.0f)))
+		.output_closure("Background::Background");
+
+	graph.finalize(&scene);
+}
+
+TEST(render_graph, constant_fold_background2)
+{
+	DEFINE_COMMON_VARIABLES(builder, log);
+
+	EXPECT_ANY_MESSAGE(log);
+	CORRECT_INFO_MESSAGE(log, "Discarding closure Background.");
+
+	builder
+		.add_node(ShaderNodeBuilder<BackgroundNode>("Background")
+		          .set("Strength", 0.0f))
+		.output_closure("Background::Background");
+
+	graph.finalize(&scene);
+}
+
+/*
+ * Tests:
+ *  - Folding of Add Closure with only one input.
+ */
+TEST(render_graph, constant_fold_shader_add)
+{
+	DEFINE_COMMON_VARIABLES(builder, log);
+
+	EXPECT_ANY_MESSAGE(log);
+	CORRECT_INFO_MESSAGE(log, "Folding AddClosure1::Closure to socket Diffuse::BSDF.");
+	CORRECT_INFO_MESSAGE(log, "Folding AddClosure2::Closure to socket Diffuse::BSDF.");
+	INVALID_INFO_MESSAGE(log, "Folding AddClosure3");
+
+	builder
+		.add_node(ShaderNodeBuilder<DiffuseBsdfNode>("Diffuse"))
+		.add_node(ShaderNodeBuilder<AddClosureNode>("AddClosure1"))
+		.add_node(ShaderNodeBuilder<AddClosureNode>("AddClosure2"))
+		.add_node(ShaderNodeBuilder<AddClosureNode>("AddClosure3"))
+		.add_connection("Diffuse::BSDF", "AddClosure1::Closure1")
+		.add_connection("Diffuse::BSDF", "AddClosure2::Closure2")
+		.add_connection("AddClosure1::Closure", "AddClosure3::Closure1")
+		.add_connection("AddClosure2::Closure", "AddClosure3::Closure2")
+		.output_closure("AddClosure3::Closure");
+
+	graph.finalize(&scene);
+}
+
+/*
+ * Tests:
+ *  - Folding of Mix Closure with 0 or 1 fac.
+ *  - Folding of Mix Closure with both inputs folded to the same node.
+ */
+TEST(render_graph, constant_fold_shader_mix)
+{
+	DEFINE_COMMON_VARIABLES(builder, log);
+
+	EXPECT_ANY_MESSAGE(log);
+	CORRECT_INFO_MESSAGE(log, "Folding MixClosure1::Closure to socket Diffuse::BSDF.");
+	CORRECT_INFO_MESSAGE(log, "Folding MixClosure2::Closure to socket Diffuse::BSDF.");
+	CORRECT_INFO_MESSAGE(log, "Folding MixClosure3::Closure to socket Diffuse::BSDF.");
+
+	builder
+		.add_attribute("Attribute")
+		.add_node(ShaderNodeBuilder<DiffuseBsdfNode>("Diffuse"))
+		/* choose left */
+		.add_node(ShaderNodeBuilder<MixClosureNode>("MixClosure1")
+		          .set("Fac", 0.0f))
+		.add_connection("Diffuse::BSDF", "MixClosure1::Closure1")
+		/* choose right */
+		.add_node(ShaderNodeBuilder<MixClosureNode>("MixClosure2")
+		          .set("Fac", 1.0f))
+		.add_connection("Diffuse::BSDF", "MixClosure2::Closure2")
+		/* both inputs folded the same */
+		.add_node(ShaderNodeBuilder<MixClosureNode>("MixClosure3"))
+		.add_connection("Attribute::Fac", "

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list