From 5234e9ddd3ecefcf3a48d1f41e4dc18b89627f72 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Sat, 16 Jul 2016 13:16:54 +0200 Subject: Cycles: add ConstantFolder class for constant folding boilerplate. Reviewed By: brecht, sergey Differential Revision: https://developer.blender.org/D2089 --- intern/cycles/render/CMakeLists.txt | 2 + intern/cycles/render/constant_fold.cpp | 122 ++++++++++++ intern/cycles/render/constant_fold.h | 59 ++++++ intern/cycles/render/graph.cpp | 36 ++-- intern/cycles/render/graph.h | 8 +- intern/cycles/render/nodes.cpp | 338 ++++++++++++--------------------- intern/cycles/render/nodes.h | 43 +++-- 7 files changed, 347 insertions(+), 261 deletions(-) create mode 100644 intern/cycles/render/constant_fold.cpp create mode 100644 intern/cycles/render/constant_fold.h diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt index b14da3e63d0..a632ddc0598 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 00000000000..1fee6b2c081 --- /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 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 00000000000..978c8e5335a --- /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 fd48bf2631e..ac78238dfee 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 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 61100cda60b..b35be48d8ca 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 a8fd9da9ced..66c92bda54b 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 fold in that case */ - if(all_inputs_constant()) { + if(folder.all_inputs_constant()) { if(from == SocketType::FLOAT) { if(SocketType::is_float3(to)) { - optimized->set(make_float3(value_float, value_float, value_float)); - return true; + folder.make_constant(make_float3(value_float, value_float, value_float)); } } else if(SocketType::is_float3(from)) { if(to == SocketType::FLOAT) { - if(from == SocketType::COLOR) + if(from == SocketType::COLOR) { /* color to float */ - optimized->set(linear_rgb_to_gray(value_color)); - else + folder.make_constant(linear_rgb_to_gray(value_color)); + } + else { /* vector/point/normal to float */ - optimized->set(average(value_vector)); - return true; + folder.make_constant(average(value_vector)); + } } else if(SocketType::is_float3(to)) { - optimized->set(value_color); - return true; + folder.make_constant(value_color); } } } - - return false; } void ConvertNode::compile(SVMCompiler& compiler) @@ -2366,15 +2357,15 @@ void EmissionNode::compile(OSLCompiler& compiler) compiler.add(this, "node_emission"); } -bool EmissionNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput * /*socket*/, - ShaderInput * /*optimized*/) +void EmissionNode::constant_fold(const ConstantFolder& folder) { ShaderInput *color_in = input("Color"); ShaderInput *strength_in = input("Strength"); - return ((!color_in->link && color == make_float3(0.0f, 0.0f, 0.0f)) || - (!strength_in->link && strength == 0.0f)); + if ((!color_in->link && color == make_float3(0.0f, 0.0f, 0.0f)) || + (!strength_in->link && strength == 0.0f)) { + folder.discard(); + } } /* Background Closure */ @@ -2418,15 +2409,15 @@ void BackgroundNode::compile(OSLCompiler& compiler) compiler.add(this, "node_background"); } -bool BackgroundNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput * /*socket*/, - ShaderInput * /*optimized*/) +void BackgroundNode::constant_fold(const ConstantFolder& folder) { ShaderInput *color_in = input("Color"); ShaderInput *strength_in = input("Strength"); - return ((!color_in->link && color == make_float3(0.0f, 0.0f, 0.0f)) || - (!strength_in->link && strength == 0.0f)); + if ((!color_in->link && color == make_float3(0.0f, 0.0f, 0.0f)) || + (!strength_in->link && strength == 0.0f)) { + folder.discard(); + } } /* Holdout Closure */ @@ -3388,12 +3379,9 @@ ValueNode::ValueNode() { } -bool ValueNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput * /*socket*/, - ShaderInput *optimized) +void ValueNode::constant_fold(const ConstantFolder& folder) { - optimized->set(value); - return true; + folder.make_constant(value); } void ValueNode::compile(SVMCompiler& compiler) @@ -3426,12 +3414,9 @@ ColorNode::ColorNode() { } -bool ColorNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput * /*socket*/, - ShaderInput *optimized) +void ColorNode::constant_fold(const ConstantFolder& folder) { - optimized->set(value); - return true; + folder.make_constant(value); } void ColorNode::compile(SVMCompiler& compiler) @@ -3480,6 +3465,20 @@ void AddClosureNode::compile(OSLCompiler& compiler) compiler.add(this, "node_add_closure"); } +void AddClosureNode::constant_fold(const ConstantFolder& folder) +{ + ShaderInput *closure1_in = input("Closure1"); + ShaderInput *closure2_in = input("Closure2"); + + /* remove useless add closures nodes */ + if(!closure1_in->link) { + folder.bypass_or_discard(closure2_in); + } + else if(!closure2_in->link) { + folder.bypass_or_discard(closure1_in); + } +} + /* Mix Closure */ NODE_DEFINE(MixClosureNode) @@ -3511,37 +3510,28 @@ void MixClosureNode::compile(OSLCompiler& compiler) compiler.add(this, "node_mix_closure"); } -bool MixClosureNode::constant_fold(ShaderGraph *graph, - ShaderOutput * /*socket*/, - ShaderInput * /*optimized*/) +void MixClosureNode::constant_fold(const ConstantFolder& folder) { ShaderInput *fac_in = input("Fac"); ShaderInput *closure1_in = input("Closure1"); ShaderInput *closure2_in = input("Closure2"); - ShaderOutput *closure_out = output("Closure"); /* remove useless mix closures nodes */ if(closure1_in->link == closure2_in->link) { - graph->relink(this, closure_out, closure1_in->link); - return true; + folder.bypass_or_discard(closure1_in); } - - /* remove unused mix closure input when factor is 0.0 or 1.0 */ - /* check for closure links and make sure factor link is disconnected */ - if(closure1_in->link && closure2_in->link && !fac_in->link) { + /* remove unused mix closure input when factor is 0.0 or 1.0 + * check for closure links and make sure factor link is disconnected */ + else if(!fac_in->link) { /* factor 0.0 */ - if(fac == 0.0f) { - graph->relink(this, closure_out, closure1_in->link); - return true; + if(fac <= 0.0f) { + folder.bypass_or_discard(closure1_in); } /* factor 1.0 */ - else if(fac == 1.0f) { - graph->relink(this, closure_out, closure2_in->link); - return true; + else if(fac >= 1.0f) { + folder.bypass_or_discard(closure2_in); } } - - return false; } /* Mix Closure */ @@ -3603,28 +3593,21 @@ InvertNode::InvertNode() { } -bool InvertNode::constant_fold(ShaderGraph *graph, - ShaderOutput * /*socket*/, - ShaderInput *optimized) +void InvertNode::constant_fold(const ConstantFolder& folder) { ShaderInput *fac_in = input("Fac"); ShaderInput *color_in = input("Color"); - ShaderOutput *color_out = output("Color"); if(!fac_in->link) { /* evaluate fully constant node */ if(!color_in->link) { - optimized->set(interp(color, make_float3(1.0f, 1.0f, 1.0f) - color, fac)); - return true; + folder.make_constant(interp(color, make_float3(1.0f, 1.0f, 1.0f) - color, fac)); } /* remove no-op node */ else if(fac == 0.0f) { - graph->relink(this, color_out, color_in->link); - return true; + folder.bypass(color_in->link); } } - - return false; } void InvertNode::compile(SVMCompiler& compiler) @@ -3713,63 +3696,47 @@ void MixNode::compile(OSLCompiler& compiler) compiler.add(this, "node_mix"); } -bool MixNode::constant_fold(ShaderGraph *graph, - ShaderOutput * /*socket*/, - ShaderInput *optimized) +void MixNode::constant_fold(const ConstantFolder& folder) { ShaderInput *fac_in = input("Fac"); ShaderInput *color1_in = input("Color1"); ShaderInput *color2_in = input("Color2"); - ShaderOutput *color_out = output("Color"); /* evaluate fully constant node */ - if(all_inputs_constant()) { - float3 result = svm_mix(type, fac, color1, color2); - optimized->set(use_clamp ? svm_mix_clamp(result) : result); - return true; + if(folder.all_inputs_constant()) { + folder.make_constant_clamp(svm_mix(type, fac, color1, color2), use_clamp); + return; } /* remove no-op node when factor is 0.0 */ if(!fac_in->link && fac <= 0.0f) { /* note that some of the modes will clamp out of bounds values even without use_clamp */ - if(!color1_in->link) { - float3 result = svm_mix(type, 0.0f, color1, color1); - optimized->set(use_clamp ? svm_mix_clamp(result) : result); - return true; + if(type == NODE_MIX_LIGHT || type == NODE_MIX_DODGE || type == NODE_MIX_BURN) { + if(!color1_in->link) { + folder.make_constant_clamp(svm_mix(type, 0.0f, color1, color1), use_clamp); + return; + } } - else if(!use_clamp && type != NODE_MIX_LIGHT && type != NODE_MIX_DODGE && type != NODE_MIX_BURN) { - graph->relink(this, color_out, color1_in->link); - return true; + else if(folder.try_bypass_or_make_constant(color1_in, color1, use_clamp)) { + return; } } - if(type != NODE_MIX_BLEND) { - return false; - } - - /* remove useless mix colors nodes */ - if(color1_in->link && color1_in->link == color2_in->link && !use_clamp) { - graph->relink(this, color_out, color1_in->link); - return true; - } - if(!color1_in->link && !color2_in->link && color1 == color2) { - optimized->set(use_clamp ? svm_mix_clamp(color1) : color1); - return true; - } - - /* remove no-op mix color node when factor is 1.0 */ - if(!fac_in->link && fac >= 1.0f) { - if(!color2_in->link) { - optimized->set(use_clamp ? svm_mix_clamp(color2) : color2); - return true; + if(type == NODE_MIX_BLEND) { + /* remove useless mix colors nodes */ + if(color1_in->link ? (color1_in->link == color2_in->link) : (!color2_in->link && color1 == color2)) { + if(folder.try_bypass_or_make_constant(color1_in, color1, use_clamp)) { + return; + } } - else if(!use_clamp) { - graph->relink(this, color_out, color2_in->link); - return true; + + /* remove no-op mix color node when factor is 1.0 */ + if(!fac_in->link && fac >= 1.0f) { + if(folder.try_bypass_or_make_constant(color2_in, color2, use_clamp)) { + return; + } } } - - return false; } /* Combine RGB */ @@ -3792,16 +3759,11 @@ CombineRGBNode::CombineRGBNode() { } -bool CombineRGBNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput * /*socket*/, - ShaderInput *optimized) +void CombineRGBNode::constant_fold(const ConstantFolder& folder) { - if(all_inputs_constant()) { - optimized->set(make_float3(r, g, b)); - return true; + if(folder.all_inputs_constant()) { + folder.make_constant(make_float3(r, g, b)); } - - return false; } void CombineRGBNode::compile(SVMCompiler& compiler) @@ -3849,16 +3811,11 @@ CombineXYZNode::CombineXYZNode() { } -bool CombineXYZNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput * /*socket*/, - ShaderInput *optimized) +void CombineXYZNode::constant_fold(const ConstantFolder& folder) { - if(all_inputs_constant()) { - optimized->set(make_float3(x, y, z)); - return true; + if(folder.all_inputs_constant()) { + folder.make_constant(make_float3(x, y, z)); } - - return false; } void CombineXYZNode::compile(SVMCompiler& compiler) @@ -3906,16 +3863,11 @@ CombineHSVNode::CombineHSVNode() { } -bool CombineHSVNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput * /*socket*/, - ShaderInput *optimized) +void CombineHSVNode::constant_fold(const ConstantFolder& folder) { - if(all_inputs_constant()) { - optimized->set(hsv_to_rgb(make_float3(h, s, v))); - return true; + if(folder.all_inputs_constant()) { + folder.make_constant(hsv_to_rgb(make_float3(h, s, v))); } - - return false; } void CombineHSVNode::compile(SVMCompiler& compiler) @@ -3956,16 +3908,11 @@ GammaNode::GammaNode() { } -bool GammaNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput * /*socket*/, - ShaderInput *optimized) +void GammaNode::constant_fold(const ConstantFolder& folder) { - if(all_inputs_constant()) { - optimized->set(svm_math_gamma_color(color, gamma)); - return true; + if(folder.all_inputs_constant()) { + folder.make_constant(svm_math_gamma_color(color, gamma)); } - - return false; } void GammaNode::compile(SVMCompiler& compiler) @@ -4005,16 +3952,11 @@ BrightContrastNode::BrightContrastNode() { } -bool BrightContrastNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput * /*socket*/, - ShaderInput *optimized) +void BrightContrastNode::constant_fold(const ConstantFolder& folder) { - if(all_inputs_constant()) { - optimized->set(svm_brightness_contrast(color, bright, contrast)); - return true; + if(folder.all_inputs_constant()) { + folder.make_constant(svm_brightness_contrast(color, bright, contrast)); } - - return false; } void BrightContrastNode::compile(SVMCompiler& compiler) @@ -4057,20 +3999,16 @@ SeparateRGBNode::SeparateRGBNode() { } -bool SeparateRGBNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput *socket, - ShaderInput *optimized) +void SeparateRGBNode::constant_fold(const ConstantFolder& folder) { - if(all_inputs_constant()) { + if(folder.all_inputs_constant()) { for(int channel = 0; channel < 3; channel++) { - if(outputs[channel] == socket) { - optimized->set(color[channel]); - return true; + if(outputs[channel] == folder.output) { + folder.make_constant(color[channel]); + return; } } } - - return false; } void SeparateRGBNode::compile(SVMCompiler& compiler) @@ -4118,20 +4056,16 @@ SeparateXYZNode::SeparateXYZNode() { } -bool SeparateXYZNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput *socket, - ShaderInput *optimized) +void SeparateXYZNode::constant_fold(const ConstantFolder& folder) { - if(all_inputs_constant()) { + if(folder.all_inputs_constant()) { for(int channel = 0; channel < 3; channel++) { - if(outputs[channel] == socket) { - optimized->set(vector[channel]); - return true; + if(outputs[channel] == folder.output) { + folder.make_constant(vector[channel]); + return; } } } - - return false; } void SeparateXYZNode::compile(SVMCompiler& compiler) @@ -4179,22 +4113,18 @@ SeparateHSVNode::SeparateHSVNode() { } -bool SeparateHSVNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput *socket, - ShaderInput *optimized) +void SeparateHSVNode::constant_fold(const ConstantFolder& folder) { - if(all_inputs_constant()) { + if(folder.all_inputs_constant()) { float3 hsv = rgb_to_hsv(color); for(int channel = 0; channel < 3; channel++) { - if(outputs[channel] == socket) { - optimized->set(hsv[channel]); - return true; + if(outputs[channel] == folder.output) { + folder.make_constant(hsv[channel]); + return; } } } - - return false; } void SeparateHSVNode::compile(SVMCompiler& compiler) @@ -4580,16 +4510,11 @@ BlackbodyNode::BlackbodyNode() { } -bool BlackbodyNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput * /*socket*/, - ShaderInput *optimized) +void BlackbodyNode::constant_fold(const ConstantFolder& folder) { - if(all_inputs_constant()) { - optimized->set(svm_math_blackbody_color(temperature)); - return true; + if(folder.all_inputs_constant()) { + folder.make_constant(svm_math_blackbody_color(temperature)); } - - return false; } void BlackbodyNode::compile(SVMCompiler& compiler) @@ -4691,17 +4616,11 @@ MathNode::MathNode() { } -bool MathNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput * /*socket*/, - ShaderInput *optimized) +void MathNode::constant_fold(const ConstantFolder& folder) { - if(all_inputs_constant()) { - float value = svm_math(type, value1, value2); - optimized->set(use_clamp ? saturate(value) : value); - return true; + if(folder.all_inputs_constant()) { + folder.make_constant_clamp(svm_math(type, value1, value2), use_clamp); } - - return false; } void MathNode::compile(SVMCompiler& compiler) @@ -4755,31 +4674,25 @@ VectorMathNode::VectorMathNode() { } -bool VectorMathNode::constant_fold(ShaderGraph * /*graph*/, - ShaderOutput *socket, - ShaderInput *optimized) +void VectorMathNode::constant_fold(const ConstantFolder& folder) { float value; float3 vector; - if(all_inputs_constant()) { + if(folder.all_inputs_constant()) { svm_vector_math(&value, &vector, type, vector1, vector2); - if(socket == output("Value")) { - optimized->set(value); - return true; + if(folder.output == output("Value")) { + folder.make_constant(value); } - else if(socket == output("Vector")) { - optimized->set(vector); - return true; + else if(folder.output == output("Vector")) { + folder.make_constant(vector); } } - - return false; } void VectorMathNode::compile(SVMCompiler& compiler) @@ -4913,9 +4826,7 @@ void BumpNode::compile(OSLCompiler& compiler) compiler.add(this, "node_bump"); } -bool BumpNode::constant_fold(ShaderGraph *graph, - ShaderOutput * /*socket*/, - ShaderInput * /*optimized*/) +void BumpNode::constant_fold(const ConstantFolder& folder) { ShaderInput *height_in = input("Height"); ShaderInput *normal_in = input("Normal"); @@ -4923,18 +4834,15 @@ bool BumpNode::constant_fold(ShaderGraph *graph, if(height_in->link == NULL) { if(normal_in->link == NULL) { GeometryNode *geom = new GeometryNode(); - graph->add(geom); - graph->relink(this, outputs[0], geom->output("Normal")); + folder.graph->add(geom); + folder.bypass(geom->output("Normal")); } else { - graph->relink(this, outputs[0], normal_in->link); + folder.bypass(normal_in->link); } - return true; } /* TODO(sergey): Ignore bump with zero strength. */ - - return false; } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 3245fdfb6d9..c98ff6f278d 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -289,7 +289,7 @@ public: class RGBToBWNode : public ShaderNode { public: SHADER_NODE_CLASS(RGBToBWNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); float3 color; }; @@ -299,7 +299,7 @@ public: ConvertNode(SocketType::Type from, SocketType::Type to, bool autoconvert = false); SHADER_NODE_BASE_CLASS(ConvertNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); SocketType::Type from, to; @@ -436,7 +436,7 @@ public: class EmissionNode : public ShaderNode { public: SHADER_NODE_CLASS(EmissionNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); virtual ClosureType get_closure_type() { return CLOSURE_EMISSION_ID; } bool has_surface_emission() { return true; } @@ -449,7 +449,7 @@ public: class BackgroundNode : public ShaderNode { public: SHADER_NODE_CLASS(BackgroundNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); virtual ClosureType get_closure_type() { return CLOSURE_BACKGROUND_ID; } float3 color; @@ -605,7 +605,7 @@ class ValueNode : public ShaderNode { public: SHADER_NODE_CLASS(ValueNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); float value; }; @@ -614,7 +614,7 @@ class ColorNode : public ShaderNode { public: SHADER_NODE_CLASS(ColorNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); float3 value; }; @@ -622,12 +622,13 @@ public: class AddClosureNode : public ShaderNode { public: SHADER_NODE_CLASS(AddClosureNode) + void constant_fold(const ConstantFolder& folder); }; class MixClosureNode : public ShaderNode { public: SHADER_NODE_CLASS(MixClosureNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); float fac; }; @@ -643,7 +644,7 @@ public: class InvertNode : public ShaderNode { public: SHADER_NODE_CLASS(InvertNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); virtual int get_group() { return NODE_GROUP_LEVEL_3; } float fac; @@ -653,7 +654,7 @@ public: class MixNode : public ShaderNode { public: SHADER_NODE_CLASS(MixNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); virtual int get_group() { return NODE_GROUP_LEVEL_3; } @@ -667,7 +668,7 @@ public: class CombineRGBNode : public ShaderNode { public: SHADER_NODE_CLASS(CombineRGBNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); virtual int get_group() { return NODE_GROUP_LEVEL_3; } float r, g, b; @@ -676,7 +677,7 @@ public: class CombineHSVNode : public ShaderNode { public: SHADER_NODE_CLASS(CombineHSVNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); virtual int get_group() { return NODE_GROUP_LEVEL_3; } float h, s, v; @@ -685,7 +686,7 @@ public: class CombineXYZNode : public ShaderNode { public: SHADER_NODE_CLASS(CombineXYZNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); virtual int get_group() { return NODE_GROUP_LEVEL_3; } float x, y, z; @@ -694,7 +695,7 @@ public: class GammaNode : public ShaderNode { public: SHADER_NODE_CLASS(GammaNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); virtual int get_group() { return NODE_GROUP_LEVEL_1; } float3 color; @@ -704,7 +705,7 @@ public: class BrightContrastNode : public ShaderNode { public: SHADER_NODE_CLASS(BrightContrastNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); virtual int get_group() { return NODE_GROUP_LEVEL_1; } float3 color; @@ -715,7 +716,7 @@ public: class SeparateRGBNode : public ShaderNode { public: SHADER_NODE_CLASS(SeparateRGBNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); virtual int get_group() { return NODE_GROUP_LEVEL_3; } float3 color; @@ -724,7 +725,7 @@ public: class SeparateHSVNode : public ShaderNode { public: SHADER_NODE_CLASS(SeparateHSVNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); virtual int get_group() { return NODE_GROUP_LEVEL_3; } float3 color; @@ -733,7 +734,7 @@ public: class SeparateXYZNode : public ShaderNode { public: SHADER_NODE_CLASS(SeparateXYZNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); virtual int get_group() { return NODE_GROUP_LEVEL_3; } float3 vector; @@ -806,7 +807,7 @@ public: class BlackbodyNode : public ShaderNode { public: SHADER_NODE_CLASS(BlackbodyNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); virtual int get_group() { return NODE_GROUP_LEVEL_3; } float temperature; @@ -816,7 +817,7 @@ class MathNode : public ShaderNode { public: SHADER_NODE_CLASS(MathNode) virtual int get_group() { return NODE_GROUP_LEVEL_1; } - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); float value1; float value2; @@ -837,7 +838,7 @@ class VectorMathNode : public ShaderNode { public: SHADER_NODE_CLASS(VectorMathNode) virtual int get_group() { return NODE_GROUP_LEVEL_1; } - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); float3 vector1; float3 vector2; @@ -859,7 +860,7 @@ public: class BumpNode : public ShaderNode { public: SHADER_NODE_CLASS(BumpNode) - bool constant_fold(ShaderGraph *graph, ShaderOutput *socket, ShaderInput *optimized); + void constant_fold(const ConstantFolder& folder); bool has_spatial_varying() { return true; } virtual int get_feature() { return NODE_FEATURE_BUMP; -- cgit v1.2.3