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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to