[Bf-blender-cvs] [d54eebbfa77] functions: support constant folding for vectors

Jacques Lucke noreply at git.blender.org
Thu Jan 9 18:17:31 CET 2020


Commit: d54eebbfa77e71915384aa12b9d2f62ac805586a
Author: Jacques Lucke
Date:   Thu Jan 9 17:41:10 2020 +0100
Branches: functions
https://developer.blender.org/rBd54eebbfa77e71915384aa12b9d2f62ac805586a

support constant folding for vectors

===================================================================

M	source/blender/functions/intern/multi_function_network_optimization.cc
M	source/blender/functions/intern/multi_functions/constants.cc
M	source/blender/functions/intern/multi_functions/constants.h

===================================================================

diff --git a/source/blender/functions/intern/multi_function_network_optimization.cc b/source/blender/functions/intern/multi_function_network_optimization.cc
index 27a35e0e957..56ce8f3a850 100644
--- a/source/blender/functions/intern/multi_function_network_optimization.cc
+++ b/source/blender/functions/intern/multi_function_network_optimization.cc
@@ -15,18 +15,6 @@ static bool node_can_be_constant(MFBuilderNode &node)
     if (fn.depends_on_context()) {
       return false;
     }
-
-    /* TODO: Support vectors. */
-    for (auto *socket : node.inputs()) {
-      if (socket->data_type().is_vector()) {
-        return false;
-      }
-    }
-    for (auto *socket : node.outputs()) {
-      if (socket->data_type().is_vector()) {
-        return false;
-      }
-    }
     return true;
   }
   else {
@@ -125,7 +113,10 @@ void optimize_network__constant_folding(MFNetworkBuilder &network_builder,
         break;
       }
       case MFDataType::Vector: {
-        BLI_assert(false);
+        const CPPType &cpp_base_type = data_type.vector__cpp_base_type();
+        GenericVectorArray &vector_array = resources.construct<GenericVectorArray>(
+            "constant vector", cpp_base_type, 1);
+        params_builder.add_vector_output(vector_array);
         break;
       }
     }
