From ae94e36cfb2f3bc9a99b638782092d9c71d4b3c7 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 26 Apr 2022 17:12:34 +0200 Subject: Geometry Nodes: refactor array devirtualization Goals: * Better high level control over where devirtualization occurs. There is always a trade-off between performance and compile-time/binary-size. * Simplify using array devirtualization. * Better performance for cases where devirtualization wasn't used before. Many geometry nodes accept fields as inputs. Internally, that means that the execution functions have to accept so called "virtual arrays" as inputs. Those can be e.g. actual arrays, just single values, or lazily computed arrays. Due to these different possible virtual arrays implementations, access to individual elements is slower than it would be if everything was just a normal array (access does through a virtual function call). For more complex execution functions, this overhead does not matter, but for small functions (like a simple addition) it very much does. The virtual function call also prevents the compiler from doing some optimizations (e.g. loop unrolling and inserting simd instructions). The solution is to "devirtualize" the virtual arrays for small functions where the overhead is measurable. Essentially, the function is generated many times with different array types as input. Then there is a run-time dispatch that calls the best implementation. We have been doing devirtualization in e.g. math nodes for a long time already. This patch just generalizes the concept and makes it easier to control. It also makes it easier to investigate the different trade-offs when it comes to devirtualization. Nodes that we've optimized using devirtualization before didn't get a speedup. However, a couple of nodes are using devirtualization now, that didn't before. Those got a 2-4x speedup in common cases. * Map Range * Random Value * Switch * Combine XYZ Differential Revision: https://developer.blender.org/D14628 --- .../nodes/shader/nodes/node_shader_map_range.cc | 527 ++++++++------------- .../blender/nodes/shader/nodes/node_shader_math.cc | 26 +- .../nodes/shader/nodes/node_shader_sepcomb_xyz.cc | 4 +- .../nodes/shader/nodes/node_shader_vector_math.cc | 54 ++- 4 files changed, 234 insertions(+), 377 deletions(-) (limited to 'source/blender/nodes/shader') diff --git a/source/blender/nodes/shader/nodes/node_shader_map_range.cc b/source/blender/nodes/shader/nodes/node_shader_map_range.cc index 8e7934bf34e..9ba9a279c57 100644 --- a/source/blender/nodes/shader/nodes/node_shader_map_range.cc +++ b/source/blender/nodes/shader/nodes/node_shader_map_range.cc @@ -223,327 +223,106 @@ static float3 clamp_range(const float3 value, const float3 min, const float3 max clamp_range(value.z, min.z, max.z)); } -static void map_range_vector_signature(fn::MFSignatureBuilder *signature, bool use_steps) +template static auto build_float_linear() { - signature->single_input("Vector"); - signature->single_input("From Min"); - signature->single_input("From Max"); - signature->single_input("To Min"); - signature->single_input("To Max"); - if (use_steps) { - signature->single_input("Steps"); - } - signature->single_output("Vector"); + return fn::CustomMF, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag>{ + Clamp ? "Map Range (clamped)" : "Map Range (unclamped)", + [](float value, float from_min, float from_max, float to_min, float to_max, float *r_value) { + const float factor = safe_divide(value - from_min, from_max - from_min); + float result = to_min + factor * (to_max - to_min); + if constexpr (Clamp) { + result = clamp_range(result, to_min, to_max); + } + *r_value = result; + }, + fn::CustomMF_presets::SomeSpanOrSingle<0>()}; } -class MapRangeVectorFunction : public fn::MultiFunction { - private: - bool clamp_; - - public: - MapRangeVectorFunction(bool clamp) : clamp_(clamp) - { - static fn::MFSignature signature = create_signature(); - this->set_signature(&signature); - } - - static fn::MFSignature create_signature() - { - fn::MFSignatureBuilder signature{"Vector Map Range"}; - map_range_vector_signature(&signature, false); - return signature.build(); - } - - void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override - { - const VArray &values = params.readonly_single_input(0, "Vector"); - const VArray &from_min = params.readonly_single_input(1, "From Min"); - const VArray &from_max = params.readonly_single_input(2, "From Max"); - const VArray &to_min = params.readonly_single_input(3, "To Min"); - const VArray &to_max = params.readonly_single_input(4, "To Max"); - MutableSpan results = params.uninitialized_single_output(5, "Vector"); - - for (int64_t i : mask) { - float3 factor = math::safe_divide(values[i] - from_min[i], from_max[i] - from_min[i]); - results[i] = factor * (to_max[i] - to_min[i]) + to_min[i]; - } - - if (clamp_) { - for (int64_t i : mask) { - results[i] = clamp_range(results[i], to_min[i], to_max[i]); - } - } - } -}; - -class MapRangeSteppedVectorFunction : public fn::MultiFunction { - private: - bool clamp_; - - public: - MapRangeSteppedVectorFunction(bool clamp) : clamp_(clamp) - { - static fn::MFSignature signature = create_signature(); - this->set_signature(&signature); - } - - static fn::MFSignature create_signature() - { - fn::MFSignatureBuilder signature{"Vector Map Range Stepped"}; - map_range_vector_signature(&signature, true); - return signature.build(); - } - - void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override - { - const VArray &values = params.readonly_single_input(0, "Vector"); - const VArray &from_min = params.readonly_single_input(1, "From Min"); - const VArray &from_max = params.readonly_single_input(2, "From Max"); - const VArray &to_min = params.readonly_single_input(3, "To Min"); - const VArray &to_max = params.readonly_single_input(4, "To Max"); - const VArray &steps = params.readonly_single_input(5, "Steps"); - MutableSpan results = params.uninitialized_single_output(6, "Vector"); - - for (int64_t i : mask) { - float3 factor = math::safe_divide(values[i] - from_min[i], from_max[i] - from_min[i]); - factor = math::safe_divide(math::floor(factor * (steps[i] + 1.0f)), steps[i]); - results[i] = factor * (to_max[i] - to_min[i]) + to_min[i]; - } - - if (clamp_) { - for (int64_t i : mask) { - results[i] = clamp_range(results[i], to_min[i], to_max[i]); - } - } - } -}; - -class MapRangeSmoothstepVectorFunction : public fn::MultiFunction { - public: - MapRangeSmoothstepVectorFunction() - { - static fn::MFSignature signature = create_signature(); - this->set_signature(&signature); - } - - static fn::MFSignature create_signature() - { - fn::MFSignatureBuilder signature{"Vector Map Range Smoothstep"}; - map_range_vector_signature(&signature, false); - return signature.build(); - } - - void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override - { - const VArray &values = params.readonly_single_input(0, "Vector"); - const VArray &from_min = params.readonly_single_input(1, "From Min"); - const VArray &from_max = params.readonly_single_input(2, "From Max"); - const VArray &to_min = params.readonly_single_input(3, "To Min"); - const VArray &to_max = params.readonly_single_input(4, "To Max"); - MutableSpan results = params.uninitialized_single_output(5, "Vector"); - - for (int64_t i : mask) { - float3 factor = math::safe_divide(values[i] - from_min[i], from_max[i] - from_min[i]); - clamp_v3(factor, 0.0f, 1.0f); - factor = (float3(3.0f) - 2.0f * factor) * (factor * factor); - results[i] = factor * (to_max[i] - to_min[i]) + to_min[i]; - } - } -}; - -class MapRangeSmootherstepVectorFunction : public fn::MultiFunction { - public: - MapRangeSmootherstepVectorFunction() - { - static fn::MFSignature signature = create_signature(); - this->set_signature(&signature); - } - - static fn::MFSignature create_signature() - { - fn::MFSignatureBuilder signature{"Vector Map Range Smoothstep"}; - map_range_vector_signature(&signature, false); - return signature.build(); - } - - void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override - { - const VArray &values = params.readonly_single_input(0, "Vector"); - const VArray &from_min = params.readonly_single_input(1, "From Min"); - const VArray &from_max = params.readonly_single_input(2, "From Max"); - const VArray &to_min = params.readonly_single_input(3, "To Min"); - const VArray &to_max = params.readonly_single_input(4, "To Max"); - MutableSpan results = params.uninitialized_single_output(5, "Vector"); - - for (int64_t i : mask) { - float3 factor = math::safe_divide(values[i] - from_min[i], from_max[i] - from_min[i]); - clamp_v3(factor, 0.0f, 1.0f); - factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f); - results[i] = factor * (to_max[i] - to_min[i]) + to_min[i]; - } - } -}; - -static void map_range_signature(fn::MFSignatureBuilder *signature, bool use_steps) +template static auto build_float_stepped() { - signature->single_input("Value"); - signature->single_input("From Min"); - signature->single_input("From Max"); - signature->single_input("To Min"); - signature->single_input("To Max"); - if (use_steps) { - signature->single_input("Steps"); - } - signature->single_output("Result"); + return fn::CustomMF, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag>{ + Clamp ? "Map Range Stepped (clamped)" : "Map Range Stepped (unclamped)", + [](float value, + float from_min, + float from_max, + float to_min, + float to_max, + float steps, + float *r_value) { + float factor = safe_divide(value - from_min, from_max - from_min); + factor = safe_divide(floorf(factor * (steps + 1.0f)), steps); + float result = to_min + factor * (to_max - to_min); + if constexpr (Clamp) { + result = clamp_range(result, to_min, to_max); + } + *r_value = result; + }, + fn::CustomMF_presets::SomeSpanOrSingle<0>()}; } -class MapRangeFunction : public fn::MultiFunction { - private: - bool clamp_; - - public: - MapRangeFunction(bool clamp) : clamp_(clamp) - { - static fn::MFSignature signature = create_signature(); - this->set_signature(&signature); - } - - static fn::MFSignature create_signature() - { - fn::MFSignatureBuilder signature{"Map Range"}; - map_range_signature(&signature, false); - return signature.build(); - } - - void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override - { - const VArray &values = params.readonly_single_input(0, "Value"); - const VArray &from_min = params.readonly_single_input(1, "From Min"); - const VArray &from_max = params.readonly_single_input(2, "From Max"); - const VArray &to_min = params.readonly_single_input(3, "To Min"); - const VArray &to_max = params.readonly_single_input(4, "To Max"); - MutableSpan results = params.uninitialized_single_output(5, "Result"); - - for (int64_t i : mask) { - float factor = safe_divide(values[i] - from_min[i], from_max[i] - from_min[i]); - results[i] = to_min[i] + factor * (to_max[i] - to_min[i]); - } - - if (clamp_) { - for (int64_t i : mask) { - results[i] = clamp_range(results[i], to_min[i], to_max[i]); - } - } - } -}; - -class MapRangeSteppedFunction : public fn::MultiFunction { - private: - bool clamp_; - - public: - MapRangeSteppedFunction(bool clamp) : clamp_(clamp) - { - static fn::MFSignature signature = create_signature(); - this->set_signature(&signature); - } - - static fn::MFSignature create_signature() - { - fn::MFSignatureBuilder signature{"Map Range Stepped"}; - map_range_signature(&signature, true); - return signature.build(); - } - - void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override - { - const VArray &values = params.readonly_single_input(0, "Value"); - const VArray &from_min = params.readonly_single_input(1, "From Min"); - const VArray &from_max = params.readonly_single_input(2, "From Max"); - const VArray &to_min = params.readonly_single_input(3, "To Min"); - const VArray &to_max = params.readonly_single_input(4, "To Max"); - const VArray &steps = params.readonly_single_input(5, "Steps"); - MutableSpan results = params.uninitialized_single_output(6, "Result"); - - for (int64_t i : mask) { - float factor = safe_divide(values[i] - from_min[i], from_max[i] - from_min[i]); - factor = safe_divide(floorf(factor * (steps[i] + 1.0f)), steps[i]); - results[i] = to_min[i] + factor * (to_max[i] - to_min[i]); - } - - if (clamp_) { - for (int64_t i : mask) { - results[i] = clamp_range(results[i], to_min[i], to_max[i]); - } - } - } -}; - -class MapRangeSmoothstepFunction : public fn::MultiFunction { - public: - MapRangeSmoothstepFunction() - { - static fn::MFSignature signature = create_signature(); - this->set_signature(&signature); - } - - static fn::MFSignature create_signature() - { - fn::MFSignatureBuilder signature{"Map Range Smoothstep"}; - map_range_signature(&signature, false); - return signature.build(); - } - - void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override - { - const VArray &values = params.readonly_single_input(0, "Value"); - const VArray &from_min = params.readonly_single_input(1, "From Min"); - const VArray &from_max = params.readonly_single_input(2, "From Max"); - const VArray &to_min = params.readonly_single_input(3, "To Min"); - const VArray &to_max = params.readonly_single_input(4, "To Max"); - MutableSpan results = params.uninitialized_single_output(5, "Result"); - - for (int64_t i : mask) { - float factor = safe_divide(values[i] - from_min[i], from_max[i] - from_min[i]); - factor = std::clamp(factor, 0.0f, 1.0f); - factor = (3.0f - 2.0f * factor) * (factor * factor); - results[i] = to_min[i] + factor * (to_max[i] - to_min[i]); - } - } -}; - -class MapRangeSmootherstepFunction : public fn::MultiFunction { - public: - MapRangeSmootherstepFunction() - { - static fn::MFSignature signature = create_signature(); - this->set_signature(&signature); - } - - static fn::MFSignature create_signature() - { - fn::MFSignatureBuilder signature{"Map Range Smoothstep"}; - map_range_signature(&signature, false); - return signature.build(); - } +template static auto build_vector_linear() +{ + return fn::CustomMF, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag>{ + Clamp ? "Vector Map Range (clamped)" : "Vector Map Range (unclamped)", + [](const float3 &value, + const float3 &from_min, + const float3 &from_max, + const float3 &to_min, + const float3 &to_max, + float3 *r_value) { + float3 factor = math::safe_divide(value - from_min, from_max - from_min); + float3 result = factor * (to_max - to_min) + to_min; + if constexpr (Clamp) { + result = clamp_range(result, to_min, to_max); + } + *r_value = result; + }, + fn::CustomMF_presets::SomeSpanOrSingle<0>()}; +} - void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override - { - const VArray &values = params.readonly_single_input(0, "Value"); - const VArray &from_min = params.readonly_single_input(1, "From Min"); - const VArray &from_max = params.readonly_single_input(2, "From Max"); - const VArray &to_min = params.readonly_single_input(3, "To Min"); - const VArray &to_max = params.readonly_single_input(4, "To Max"); - MutableSpan results = params.uninitialized_single_output(5, "Result"); - - for (int64_t i : mask) { - float factor = safe_divide(values[i] - from_min[i], from_max[i] - from_min[i]); - factor = std::clamp(factor, 0.0f, 1.0f); - factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f); - results[i] = to_min[i] + factor * (to_max[i] - to_min[i]); - } - } -}; +template static auto build_vector_stepped() +{ + return fn::CustomMF, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag>{ + Clamp ? "Vector Map Range Stepped (clamped)" : "Vector Map Range Stepped (unclamped)", + [](const float3 &value, + const float3 &from_min, + const float3 &from_max, + const float3 &to_min, + const float3 &to_max, + const float3 &steps, + float3 *r_value) { + float3 factor = math::safe_divide(value - from_min, from_max - from_min); + factor = math::safe_divide(math::floor(factor * (steps + 1.0f)), steps); + float3 result = factor * (to_max - to_min) + to_min; + if constexpr (Clamp) { + result = clamp_range(result, to_min, to_max); + } + *r_value = result; + }, + fn::CustomMF_presets::SomeSpanOrSingle<0>()}; +} static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &builder) { @@ -556,34 +335,70 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui switch (interpolation_type) { case NODE_MAP_RANGE_LINEAR: { if (clamp) { - static MapRangeVectorFunction fn_with_clamp{true}; - builder.set_matching_fn(fn_with_clamp); + static auto fn = build_vector_linear(); + builder.set_matching_fn(fn); } else { - static MapRangeVectorFunction fn_without_clamp{false}; - builder.set_matching_fn(fn_without_clamp); + static auto fn = build_vector_linear(); + builder.set_matching_fn(fn); } break; } case NODE_MAP_RANGE_STEPPED: { if (clamp) { - static MapRangeSteppedVectorFunction fn_stepped_with_clamp{true}; - builder.set_matching_fn(fn_stepped_with_clamp); + static auto fn = build_vector_stepped(); + builder.set_matching_fn(fn); } else { - static MapRangeSteppedVectorFunction fn_stepped_without_clamp{false}; - builder.set_matching_fn(fn_stepped_without_clamp); + static auto fn = build_vector_stepped(); + builder.set_matching_fn(fn); } break; } case NODE_MAP_RANGE_SMOOTHSTEP: { - static MapRangeSmoothstepVectorFunction smoothstep; - builder.set_matching_fn(smoothstep); + static fn::CustomMF, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag> + fn{"Vector Map Range Smoothstep", + [](const float3 &value, + const float3 &from_min, + const float3 &from_max, + const float3 &to_min, + const float3 &to_max, + float3 *r_value) { + float3 factor = math::safe_divide(value - from_min, from_max - from_min); + clamp_v3(factor, 0.0f, 1.0f); + factor = (float3(3.0f) - 2.0f * factor) * (factor * factor); + *r_value = factor * (to_max - to_min) + to_min; + }, + fn::CustomMF_presets::SomeSpanOrSingle<0>()}; + builder.set_matching_fn(fn); break; } case NODE_MAP_RANGE_SMOOTHERSTEP: { - static MapRangeSmootherstepVectorFunction smootherstep; - builder.set_matching_fn(smootherstep); + static fn::CustomMF, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag> + fn{"Vector Map Range Smootherstep", + [](const float3 &value, + const float3 &from_min, + const float3 &from_max, + const float3 &to_min, + const float3 &to_max, + float3 *r_value) { + float3 factor = math::safe_divide(value - from_min, from_max - from_min); + clamp_v3(factor, 0.0f, 1.0f); + factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f); + *r_value = factor * (to_max - to_min) + to_min; + }, + fn::CustomMF_presets::SomeSpanOrSingle<0>()}; + builder.set_matching_fn(fn); break; } default: @@ -594,34 +409,70 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui switch (interpolation_type) { case NODE_MAP_RANGE_LINEAR: { if (clamp) { - static MapRangeFunction fn_with_clamp{true}; - builder.set_matching_fn(fn_with_clamp); + static auto fn = build_float_linear(); + builder.set_matching_fn(fn); } else { - static MapRangeFunction fn_without_clamp{false}; - builder.set_matching_fn(fn_without_clamp); + static auto fn = build_float_linear(); + builder.set_matching_fn(fn); } break; } case NODE_MAP_RANGE_STEPPED: { if (clamp) { - static MapRangeSteppedFunction fn_stepped_with_clamp{true}; - builder.set_matching_fn(fn_stepped_with_clamp); + static auto fn = build_float_stepped(); + builder.set_matching_fn(fn); } else { - static MapRangeSteppedFunction fn_stepped_without_clamp{false}; - builder.set_matching_fn(fn_stepped_without_clamp); + static auto fn = build_float_stepped(); + builder.set_matching_fn(fn); } break; } case NODE_MAP_RANGE_SMOOTHSTEP: { - static MapRangeSmoothstepFunction smoothstep; - builder.set_matching_fn(smoothstep); + static fn::CustomMF, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag> + fn{"Map Range Smoothstep", + [](float value, + float from_min, + float from_max, + float to_min, + float to_max, + float *r_value) { + float factor = safe_divide(value - from_min, from_max - from_min); + factor = std::clamp(factor, 0.0f, 1.0f); + factor = (3.0f - 2.0f * factor) * (factor * factor); + *r_value = to_min + factor * (to_max - to_min); + }, + fn::CustomMF_presets::SomeSpanOrSingle<0>()}; + builder.set_matching_fn(fn); break; } case NODE_MAP_RANGE_SMOOTHERSTEP: { - static MapRangeSmootherstepFunction smootherstep; - builder.set_matching_fn(smootherstep); + static fn::CustomMF, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag, + fn::MFParamTag> + fn{"Map Range Smoothstep", + [](float value, + float from_min, + float from_max, + float to_min, + float to_max, + float *r_value) { + float factor = safe_divide(value - from_min, from_max - from_min); + factor = std::clamp(factor, 0.0f, 1.0f); + factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f); + *r_value = to_min + factor * (to_max - to_min); + }, + fn::CustomMF_presets::SomeSpanOrSingle<0>()}; + builder.set_matching_fn(fn); break; } default: diff --git a/source/blender/nodes/shader/nodes/node_shader_math.cc b/source/blender/nodes/shader/nodes/node_shader_math.cc index a828011a3ab..8a2b18d7d76 100644 --- a/source/blender/nodes/shader/nodes/node_shader_math.cc +++ b/source/blender/nodes/shader/nodes/node_shader_math.cc @@ -106,28 +106,30 @@ static const fn::MultiFunction *get_base_multi_function(bNode &node) const int mode = node.custom1; const fn::MultiFunction *base_fn = nullptr; - try_dispatch_float_math_fl_to_fl(mode, [&](auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SO fn{info.title_case_name.c_str(), function}; - base_fn = &fn; - }); + try_dispatch_float_math_fl_to_fl( + mode, [&](auto devi_fn, auto function, const FloatMathOperationInfo &info) { + static fn::CustomMF_SI_SO fn{ + info.title_case_name.c_str(), function, devi_fn}; + base_fn = &fn; + }); if (base_fn != nullptr) { return base_fn; } - try_dispatch_float_math_fl_fl_to_fl(mode, - [&](auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SI_SO fn{ - info.title_case_name.c_str(), function}; - base_fn = &fn; - }); + try_dispatch_float_math_fl_fl_to_fl( + mode, [&](auto devi_fn, auto function, const FloatMathOperationInfo &info) { + static fn::CustomMF_SI_SI_SO fn{ + info.title_case_name.c_str(), function, devi_fn}; + base_fn = &fn; + }); if (base_fn != nullptr) { return base_fn; } try_dispatch_float_math_fl_fl_fl_to_fl( - mode, [&](auto function, const FloatMathOperationInfo &info) { + mode, [&](auto devi_fn, auto function, const FloatMathOperationInfo &info) { static fn::CustomMF_SI_SI_SI_SO fn{ - info.title_case_name.c_str(), function}; + info.title_case_name.c_str(), function, devi_fn}; base_fn = &fn; }); if (base_fn != nullptr) { diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc index 0d751157817..94a6febe92e 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc @@ -106,7 +106,9 @@ static int gpu_shader_combxyz(GPUMaterial *mat, static void sh_node_combxyz_build_multi_function(NodeMultiFunctionBuilder &builder) { static fn::CustomMF_SI_SI_SI_SO fn{ - "Combine Vector", [](float x, float y, float z) { return float3(x, y, z); }}; + "Combine Vector", + [](float x, float y, float z) { return float3(x, y, z); }, + fn::CustomMF_presets::AllSpanOrSingle()}; builder.set_matching_fn(fn); } diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc index 02a3552704e..21f5c44c640 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc @@ -231,20 +231,20 @@ static const fn::MultiFunction *get_multi_function(bNode &node) const fn::MultiFunction *multi_fn = nullptr; - try_dispatch_float_math_fl3_fl3_to_fl3(operation, - [&](auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SI_SO fn{ - info.title_case_name.c_str(), function}; - multi_fn = &fn; - }); + try_dispatch_float_math_fl3_fl3_to_fl3( + operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { + static fn::CustomMF_SI_SI_SO fn{ + info.title_case_name.c_str(), function, exec_preset}; + multi_fn = &fn; + }); if (multi_fn != nullptr) { return multi_fn; } try_dispatch_float_math_fl3_fl3_fl3_to_fl3( - operation, [&](auto function, const FloatMathOperationInfo &info) { + operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { static fn::CustomMF_SI_SI_SI_SO fn{ - info.title_case_name.c_str(), function}; + info.title_case_name.c_str(), function, exec_preset}; multi_fn = &fn; }); if (multi_fn != nullptr) { @@ -252,38 +252,39 @@ static const fn::MultiFunction *get_multi_function(bNode &node) } try_dispatch_float_math_fl3_fl3_fl_to_fl3( - operation, [&](auto function, const FloatMathOperationInfo &info) { + operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { static fn::CustomMF_SI_SI_SI_SO fn{ - info.title_case_name.c_str(), function}; + info.title_case_name.c_str(), function, exec_preset}; multi_fn = &fn; }); if (multi_fn != nullptr) { return multi_fn; } - try_dispatch_float_math_fl3_fl3_to_fl(operation, - [&](auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SI_SO fn{ - info.title_case_name.c_str(), function}; - multi_fn = &fn; - }); + try_dispatch_float_math_fl3_fl3_to_fl( + operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { + static fn::CustomMF_SI_SI_SO fn{ + info.title_case_name.c_str(), function, exec_preset}; + multi_fn = &fn; + }); if (multi_fn != nullptr) { return multi_fn; } - try_dispatch_float_math_fl3_fl_to_fl3(operation, - [&](auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SI_SO fn{ - info.title_case_name.c_str(), function}; - multi_fn = &fn; - }); + try_dispatch_float_math_fl3_fl_to_fl3( + operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { + static fn::CustomMF_SI_SI_SO fn{ + info.title_case_name.c_str(), function, exec_preset}; + multi_fn = &fn; + }); if (multi_fn != nullptr) { return multi_fn; } try_dispatch_float_math_fl3_to_fl3( - operation, [&](auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SO fn{info.title_case_name.c_str(), function}; + operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { + static fn::CustomMF_SI_SO fn{ + info.title_case_name.c_str(), function, exec_preset}; multi_fn = &fn; }); if (multi_fn != nullptr) { @@ -291,8 +292,9 @@ static const fn::MultiFunction *get_multi_function(bNode &node) } try_dispatch_float_math_fl3_to_fl( - operation, [&](auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SO fn{info.title_case_name.c_str(), function}; + operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { + static fn::CustomMF_SI_SO fn{ + info.title_case_name.c_str(), function, exec_preset}; multi_fn = &fn; }); if (multi_fn != nullptr) { -- cgit v1.2.3