Cycles: Add fundamentals to test constant folding
[blender.git] / intern / cycles / test / render_graph_finalize_test.cpp
1 /*
2  * Copyright 2011-2016 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "testing/testing.h"
18 #include "testing/mock_log.h"
19
20 #include "render/graph.h"
21 #include "render/scene.h"
22 #include "render/nodes.h"
23 #include "util/util_logging.h"
24 #include "util/util_string.h"
25 #include "util/util_vector.h"
26
27 using testing::AnyNumber;
28 using testing::HasSubstr;
29 using testing::ScopedMockLog;
30 using testing::_;
31
32 CCL_NAMESPACE_BEGIN
33
34 namespace {
35
36 template<typename T>
37 class ShaderNodeBuilder {
38 public:
39         ShaderNodeBuilder(const string& name)
40           : name_(name)
41         {
42                 node_ = new T();
43         }
44
45         const string& name() const {
46                 return name_;
47         }
48
49         ShaderNode *node() const {
50                 return node_;
51         }
52
53         template<typename V>
54         ShaderNodeBuilder& set(const string& input_name, V value)
55         {
56                 ShaderInput *input_socket = node_->input(input_name.c_str());
57                 EXPECT_NE((void*)NULL, input_socket);
58                 input_socket->set(value);
59                 return *this;
60         }
61
62 protected:
63         string name_;
64         ShaderNode *node_;
65 };
66
67 class ShaderGraphBuilder {
68 public:
69         explicit ShaderGraphBuilder(ShaderGraph *graph)
70           : graph_(graph)
71         {
72         }
73
74         ShaderNode *find_node(const string& name)
75         {
76                 map<string, ShaderNode *>::iterator it = node_map_.find(name);
77                 if(it == node_map_.end()) {
78                         return NULL;
79                 }
80                 return it->second;
81         }
82
83         template<typename T>
84         ShaderGraphBuilder& add_node(const T& node)
85         {
86                 EXPECT_EQ(NULL, find_node(node.name()));
87                 graph_->add(node.node());
88                 node_map_[node.name()] = node.node();
89                 return *this;
90         }
91
92         ShaderGraphBuilder& add_connection(const string& from,
93                                            const string& to)
94         {
95                 vector<string> tokens_from, tokens_to;
96                 string_split(tokens_from, from, "::");
97                 string_split(tokens_to, to, "::");
98                 EXPECT_EQ(2, tokens_from.size());
99                 EXPECT_EQ(2, tokens_to.size());
100                 ShaderNode *node_from = find_node(tokens_from[0]),
101                            *node_to = find_node(tokens_to[0]);
102                 EXPECT_NE((void*)NULL, node_from);
103                 EXPECT_NE((void*)NULL, node_to);
104                 EXPECT_NE(node_from, node_to);
105                 ShaderOutput *socket_from = node_from->output(tokens_from[1].c_str());
106                 ShaderInput *socket_to = node_to->input(tokens_to[1].c_str());
107                 EXPECT_NE((void*)NULL, socket_from);
108                 EXPECT_NE((void*)NULL, socket_to);
109                 graph_->connect(socket_from, socket_to);
110                 return *this;
111         }
112
113 protected:
114         ShaderGraph *graph_;
115         map<string, ShaderNode *> node_map_;
116 };
117
118 }  // namespace
119
120 #define DEFINE_COMMON_VARIABLES(builder_name, mock_log_name) \
121         util_logging_start(); \
122         util_logging_verbosity_set(1); \
123         ScopedMockLog mock_log_name; \
124         DeviceInfo device_info; \
125         SceneParams scene_params; \
126         Scene scene(scene_params, device_info); \
127         ShaderGraph graph; \
128         ShaderGraphBuilder builder(&graph); \
129
130 TEST(render_graph, constant_fold_rgb_to_bw)
131 {
132         DEFINE_COMMON_VARIABLES(builder, log);
133
134         EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
135         EXPECT_CALL(log, Log(google::INFO, _,
136                              HasSubstr("Replacing rgb_to_bw with constant 0.8.")));
137
138         builder
139                 .add_node(ShaderNodeBuilder<OutputNode>("OutputNode"))
140                 .add_node(ShaderNodeBuilder<EmissionNode>("EmissionNode"))
141                 .add_node(ShaderNodeBuilder<RGBToBWNode>("RGBToBWNodeNode")
142                           .set("Color", make_float3(0.8f, 0.8f, 0.8f)))
143                 .add_connection("RGBToBWNodeNode::Val", "EmissionNode::Color")
144                 .add_connection("EmissionNode::Emission", "OutputNode::Surface");
145
146         graph.finalize(&scene);
147 }
148
149 CCL_NAMESPACE_END