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:
authorHans Goudey <h.goudey@me.com>2022-03-25 02:47:48 +0300
committerHans Goudey <h.goudey@me.com>2022-03-25 02:48:38 +0300
commitd3a1e9cbb92cca04e2fcbce3b8de3fdf25f2fcc6 (patch)
tree5326c2d1abd2429ea50b67c2735deb71dc9e8e1d /source/blender/functions
parentb030ec8760a0f3ca9b0eb36c265cb35025fdc7ca (diff)
Geometry Nodes: Multi-thread creation of selection from field
When boolean fields are evaluated and used as selections, we create a vector of indices. This process is currently single-threaded, but 226f0c4fef7e7792c added a more optimized multi-threaded version of this process. It's simple to use this in the field evaluator. I tested this with the set position node and a random value node set to boolean mode on a Ryzen 2700x: | | Before | After | Improvement | | 10% Selected | 40.5 ms | 29.0 ms | 1.4x | | 90% Selected | 115 ms | 45.3 ms | 2.5x | In the future there could be a specialized version for non-span virtual array selections that uses `materialize` to lower virtual call overhead. Differential Revision: https://developer.blender.org/D14436
Diffstat (limited to 'source/blender/functions')
-rw-r--r--source/blender/functions/intern/field.cc36
1 files changed, 14 insertions, 22 deletions
diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc
index 7b514b6a49b..9f742f11ce4 100644
--- a/source/blender/functions/intern/field.cc
+++ b/source/blender/functions/intern/field.cc
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "BLI_index_mask_ops.hh"
#include "BLI_map.hh"
#include "BLI_multi_value_map.hh"
#include "BLI_set.hh"
@@ -692,29 +693,21 @@ GPointer FieldConstant::value() const
* FieldEvaluator.
*/
-static Vector<int64_t> indices_from_selection(IndexMask mask, const VArray<bool> &selection)
+static IndexMask index_mask_from_selection(const IndexMask full_mask,
+ VArray<bool> &selection,
+ ResourceScope &scope)
{
- /* If the selection is just a single value, it's best to avoid calling this
- * function when constructing an IndexMask and use an IndexRange instead. */
- BLI_assert(!selection.is_single());
-
- Vector<int64_t> indices;
if (selection.is_span()) {
Span<bool> span = selection.get_internal_span();
- for (const int64_t i : mask) {
- if (span[i]) {
- indices.append(i);
- }
- }
+ return index_mask_ops::find_indices_based_on_predicate(
+ full_mask, 4096, scope.construct<Vector<int64_t>>(), [&](const int curve_index) {
+ return span[curve_index];
+ });
}
- else {
- for (const int i : mask) {
- if (selection[i]) {
- indices.append(i);
- }
- }
- }
- return indices;
+ return index_mask_ops::find_indices_based_on_predicate(
+ full_mask, 1024, scope.construct<Vector<int64_t>>(), [&](const int curve_index) {
+ return selection[curve_index];
+ });
}
int FieldEvaluator::add_with_destination(GField field, GVMutableArray dst)
@@ -763,7 +756,7 @@ static IndexMask evaluate_selection(const Field<bool> &selection_field,
}
return IndexRange(0);
}
- return scope.add_value(indices_from_selection(full_mask, selection)).as_span();
+ return index_mask_from_selection(full_mask, selection, scope);
}
return full_mask;
}
@@ -799,8 +792,7 @@ IndexMask FieldEvaluator::get_evaluated_as_mask(const int field_index)
}
return IndexRange(0);
}
-
- return scope_.add_value(indices_from_selection(mask_, varray)).as_span();
+ return index_mask_from_selection(mask_, varray, scope_);
}
IndexMask FieldEvaluator::get_evaluated_selection_as_mask()