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:
authorJacques Lucke <jacques@blender.org>2022-04-10 16:17:57 +0300
committerJacques Lucke <jacques@blender.org>2022-04-10 16:17:57 +0300
commitf7908bda064209fb9010a5d3622aa62b5b9f20ed (patch)
tree4f2f419c028a96f41ea4fc30402381ff85ba5754
parent3e5b98827272aed2f9efce9c98348d3a49901541 (diff)
support execute materialized
-rw-r--r--source/blender/blenlib/BLI_virtual_array_devirtualize.hh59
-rw-r--r--source/blender/blenlib/tests/BLI_virtual_array_test.cc2
2 files changed, 60 insertions, 1 deletions
diff --git a/source/blender/blenlib/BLI_virtual_array_devirtualize.hh b/source/blender/blenlib/BLI_virtual_array_devirtualize.hh
index 3164dcf459b..2293b55b663 100644
--- a/source/blender/blenlib/BLI_virtual_array_devirtualize.hh
+++ b/source/blender/blenlib/BLI_virtual_array_devirtualize.hh
@@ -37,6 +37,9 @@ struct DevirtualizeSpan {
struct DevirtualizeSingle {
};
+template<typename TagsTuple, size_t I>
+using BaseType = typename std::tuple_element_t<I, TagsTuple>::BaseType;
+
template<typename Fn, typename... Args> class ArrayDevirtualizer {
private:
using TagsTuple = std::tuple<Args...>;
@@ -69,7 +72,63 @@ template<typename Fn, typename... Args> class ArrayDevirtualizer {
return this->try_execute_devirtualized_impl();
}
+ void execute_materialized()
+ {
+ BLI_assert(!executed_);
+ this->execute_materialized_impl(std::make_index_sequence<sizeof...(Args)>{});
+ }
+
private:
+ template<size_t... I> void execute_materialized_impl(std::index_sequence<I...> /* indices */)
+ {
+ static constexpr int64_t MaxChunkSize = 32;
+ const int64_t mask_size = mask_.size();
+ std::tuple<TypedBuffer<BaseType<TagsTuple, I>, MaxChunkSize>...> buffers_owner;
+ std::tuple<MutableSpan<BaseType<TagsTuple, I>>...> buffers = {
+ MutableSpan{std::get<I>(buffers_owner).ptr(), std::min(mask_size, MaxChunkSize)}...};
+
+ for (int64_t chunk_start = 0; chunk_start < mask_size; chunk_start += MaxChunkSize) {
+ const int64_t chunk_size = std::min(mask_size - chunk_start, MaxChunkSize);
+ const IndexMask sliced_mask = mask_.slice(chunk_start, chunk_size);
+ const int64_t sliced_mask_size = sliced_mask.size();
+ (
+ [&]() {
+ using ParamTag = std::tuple_element_t<I, TagsTuple>;
+ using T = typename ParamTag::BaseType;
+ if constexpr (std::is_base_of_v<SingleInputTagBase, ParamTag>) {
+ MutableSpan in_chunk = std::get<I>(buffers).take_front(sliced_mask_size);
+ const VArray<T> *varray = std::get<I>(params_);
+ varray->materialize_compressed_to_uninitialized(sliced_mask, in_chunk);
+ }
+ }(),
+ ...);
+
+ fn_(IndexRange(sliced_mask_size), sliced_mask, [&]() {
+ using ParamTag = std::tuple_element_t<I, TagsTuple>;
+ using T = typename ParamTag::BaseType;
+ if constexpr (std::is_base_of_v<SingleInputTagBase, ParamTag>) {
+ MutableSpan<T> in_chunk = std::get<I>(buffers).take_front(sliced_mask_size);
+ return in_chunk;
+ }
+ else if constexpr (std::is_base_of_v<SingleOutputTagBase, ParamTag>) {
+ MutableSpan<T> out_span = *std::get<I>(params_);
+ return out_span.data();
+ }
+ }()...);
+
+ (
+ [&]() {
+ using ParamTag = std::tuple_element_t<I, TagsTuple>;
+ using T = typename ParamTag::BaseType;
+ if constexpr (std::is_base_of_v<SingleInputTagBase, ParamTag>) {
+ MutableSpan<T> in_chunk = std::get<I>(buffers);
+ destruct_n(in_chunk.data(), sliced_mask_size);
+ }
+ }(),
+ ...);
+ }
+ }
+
template<typename... Mode> bool try_execute_devirtualized_impl()
{
if constexpr (sizeof...(Mode) == sizeof...(Args)) {
diff --git a/source/blender/blenlib/tests/BLI_virtual_array_test.cc b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
index 95222e72bb0..a1d43c89cdf 100644
--- a/source/blender/blenlib/tests/BLI_virtual_array_test.cc
+++ b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
@@ -256,7 +256,7 @@ TEST(virtual_array, Devirtualize)
devirtualizer{fn, &mask, &in1, &in2, &out1};
if (!devirtualizer.try_execute_devirtualized()) {
- devirtualizer.execute_fallback();
+ devirtualizer.execute_materialized();
}
EXPECT_EQ(out1[0], 8);