From 6a4a911fc39ffc5f5a43cf6da46bd6af34167992 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 26 Oct 2014 19:40:04 +0500 Subject: Cycles: Optimize math node without links to a single value node Pretty straightforward implementation. Just needed to move some functions around to make them available at shader compile time. --- intern/cycles/kernel/CMakeLists.txt | 1 + intern/cycles/kernel/svm/svm.h | 1 + intern/cycles/kernel/svm/svm_math.h | 50 ----------------------- intern/cycles/kernel/svm/svm_math_util.h | 70 ++++++++++++++++++++++++++++++++ intern/cycles/render/nodes.cpp | 18 +++++++- 5 files changed, 89 insertions(+), 51 deletions(-) create mode 100644 intern/cycles/kernel/svm/svm_math_util.h diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index c521e1383a4..0ff227938ae 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -91,6 +91,7 @@ set(SRC_SVM_HEADERS svm/svm_magic.h svm/svm_mapping.h svm/svm_math.h + svm/svm_math_util.h svm/svm_mix.h svm/svm_musgrave.h svm/svm_noise.h diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index c13eae813d6..5acfbbf972b 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -164,6 +164,7 @@ CCL_NAMESPACE_END #include "svm_mapping.h" #include "svm_normal.h" #include "svm_wave.h" +#include "svm_math_util.h" #include "svm_math.h" #include "svm_mix.h" #include "svm_ramp.h" diff --git a/intern/cycles/kernel/svm/svm_math.h b/intern/cycles/kernel/svm/svm_math.h index 1ce9386e40e..e3d8c1f3242 100644 --- a/intern/cycles/kernel/svm/svm_math.h +++ b/intern/cycles/kernel/svm/svm_math.h @@ -16,56 +16,6 @@ CCL_NAMESPACE_BEGIN -ccl_device float svm_math(NodeMath type, float Fac1, float Fac2) -{ - float Fac; - - if(type == NODE_MATH_ADD) - Fac = Fac1 + Fac2; - else if(type == NODE_MATH_SUBTRACT) - Fac = Fac1 - Fac2; - else if(type == NODE_MATH_MULTIPLY) - Fac = Fac1*Fac2; - else if(type == NODE_MATH_DIVIDE) - Fac = safe_divide(Fac1, Fac2); - else if(type == NODE_MATH_SINE) - Fac = sinf(Fac1); - else if(type == NODE_MATH_COSINE) - Fac = cosf(Fac1); - else if(type == NODE_MATH_TANGENT) - Fac = tanf(Fac1); - else if(type == NODE_MATH_ARCSINE) - Fac = safe_asinf(Fac1); - else if(type == NODE_MATH_ARCCOSINE) - Fac = safe_acosf(Fac1); - else if(type == NODE_MATH_ARCTANGENT) - Fac = atanf(Fac1); - else if(type == NODE_MATH_POWER) - Fac = safe_powf(Fac1, Fac2); - else if(type == NODE_MATH_LOGARITHM) - Fac = safe_logf(Fac1, Fac2); - else if(type == NODE_MATH_MINIMUM) - Fac = fminf(Fac1, Fac2); - else if(type == NODE_MATH_MAXIMUM) - Fac = fmaxf(Fac1, Fac2); - else if(type == NODE_MATH_ROUND) - Fac = floorf(Fac1 + 0.5f); - else if(type == NODE_MATH_LESS_THAN) - Fac = Fac1 < Fac2; - else if(type == NODE_MATH_GREATER_THAN) - Fac = Fac1 > Fac2; - else if(type == NODE_MATH_MODULO) - Fac = safe_modulo(Fac1, Fac2); - else if(type == NODE_MATH_ABSOLUTE) - Fac = fabsf(Fac1); - else if(type == NODE_MATH_CLAMP) - Fac = clamp(Fac1, 0.0f, 1.0f); - else - Fac = 0.0f; - - return Fac; -} - ccl_device float average_fac(float3 v) { return (fabsf(v.x) + fabsf(v.y) + fabsf(v.z))/3.0f; diff --git a/intern/cycles/kernel/svm/svm_math_util.h b/intern/cycles/kernel/svm/svm_math_util.h new file mode 100644 index 00000000000..b813bf531dc --- /dev/null +++ b/intern/cycles/kernel/svm/svm_math_util.h @@ -0,0 +1,70 @@ +/* + * Copyright 2011-2014 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 + */ + +CCL_NAMESPACE_BEGIN + +ccl_device float svm_math(NodeMath type, float Fac1, float Fac2) +{ + float Fac; + + if(type == NODE_MATH_ADD) + Fac = Fac1 + Fac2; + else if(type == NODE_MATH_SUBTRACT) + Fac = Fac1 - Fac2; + else if(type == NODE_MATH_MULTIPLY) + Fac = Fac1*Fac2; + else if(type == NODE_MATH_DIVIDE) + Fac = safe_divide(Fac1, Fac2); + else if(type == NODE_MATH_SINE) + Fac = sinf(Fac1); + else if(type == NODE_MATH_COSINE) + Fac = cosf(Fac1); + else if(type == NODE_MATH_TANGENT) + Fac = tanf(Fac1); + else if(type == NODE_MATH_ARCSINE) + Fac = safe_asinf(Fac1); + else if(type == NODE_MATH_ARCCOSINE) + Fac = safe_acosf(Fac1); + else if(type == NODE_MATH_ARCTANGENT) + Fac = atanf(Fac1); + else if(type == NODE_MATH_POWER) + Fac = safe_powf(Fac1, Fac2); + else if(type == NODE_MATH_LOGARITHM) + Fac = safe_logf(Fac1, Fac2); + else if(type == NODE_MATH_MINIMUM) + Fac = fminf(Fac1, Fac2); + else if(type == NODE_MATH_MAXIMUM) + Fac = fmaxf(Fac1, Fac2); + else if(type == NODE_MATH_ROUND) + Fac = floorf(Fac1 + 0.5f); + else if(type == NODE_MATH_LESS_THAN) + Fac = Fac1 < Fac2; + else if(type == NODE_MATH_GREATER_THAN) + Fac = Fac1 > Fac2; + else if(type == NODE_MATH_MODULO) + Fac = safe_modulo(Fac1, Fac2); + else if(type == NODE_MATH_ABSOLUTE) + Fac = fabsf(Fac1); + else if(type == NODE_MATH_CLAMP) + Fac = clamp(Fac1, 0.0f, 1.0f); + else + Fac = 0.0f; + + return Fac; +} + +CCL_NAMESPACE_END + diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index e8476bfac4c..971b96e4a16 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -17,6 +17,7 @@ #include "image.h" #include "nodes.h" #include "svm.h" +#include "svm_math_util.h" #include "osl.h" #include "sky_model.h" @@ -3682,9 +3683,24 @@ void MathNode::compile(SVMCompiler& compiler) ShaderInput *value2_in = input("Value2"); ShaderOutput *value_out = output("Value"); + compiler.stack_assign(value_out); + + /* Optimize math node without links to a single value node. */ + if(value1_in->link == NULL && value2_in->link == NULL) { + float optimized_value = svm_math((NodeMath)type_enum[type], + value1_in->value.x, + value2_in->value.x); + if(use_clamp) { + optimized_value = clamp(optimized_value, 0.0f, 1.0f); + } + compiler.add_node(NODE_VALUE_F, + __float_as_int(optimized_value), + value_out->stack_offset); + return; + } + compiler.stack_assign(value1_in); compiler.stack_assign(value2_in); - compiler.stack_assign(value_out); compiler.add_node(NODE_MATH, type_enum[type], value1_in->stack_offset, value2_in->stack_offset); compiler.add_node(NODE_MATH, value_out->stack_offset); -- cgit v1.2.3