[Bf-blender-cvs] [d4b7f2e1197] temp-viewport-compositor-compiler: Viewport Compositor: Implement single value reduction

Omar Emara noreply at git.blender.org
Thu Mar 31 16:22:13 CEST 2022


Commit: d4b7f2e1197ba0bd86d90fbd9ce64995bd5cfb0b
Author: Omar Emara
Date:   Thu Mar 31 14:58:46 2022 +0200
Branches: temp-viewport-compositor-compiler
https://developer.blender.org/rBd4b7f2e1197ba0bd86d90fbd9ce64995bd5cfb0b

Viewport Compositor: Implement single value reduction

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

M	source/blender/nodes/NOD_compositor_execute.hh
M	source/blender/nodes/intern/node_compositor_execute.cc

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

diff --git a/source/blender/nodes/NOD_compositor_execute.hh b/source/blender/nodes/NOD_compositor_execute.hh
index 1fecad233fc..1898a710d4b 100644
--- a/source/blender/nodes/NOD_compositor_execute.hh
+++ b/source/blender/nodes/NOD_compositor_execute.hh
@@ -501,6 +501,10 @@ class Operation {
   TexturePool &texture_pool();
 
  private:
+  /* Add a reduce to single value input processor for the input identified by the given identifier
+   * if needed. */
+  void add_reduce_to_single_value_input_processor_if_needed(StringRef identifier);
+
   /* Add an implicit conversion input processor for the input identified by the given identifier if
    * needed. */
   void add_implicit_conversion_input_processor_if_needed(StringRef identifier);
@@ -615,6 +619,21 @@ class ProcessorOperation : public Operation {
   InputDescriptor &get_input_descriptor();
 };
 
+/* --------------------------------------------------------------------
+ *  Reduce To Single Value Processor Operation.
+ */
+
+/* A processor that reduces its input result into a single value output result. The input is
+ * assumed to be a texture result of size 1x1, that is, a texture composed of a single pixel, the
+ * value of which shall serve as the single value of the output result. See
+ * add_reduce_to_single_value_input_processor_if_needed. */
+class ReduceToSingleValueProcessorOperation : public ProcessorOperation {
+ public:
+  ReduceToSingleValueProcessorOperation(Context &context, ResultType type);
+
+  void execute() override;
+};
+
 /* --------------------------------------------------------------------
  *  Conversion Processor Operation.
  */
diff --git a/source/blender/nodes/intern/node_compositor_execute.cc b/source/blender/nodes/intern/node_compositor_execute.cc
index 41e01bf18ce..edd15ac1157 100644
--- a/source/blender/nodes/intern/node_compositor_execute.cc
+++ b/source/blender/nodes/intern/node_compositor_execute.cc
@@ -47,6 +47,8 @@
 #include "NOD_derived_node_tree.hh"
 #include "NOD_node_declaration.hh"
 
+#include "MEM_guardedalloc.h"
+
 namespace blender::viewport_compositor {
 
 /* --------------------------------------------------------------------
@@ -426,6 +428,7 @@ void Operation::evaluate_input_processors()
 {
   /* First, add all needed processors for each input. */
   for (const StringRef &identifier : inputs_to_results_map_.keys()) {
+    add_reduce_to_single_value_input_processor_if_needed(identifier);
     add_implicit_conversion_input_processor_if_needed(identifier);
     add_realize_on_domain_input_processor_if_needed(identifier);
   }
@@ -486,6 +489,25 @@ TexturePool &Operation::texture_pool()
   return context_.texture_pool();
 }
 
+void Operation::add_reduce_to_single_value_input_processor_if_needed(StringRef identifier)
+{
+  const Result &result = get_input(identifier);
+  /* Input result is already a single value. */
+  if (result.is_single_value()) {
+    return;
+  }
+
+  /* The input is a full sized texture can can't be reduced to a single value. */
+  if (result.domain().size != int2(1)) {
+    return;
+  }
+
+  /* The input is a texture of a single pixel and can be reduced to a single value. */
+  ProcessorOperation *processor = new ReduceToSingleValueProcessorOperation(context(),
+                                                                            result.type());
+  add_input_processor(identifier, processor);
+}
+
 void Operation::add_implicit_conversion_input_processor_if_needed(StringRef identifier)
 {
   ResultType result_type = get_input(identifier).type();
@@ -528,6 +550,12 @@ void Operation::add_realize_on_domain_input_processor_if_needed(StringRef identi
     return;
   }
 
+  /* Input result only contains a single pixel and will be reduced to a single value result through
+   * a ReduceToSingleValueProcessorOperation, so no need to realize it. */
+  if (result.domain().size == int2(1)) {
+    return;
+  }
+
   /* The input have an identical domain to the operation domain, so no need to realize it. */
   if (result.domain() == compute_domain()) {
     return;
@@ -731,6 +759,43 @@ InputDescriptor &ProcessorOperation::get_input_descriptor()
   return Operation::get_input_descriptor(input_identifier);
 }
 
+/* --------------------------------------------------------------------
+ *  Reduce To Single Value Processor Operation.
+ */
+
+ReduceToSingleValueProcessorOperation::ReduceToSingleValueProcessorOperation(Context &context,
+                                                                             ResultType type)
+    : ProcessorOperation(context)
+{
+  InputDescriptor input_descriptor;
+  input_descriptor.type = type;
+  declare_input_descriptor(input_descriptor);
+  populate_result(Result(type, texture_pool()));
+}
+
+void ReduceToSingleValueProcessorOperation::execute()
+{
+  const Result &input = get_input();
+  GPU_memory_barrier(GPU_BARRIER_TEXTURE_UPDATE);
+  float *pixel = static_cast<float *>(GPU_texture_read(input.texture(), GPU_DATA_FLOAT, 0));
+
+  Result &result = get_result();
+  result.allocate_single_value();
+  switch (result.type()) {
+    case ResultType::Color:
+      result.set_color_value(pixel);
+      break;
+    case ResultType::Vector:
+      result.set_vector_value(pixel);
+      break;
+    case ResultType::Float:
+      result.set_float_value(*pixel);
+      break;
+  }
+
+  MEM_freeN(pixel);
+}
+
 /* --------------------------------------------------------------------
  *  Conversion Processor Operation.
  */
@@ -915,12 +980,6 @@ void RealizeOnDomainProcessorOperation::execute()
   Result &input = get_input();
   Result &result = get_result();
 
-  /* The input have the same domain as the operation domain, so just pass the input through. */
-  if (input.domain() == domain_) {
-    input.pass_through(result);
-    return;
-  }
-
   result.allocate_texture(domain_);
 
   GPUShader *shader = get_realization_shader();



More information about the Bf-blender-cvs mailing list