chrono_batch_render/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
57 / 59
96.6%
Branches:
44 / 45
97.8%
Functions:
13 / 13
100.0%

bvh/common.cpp
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 #include "chrono_batch_render/bvh/common.h"
3
4 #include <algorithm>
5 #include <numeric>
6 #include <utility>
7 #include <variant>
8 #include <vector>
9
10 #include "chrono_batch_render/device/device.h"
11 #include "chrono_batch_render/util/log.h"
12
13 namespace chrono::batch_render::bvh {
14
15 using device::Buffer;
16 using device::BufferRange;
17 using device::Device;
18 using device::Traversal;
19
20 728 const char* FormatName(Traversal format) {
21
2/2
✓ Branch 0 taken 727 times.
✓ Branch 1 taken 1 time.
728 return format == Traversal::Hardware ? "hardware" : "software";
22 }
23
24 3341 uint32_t Kind(const Geometry& geometry) {
25
2/2
✓ Branch 0 taken 619 times.
✓ Branch 1 taken 2722 times.
3341 return std::holds_alternative<device::AccelBoxes>(geometry) ? kBvhBoxes : kBvhTriangles;
26 }
27
28 2013 uint32_t PrimitiveCount(const Geometry& geometry) {
29
2/3
✓ Branch 0 taken 372 times.
✓ Branch 1 taken 1641 times.
✗ Branch 2 not taken.
2013 return std::visit([](const auto& held) { return held.count; }, geometry);
30 }
31
32 121 device::AccelInput ToAccelInput(const Geometry& geometry) {
33 121 return std::visit([](const auto& held) -> device::AccelInput { return held; }, geometry);
34 }
35
36 619 std::vector<Ref<Buffer>> GeometryBuffers(const Geometry& geometry) {
37 619 std::vector<Ref<Buffer>> buffers;
38
1/1
✓ Branch 1 taken 619 times.
619 device::ForEachBuffer(geometry,
39
2/2
✓ Branch 2 taken 111 times.
✓ Branch 3 taken 4 times.
619 [&](BufferRange range) { buffers.emplace_back(&range.GetBuffer()); });
40 619 return buffers;
41 ✗ }
42
43 3238 uint64_t StorageBytes(uint32_t count, uint32_t kind) {
44
4/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3225 times.
✓ Branch 2 taken 1299 times.
✓ Branch 3 taken 1939 times.
3251 return BvhLeavesOffset(count) + uint64_t(count) * BvhRecordWords(kind) * 16;
45 }
46
47 3597 uint64_t Total(std::span<const uint32_t> capacities) {
48 3597 return std::accumulate(capacities.begin(), capacities.end(), uint64_t(0));
49 }
50
51 1615 std::vector<uint32_t> Offsets(std::span<const uint32_t> capacities) {
52 1615 std::vector<uint32_t> offsets = {0};
53
2/2
✓ Branch 0 taken 1919 times.
✓ Branch 1 taken 1615 times.
3534 for (const uint32_t capacity : capacities) {
54
1/1
✓ Branch 1 taken 1919 times.
1919 offsets.push_back(offsets.back() + capacity);
55 }
56 1615 return offsets;
57 ✗ }
58
59 238 Buffer& Reserve(Device& device, Ref<Buffer>& buffer, const device::BufferDesc& desc) {
60
4/4
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 101 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 123 times.
238 if (!buffer || buffer->Bytes() < desc.bytes) {
61 230 Log(LogLevel::Debug, "{} grows from {} to {} bytes", desc.label,
62
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 101 times.
115 buffer ? buffer->Bytes() : 0, desc.bytes);
63
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 101 times.
129 buffer = device.CreateBuffer(desc);
64 }
65 238 return *buffer;
66 }
67
68 785 void RequireInstances(const char* what, const Tlas& tlas, BufferRange instances) {
69 785 const uint64_t total = Total(tlas.Capacities());
70 785 const uint64_t bytes = total * sizeof(InstanceRecord);
71
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 784 times.
785 if (instances.Bytes() < bytes) {
72 1 throw Error("{} of a TLAS of {} instances from {} bytes; it takes {}", what, total,
73
1/1
✓ Branch 2 taken 1 time.
1 instances.Bytes(), bytes);
74 }
75 784 }
76
77 784 std::vector<uint32_t> SelectWorlds(const char* what, const Tlas& tlas,
78 std::span<const uint32_t> worlds) {
79
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 783 times.
784 if (worlds.empty()) {
80 1 std::vector<uint32_t> all(tlas.Count());
81 1 std::iota(all.begin(), all.end(), 0u);
82 1 return all;
83 1 }
84 783 std::vector<bool> seen(tlas.Count(), false);
85
2/2
✓ Branch 0 taken 910 times.
✓ Branch 1 taken 781 times.
1691 for (const uint32_t world : worlds) {
86
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 909 times.
910 if (world >= tlas.Count()) {
87
1/1
✓ Branch 2 taken 1 time.
1 throw Error("{} of world {} of a TLAS of {} worlds", what, world, tlas.Count());
88 }
89
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 908 times.
909 if (seen[world]) {
90
1/1
✓ Branch 2 taken 1 time.
1 throw Error("{} of world {} twice", what, world);
91 }
92 908 seen[world] = true;
93 }
94
1/1
✓ Branch 1 taken 781 times.
783 return {worlds.begin(), worlds.end()};
95 781 }
96
97 121 void RequireRefittable(const char* what, const device::AccelInput& input) {
98
4/4
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 120 times.
242 if (!device::Refittable(input)) {
99
1/1
✓ Branch 2 taken 1 time.
1 throw Error("{} of a BLAS that wasn't made refittable", what);
100 }
101 120 }
102
103 222 Ref<Buffer> Tables::Upload(Device& device, std::string label) const {
104
1/1
✓ Branch 2 taken 222 times.
444 return device.CreateBuffer({.label = std::move(label)}, std::span<const std::byte>(m_bytes));
105 222 }
106
107 }
108