@@ -136,15 +127,31 @@ void optimize_network__constant_folding(MFNetworkBuilder &network_builder,
   for (uint param_index : network_function.param_indices()) {
     MFParamType param_type = network_function.param_type(param_index);
     MFDataType data_type = param_type.data_type();
-    const CPPType &cpp_type = data_type.single__cpp_type();
 
-    GenericMutableArrayRef array = params_builder.computed_array(param_index);
-    void *buffer = array.buffer();
-    resources.add(buffer, array.type().destruct_cb(), "Constant folded value");
+    const MultiFunction *constant_fn = nullptr;
+
+    switch (data_type.category()) {
+      case MFDataType::Single: {
+        const CPPType &cpp_type = data_type.single__cpp_type();
+
+        GenericMutableArrayRef array = params_builder.computed_array(param_index);
+        void *buffer = array.buffer();
+        resources.add(buffer, array.type().destruct_cb(), "Constant folded value");
+
+        constant_fn = &resources.construct<MF_GenericConstantValue>(
+            "Constant folded function", cpp_type, buffer);
+        break;
+      }
+      case MFDataType::Vector: {
+        GenericVectorArray &vector_array = params_builder.computed_vector_array(param_index);
+        GenericArrayRef array = vector_array[0];
+        constant_fn = &resources.construct<MF_GenericConstantVector>("Constant folded function",
+                                                                     array);
+        break;
+      }
+    }
 
-    const MultiFunction &fn = resources.construct<MF_GenericConstantValue>(
-        "Constant folded function", cpp_type, buffer);
-    MFBuilderFunctionNode &folded_node = network_builder.add_function(fn);
+    MFBuilderFunctionNode &folded_node = network_builder.add_function(*constant_fn);
 
     MFBuilderOutputSocket &original_socket = *builder_sockets_to_compute[param_index];
     Vector<MFBuilderInputSocket *> targets = original_socket.targets();
diff --git a/source/blender/functions/intern/multi_functions/constants.cc b/source/blender/functions/intern/multi_functions/constants.cc
index 85e8978e940..d7425004e8b 100644
--- a/source/blender/functions/intern/multi_functions/constants.cc
+++ b/source/blender/functions/intern/multi_functions/constants.cc
@@ -26,4 +26,49 @@ void MF_GenericConstantValue::value_to_string(std::stringstream &ss,
   }
 }
 
+MF_GenericConstantValue::MF_GenericConstantValue(const CPPType &type, const void *value)
+    : m_value(value)
+{
+  MFSignatureBuilder signature = this->get_builder("Constant " + type.name());
+  std::stringstream ss;
+  MF_GenericConstantValue::value_to_string(ss, type, value);
+  signature.single_output(ss.str(), type);
+}
+
+void MF_GenericConstantValue::call(IndexMask mask,
+                                   MFParams params,
+                                   MFContext UNUSED(context)) const
+{
+  GenericMutableArrayRef r_value = params.uninitialized_single_output(0);
+  r_value.type().fill_uninitialized_indices(m_value, r_value.buffer(), mask);
+}
+
+MF_GenericConstantVector::MF_GenericConstantVector(GenericArrayRef array) : m_array(array)
+{
+  const CPPType &type = array.type();
+  MFSignatureBuilder signature = this->get_builder("Constant " + type.name() + " List");
+  std::stringstream ss;
+  ss << "[";
+  uint max_amount = 5;
+  for (uint i : IndexRange(std::min(max_amount, array.size()))) {
+    MF_GenericConstantValue::value_to_string(ss, type, array[i]);
+    ss << ", ";
+  }
+  if (max_amount < array.size()) {
+    ss << "...";
+  }
+  ss << "]";
+  signature.vector_output(ss.str(), type);
+}
+
+void MF_GenericConstantVector::call(IndexMask mask,
+                                    MFParams params,
+                                    MFContext UNUSED(context)) const
+{
+  GenericVectorArray &r_vectors = params.vector_output(0);
+  for (uint i : mask) {
+    r_vectors.extend_single__copy(i, m_array);
+  }
+}
+
 }  // namespace FN
diff --git a/source/blender/functions/intern/multi_functions/constants.h b/source/blender/functions/intern/multi_functions/constants.h
index db6888427c7..bfe9bfe3c3d 100644
--- a/source/blender/functions/intern/multi_functions/constants.h
+++ b/source/blender/functions/intern/multi_functions/constants.h
@@ -7,7 +7,7 @@
 namespace FN {
 
 /**
- * Note: The value buffer passed into the constructor should have a longer lifetime than the
+ * The value buffer passed into the constructor should have a longer lifetime than the
  * function itself.
  */
 class MF_GenericConstantValue : public MultiFunction {
@@ -15,23 +15,24 @@ class MF_GenericConstantValue : public MultiFunction {
   const void *m_value;
 
  public:
-  MF_GenericConstantValue(const CPPType &type, const void *value) : m_value(value)
-  {
-    MFSignatureBuilder signature = this->get_builder("Constant " + type.name());
-    std::stringstream ss;
-    MF_GenericConstantValue::value_to_string(ss, type, value);
-    signature.single_output(ss.str(), type);
-  }
-
-  void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
-  {
-    GenericMutableArrayRef r_value = params.uninitialized_single_output(0);
-    r_value.type().fill_uninitialized_indices(m_value, r_value.buffer(), mask);
-  }
+  MF_GenericConstantValue(const CPPType &type, const void *value);
+  void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override;
 
   static void value_to_string(std::stringstream &ss, const CPPType &type, const void *value);
 };
 
+/**
+ * The passed in buffer has to have a longer lifetime than the function itself.
+ */
+class MF_GenericConstantVector : public MultiFunction {
+ private:
+  GenericArrayRef m_array;
+
+ public:
+  MF_GenericConstantVector(GenericArrayRef array);
+  void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override;
+};
+
 template<typename T> class MF_ConstantValue : public MultiFunction {
  private:
   T m_value;



More information about the Bf-blender-cvs mailing list