Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/render/nodes.cpp')
-rw-r--r--intern/cycles/render/nodes.cpp314
1 files changed, 136 insertions, 178 deletions
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 15b55d17301..e26084c690b 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,14 +1577,11 @@ RGBToBWNode::RGBToBWNode()
{
}
-bool RGBToBWNode::constant_fold(ShaderGraph *, ShaderOutput *, 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)
@@ -1661,38 +1659,35 @@ ConvertNode::ConvertNode(SocketType::Type from_, SocketType::Type to_, bool auto
special_type = SHADER_SPECIAL_TYPE_AUTOCONVERT;
}
-bool ConvertNode::constant_fold(ShaderGraph *, ShaderOutput *, 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)
@@ -2362,13 +2357,15 @@ void EmissionNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_emission");
}
-bool EmissionNode::constant_fold(ShaderGraph *, ShaderOutput *, ShaderInput *)
+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 */
@@ -2412,13 +2409,15 @@ void BackgroundNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_background");
}
-bool BackgroundNode::constant_fold(ShaderGraph *, ShaderOutput *, ShaderInput *)
+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 */
@@ -3380,10 +3379,9 @@ ValueNode::ValueNode()
{
}
-bool ValueNode::constant_fold(ShaderGraph *, ShaderOutput *, ShaderInput *optimized)
+void ValueNode::constant_fold(const ConstantFolder& folder)
{
- optimized->set(value);
- return true;
+ folder.make_constant(value);
}
void ValueNode::compile(SVMCompiler& compiler)
@@ -3416,10 +3414,9 @@ ColorNode::ColorNode()
{
}
-bool ColorNode::constant_fold(ShaderGraph *, ShaderOutput *, ShaderInput *optimized)
+void ColorNode::constant_fold(const ConstantFolder& folder)
{
- optimized->set(value);
- return true;
+ folder.make_constant(value);
}
void ColorNode::compile(SVMCompiler& compiler)
@@ -3468,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)
@@ -3499,35 +3510,28 @@ void MixClosureNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_mix_closure");
}
-bool MixClosureNode::constant_fold(ShaderGraph *graph, ShaderOutput *, ShaderInput *)
+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 */
@@ -3589,26 +3593,21 @@ InvertNode::InvertNode()
{
}
-bool InvertNode::constant_fold(ShaderGraph *graph, ShaderOutput *, 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)
@@ -3697,61 +3696,47 @@ void MixNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_mix");
}
-bool MixNode::constant_fold(ShaderGraph *graph, ShaderOutput *, 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 */
@@ -3774,14 +3759,11 @@ CombineRGBNode::CombineRGBNode()
{
}
-bool CombineRGBNode::constant_fold(ShaderGraph *, ShaderOutput *, 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)
@@ -3829,14 +3811,11 @@ CombineXYZNode::CombineXYZNode()
{
}
-bool CombineXYZNode::constant_fold(ShaderGraph *, ShaderOutput *, 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)
@@ -3884,14 +3863,11 @@ CombineHSVNode::CombineHSVNode()
{
}
-bool CombineHSVNode::constant_fold(ShaderGraph *, ShaderOutput *, 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)
@@ -3932,14 +3908,11 @@ GammaNode::GammaNode()
{
}
-bool GammaNode::constant_fold(ShaderGraph *, ShaderOutput *, 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)
@@ -3979,14 +3952,11 @@ BrightContrastNode::BrightContrastNode()
{
}
-bool BrightContrastNode::constant_fold(ShaderGraph *, ShaderOutput *, 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)
@@ -4029,18 +3999,16 @@ SeparateRGBNode::SeparateRGBNode()
{
}
-bool SeparateRGBNode::constant_fold(ShaderGraph *, 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)
@@ -4088,18 +4056,16 @@ SeparateXYZNode::SeparateXYZNode()
{
}
-bool SeparateXYZNode::constant_fold(ShaderGraph *, 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)
@@ -4147,20 +4113,18 @@ SeparateHSVNode::SeparateHSVNode()
{
}
-bool SeparateHSVNode::constant_fold(ShaderGraph *, 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)
@@ -4546,14 +4510,11 @@ BlackbodyNode::BlackbodyNode()
{
}
-bool BlackbodyNode::constant_fold(ShaderGraph *, ShaderOutput *, 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)
@@ -4655,15 +4616,11 @@ MathNode::MathNode()
{
}
-bool MathNode::constant_fold(ShaderGraph *, ShaderOutput *, 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)
@@ -4717,29 +4674,25 @@ VectorMathNode::VectorMathNode()
{
}
-bool VectorMathNode::constant_fold(ShaderGraph *, 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)
@@ -4873,7 +4826,7 @@ void BumpNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_bump");
}
-bool BumpNode::constant_fold(ShaderGraph *graph, ShaderOutput *, ShaderInput *)
+void BumpNode::constant_fold(const ConstantFolder& folder)
{
ShaderInput *height_in = input("Height");
ShaderInput *normal_in = input("Normal");
@@ -4881,18 +4834,15 @@ bool BumpNode::constant_fold(ShaderGraph *graph, ShaderOutput *, ShaderInput *)
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;
}
@@ -5112,12 +5062,10 @@ OSLNode::~OSLNode()
ShaderNode *OSLNode::clone() const
{
- OSLNode *node = new OSLNode(*this);
- node->type = new NodeType(*type);
- return node;
+ return OSLNode::create(this->inputs.size(), this);
}
-OSLNode* OSLNode::create(size_t num_inputs)
+OSLNode* OSLNode::create(size_t num_inputs, const OSLNode *from)
{
/* allocate space for the node itself and parameters, aligned to 16 bytes
* assuming that's the most parameter types need */
@@ -5127,7 +5075,17 @@ OSLNode* OSLNode::create(size_t num_inputs)
char *node_memory = (char*) operator new(node_size + inputs_size);
memset(node_memory, 0, node_size + inputs_size);
- return new(node_memory) OSLNode();
+ if (!from) {
+ return new(node_memory) OSLNode();
+ }
+ else {
+ /* copy input default values and node type for cloning */
+ memcpy(node_memory + node_size, (char*)from + node_size, inputs_size);
+
+ OSLNode *node = new(node_memory) OSLNode(*from);
+ node->type = new NodeType(*(from->type));
+ return node;
+ }
}
char* OSLNode::input_default_value()