chrono_batch_render/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
49 / 51
96.1%
Branches:
26 / 34
76.5%
Functions:
5 / 5, 10 excl
100.0%

scene/tables/instances.h
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 #pragma once
3
4 #include <cstdint>
5 #include <map>
6 #include <optional>
7 #include <set>
8 #include <span>
9 #include <vector>
10
11 #include "chrono_batch_render/bvh/builder.h"
12 #include "chrono_batch_render/device/buffer.h"
13 #include "chrono_batch_render/device/program.h"
14 #include "chrono_batch_render/device/ref.h"
15 #include "chrono_batch_render/scene/tables/kernels/instances.h"
16 #include "chrono_batch_render/scene/tables/regions.h"
17 #include "chrono_batch_render/scene/tables/storage.h"
18 #include "chrono_batch_render/scene/tables/table.h"
19 #include "chrono_batch_render/stage/structure/structure.h"
20
21 namespace chrono::batch_render {
22
23
1/1
✓ Branch 1 taken 379 times.
379 struct InstanceStats {
24 uint32_t tlases = 0;
25 uint32_t instances = 0;
26 uint32_t written = 0;
27 uint32_t built = 0;
28 uint32_t refit = 0;
29 bool relaid = false;
30 };
31
32 class InstanceTable : public RenderTable {
33 public:
34 InstanceTable(Structure& structure, const RenderTables& tables, bvh::Builder& builder,
35 uint32_t maxRefits = 16);
36
37 978 std::string_view Name() const override {
38 978 return "instances";
39 }
40
41 std::span<const ColumnRef> Inputs() const override;
42
43 3502 std::span<const TableId> TableInputs() const override {
44 3502 static constexpr TableId kTables[] = {
45 TableId::Transforms, TableId::Imageables, TableId::Meshes, TableId::MeshPoints,
46 TableId::Points, TableId::PointsMoved, TableId::Curves, TableId::CurvesMoved};
47 3502 return kTables;
48 }
49
50 379 std::span<const TableId> TableOutputs() const override {
51 379 static constexpr TableId kTables[] = {TableId::Instances, TableId::Slots};
52 379 return kTables;
53 }
54
55 void Prepare() override;
56 void Run(const ChangeSet& changes, TableVersions& versions) override;
57
58 const InstanceStats& Stats() const {
59
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✓ Branch 3 taken 1 time.
2 return m_stats;
60 }
61
62 const Ref<bvh::Tlas>& Tlas() const {
63 return m_tlas;
64 }
65
66 const Ref<device::Buffer>& Layout() const {
67
2/2
✓ Branch 1 taken 1 time.
✓ Branch 4 taken 1 time.
2 return m_layout;
68 }
69
70 const Ref<device::Buffer>& Origins() const {
71
1/1
✓ Branch 1 taken 1 time.
5 return m_renderOrigins.Buffer();
72 }
73
74 void Describe(RenderTables& tables) const override;
75 void Hold(std::vector<Ref<const RefCounted>>& held) const override;
76
77 const Ref<device::Buffer>& Records() const {
78
1/1
✓ Branch 1 taken 9 times.
22 return m_records.Buffer();
79 }
80
81 const Ref<device::Buffer>& Hits() const {
82
1/1
✓ Branch 1 taken 9 times.
9 return m_hits.Buffer();
83 }
84
85 76 const std::set<uint32_t>& Members() const {
86 76 return m_members;
87 }
88
89 345 std::span<const std::pair<uint32_t, uint32_t>> LightCopies(uint32_t tlas) const {
90
1/2
✓ Branch 0 taken 345 times.
✗ Branch 1 not taken.
345 return tlas < m_lightCopies.size() ? std::span(m_lightCopies[tlas])
91 345 : std::span<const std::pair<uint32_t, uint32_t>>();
92 }
93
94 662 std::span<const uint32_t> FirstInstances() const {
95
1/2
✓ Branch 0 taken 649 times.
✗ Branch 1 not taken.
662 return m_regions.Starts();
96 }
97
98 1394 std::span<const uint32_t> InstanceCounts() const {
99
3/4
<unknown function 59>:
✓ Branch 1 taken 1 time.
<unknown function 78>:
✓ Branch 1 taken 9 times.
<unknown function 94>:
✓ Branch 0 taken 649 times.
✗ Branch 1 not taken.
1394 return m_regions.Counts();
100 }
101
102 748 std::span<const uint32_t> InstancePrims() const {
103 748 return m_regions.Items();
104 }
105
106 std::set<uint32_t> Tlases(uint32_t world) const;
107
108 42 uint32_t Relayouts() const {
109
7/7
<unknown function 108>:
✓ Branch 1 taken 18 times.
✓ Branch 4 taken 18 times.
<unknown function 78>:
✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✓ Branch 8 taken 1 time.
✓ Branch 11 taken 1 time.
✓ Branch 14 taken 1 time.
42 return m_relayouts;
110 }
111
112 private:
113 7196 struct Instancer {
114 7 uint32_t prim = kNoPrim;
115 7 uint32_t world = kGlobalWorld;
116 7 uint32_t count = 0;
117 3 bool native = false;
118 3 std::vector<uint32_t> roots;
119
120
6/10
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
7 bool operator==(const Instancer&) const = default;
121 };
122
123 std::vector<Instancer> GatherInstancers() const;
124 bool Member(uint32_t prim) const;
125 void Relayout();
126 void BuildInstancing();
127 void WriteLayoutHeader();
128 void WriteRegions(const std::set<uint32_t>& tlases);
129 device::BufferRange LayoutWords(uint64_t address, uint32_t first, uint32_t count) const;
130 bool Restack();
131 std::optional<std::set<uint32_t>> Apply(const ChangeSet& changes);
132 std::vector<uint32_t> RegionItems(uint32_t tlas) const;
133 bool ShowsGlobals(uint32_t tlas) const;
134 void Compose();
135
136 Structure& m_structure;
137 const RenderTables& m_tables;
138 bvh::Builder& m_builder;
139 uint32_t m_maxRefits;
140 Ref<device::Buffer> m_unitBoxes;
141 Ref<bvh::Blas> m_unitBox;
142 device::Program& Kernels();
143
144 Ref<device::Program> m_program;
145 Ref<bvh::Tlas> m_tlas;
146 DeviceTable<InstanceRecord> m_records{"instances", device::BufferUsage::AccelBuildInput};
147 DeviceTable<ShapeRecord> m_shapes{"instance shapes"};
148 Ref<device::Buffer> m_layout;
149 InstanceLayout m_header{};
150 DeviceTable<SlotHit> m_hits{"instance hits"};
151 DeviceTable<WorldTransform> m_slotWorlds{"slot worlds"};
152 Ref<device::Buffer> m_instancing;
153 std::vector<Instancer> m_instancers;
154 std::set<uint32_t> m_instancerPrims;
155 std::set<uint32_t> m_roots;
156 std::set<uint32_t> m_members;
157 std::vector<std::vector<uint32_t>> m_blockItems;
158 std::map<uint32_t, std::vector<uint32_t>> m_drawables;
159 std::map<uint32_t, std::vector<uint32_t>> m_nested;
160 std::vector<std::vector<std::pair<uint32_t, uint32_t>>> m_lightCopies;
161 std::map<uint32_t, std::set<uint32_t>> m_watch;
162 DeviceTable<RenderOrigin> m_renderOrigins{"render origins"};
163 Ref<device::Buffer> m_viewers;
164 std::vector<uint32_t> m_products;
165 Ref<device::Buffer> m_productBuffer;
166 std::map<uint32_t, ComposedWorldDesc> m_composed;
167 std::map<uint32_t, std::set<uint32_t>> m_shownIn;
168 uint64_t m_compositions = ~uint64_t(0);
169 std::vector<std::vector<uint32_t>> m_own;
170 std::vector<uint32_t> m_globals;
171 std::set<uint32_t> m_origins;
172 Regions m_regions;
173 std::vector<uint32_t> m_refits;
174 uint64_t m_seen = 0;
175 uint32_t m_worlds = 0;
176 uint32_t m_relayouts = 0;
177 InstanceStats m_stats;
178 };
179
180 }
181