chrono_batch_render/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
81 / 82
98.8%
Branches:
61 / 68
89.7%
Functions:
10 / 10
100.0%

scene/tables/pack.cpp
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 #include "chrono_batch_render/scene/tables/pack.h"
3
4 #include <algorithm>
5
6 #include "chrono_batch_render/device/commands.h"
7 #include "chrono_batch_render/device/device.h"
8 #include "chrono_batch_render/device/queue.h"
9 #include "chrono_batch_render/scene/kernels.h"
10 #include "chrono_batch_render/scene/tables/kernels/pack.h"
11 #include "chrono_batch_render/util/profiler.h"
12
13 namespace chrono::batch_render {
14
15 789 void PackPlan::Clear() {
16 789 m_copies.clear();
17 789 m_literals.clear();
18 789 m_columns.clear();
19 789 m_count = 0;
20 789 }
21
22 1493 void PackPlan::Copy(ColumnRef column, uint32_t row, uint32_t destination) {
23 1493 m_copies.push_back({column, row, destination});
24
2/2
✓ Branch 1 taken 1121 times.
✓ Branch 2 taken 372 times.
1493 if (!Reads(column.column)) {
25 1121 m_columns.push_back(column);
26 }
27 1493 }
28
29 3381 uint32_t PackPlan::Literal(uint32_t destination, uint32_t value) {
30 3381 m_literals.push_back({destination, value});
31 3381 return uint32_t(m_literals.size() - 1);
32 }
33
34 50 void PackPlan::SetLiteral(uint32_t literal, uint32_t value) {
35 50 m_literals[literal].value = value;
36 50 m_literals[literal].late = true;
37 50 }
38
39 1516 bool PackPlan::Reads(const ColumnInfo* column) const {
40 1516 return std::ranges::find(m_columns, column, &ColumnRef::column) != m_columns.end();
41 }
42
43 186 bool PackPlan::Stale(const ColumnStore& store, uint64_t since) const {
44 186 return std::ranges::any_of(m_columns,
45 473 [&](ColumnRef column) { return store.LastWrite(column) > since; });
46 }
47
48 311 uint32_t PackPlan::Twice(uint32_t words) const {
49 311 std::vector<uint8_t> written(words, 0);
50 311 uint32_t twice = kNoPrim;
51 6066 const auto write = [&](uint32_t word) {
52
2/6
✓ Branch 0 taken 5755 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5755 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
5755 if (word < written.size() && written[word]++ != 0 && twice == kNoPrim) {
53 ✗ twice = word;
54 }
55 6066 };
56
2/2
✓ Branch 0 taken 1392 times.
✓ Branch 1 taken 311 times.
1703 for (const Cell& copy : m_copies) {
57 1392 const uint32_t cells = ElementBytes(copy.column.column->type) / sizeof(uint32_t);
58
2/2
✓ Branch 0 taken 2374 times.
✓ Branch 1 taken 1392 times.
3766 for (uint32_t word = 0; word < cells; ++word) {
59 2374 write(copy.destination + word);
60 }
61 }
62
2/2
✓ Branch 0 taken 3381 times.
✓ Branch 1 taken 311 times.
3692 for (const Word& literal : m_literals) {
63 3381 write(literal.destination);
64 }
65 311 return twice;
66 311 }
67
68 828 void PackPlan::Build(ColumnStore& store, bool zeroed) {
69 828 std::vector<PackEntry> entries;
70
1/1
✓ Branch 1 taken 828 times.
828 entries.reserve(m_copies.size() + m_literals.size());
71
2/2
✓ Branch 0 taken 2091 times.
✓ Branch 1 taken 828 times.
2919 for (const Cell& copy : m_copies) {
72
1/1
✓ Branch 1 taken 2091 times.
2091 const ColumnTable& table = store.Schema(copy.column.schema);
73
1/1
✓ Branch 1 taken 2091 times.
4182 entries.push_back({.pages = table.Pages(copy.column.index),
74 2091 .row = copy.row,
75
1/1
✓ Branch 1 taken 2091 times.
2091 .words = table.CellBytes(copy.column.index) / uint32_t(sizeof(uint32_t)),
76
1/1
✓ Branch 1 taken 2091 times.
2091 .destination = copy.destination});
77 }
78
2/2
✓ Branch 0 taken 4755 times.
✓ Branch 1 taken 828 times.
5583 for (const Word& literal : m_literals) {
79
5/6
✓ Branch 0 taken 4755 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4705 times.
✓ Branch 3 taken 50 times.
✓ Branch 4 taken 1776 times.
✓ Branch 5 taken 2929 times.
4755 if (!zeroed || literal.late || literal.value != 0) {
80 1826 entries.push_back(
81
1/1
✓ Branch 1 taken 1826 times.
1826 {.words = 1, .destination = literal.destination, .value = literal.value});
82 }
83 }
84
2/2
✓ Branch 0 taken 715 times.
✓ Branch 1 taken 113 times.
828 m_count = uint32_t(entries.size());
85
2/2
✓ Branch 0 taken 715 times.
✓ Branch 1 taken 113 times.
828 if (entries.empty()) {
86 715 return;
87 }
88
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 60 times.
113 device::Device& device = store.GetDevice();
89 113 const uint64_t bytes = entries.size() * sizeof(PackEntry);
90
4/4
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 60 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 43 times.
113 if (!m_entries || m_entries->Bytes() < bytes) {
91
3/3
✓ Branch 1 taken 70 times.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 60 times.
80 m_entries = device.CreateBuffer({.bytes = bytes, .label = m_label + " pack entries"});
92 }
93
2/2
✓ Branch 1 taken 113 times.
✓ Branch 4 taken 113 times.
113 device.GetQueue().Write(m_entries->Slice(0, bytes), entries.data());
94 898 }
95
96 854 void PackPlan::Pack(ColumnStore& store, uint64_t words) {
97
2/2
✓ Branch 0 taken 715 times.
✓ Branch 1 taken 139 times.
854 if (m_count == 0) {
98 715 return;
99 }
100
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 79 times.
139 device::Device& device = store.GetDevice();
101
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 79 times.
139 if (!m_program) {
102 60 m_program =
103
2/2
✓ Branch 2 taken 60 times.
✓ Branch 5 taken 60 times.
180 device.CreateProgram({.modules = {"chrono_batch_render.scene.tables.kernels.pack"},
104 .library = &kSceneKernels,
105 .entries = {"PackWords"},
106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 .label = m_label + " pack"});
107 }
108 139 PackParams params{};
109
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 134 times.
139 params.entries.address = m_entries->Address();
110 139 params.words.address = words;
111 139 params.count = m_count;
112
4/5
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 134 times.
✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 5 times.
139 static const profiler::ZoneId zone = profiler::ZoneId::Named("Tables/Pack");
113 139 device::Queue& queue = device.GetQueue();
114 139 device::CommandEncoder encoder = queue.CreateEncoder();
115 139 {
116
1/1
✓ Branch 1 taken 139 times.
139 const device::ZoneScope scope(encoder, zone);
117
2/2
✓ Branch 1 taken 139 times.
✓ Branch 4 taken 139 times.
139 encoder.Dispatch(m_program->Entry("PackWords"), params,
118
1/1
✓ Branch 1 taken 139 times.
139 {.x = device::GroupCount(params.count, kPackGroup)});
119 139 }
120
2/2
✓ Branch 1 taken 139 times.
✓ Branch 4 taken 139 times.
139 queue.Submit(encoder.Finish());
121 259 }
122
123 }
124