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
