chrono_batch_render/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
35 / 36
97.2%
Branches:
15 / 20
75.0%
Functions:
5 / 5
100.0%

stage/columns/device_heap.cpp
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 #include "chrono_batch_render/stage/columns/device_heap.h"
3
4 #include <algorithm>
5 #include <utility>
6
7 #include <fmt/format.h>
8
9 #include "chrono_batch_render/device/kernels/shared.h"
10
11 namespace chrono::batch_render {
12
13 namespace {
14
15 constexpr uint64_t kFirstChunk = uint64_t(1) << 20;
16 constexpr uint64_t kLargestChunk = uint64_t(64) << 20;
17
18 }
19
20 523 DeviceHeap::DeviceHeap(device::Device& device, std::string label)
21 523 : m_device(device), m_label(std::move(label)), m_nextChunk(kFirstChunk) {}
22
23 1 uint64_t DeviceHeap::Bytes() const {
24 1 uint64_t bytes = 0;
25
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 for (const Chunk& chunk : m_chunks) {
26 ✗ bytes += chunk.buffer->Bytes();
27 }
28 1 return bytes;
29 }
30
31 38030 HeapBlock DeviceHeap::Allocate(uint64_t bytes, uint64_t alignment) {
32
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 38029 times.
38030 if (bytes == 0) {
33 1 return {};
34 }
35 38029 bytes = RoundUp(bytes, alignment);
36 38029 std::vector<HeapBlock>& free = m_free[bytes];
37 38029 const auto aligned = std::ranges::find_if(
38
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 143 times.
144 free, [&](const HeapBlock& block) { return block.offset % alignment == 0; });
39
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 37886 times.
38029 if (aligned != free.end()) {
40 143 const HeapBlock block = *aligned;
41 143 free.erase(aligned);
42 143 return block;
43 }
44 75250 const auto fits = [&](const Chunk& chunk) {
45 37364 return RoundUp(chunk.used, alignment) + bytes <= chunk.buffer->Bytes();
46 37886 };
47
4/4
✓ Branch 0 taken 37364 times.
✓ Branch 1 taken 522 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 37362 times.
37886 if (m_chunks.empty() || !fits(m_chunks.back())) {
48
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 524 times.
524 const uint64_t chunkBytes = std::max(m_nextChunk, bytes);
49
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 524 times.
524 m_nextChunk = std::min(m_nextChunk * 2, kLargestChunk);
50
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 524 times.
524 m_chunks.push_back(
51 524 {m_device.CreateBuffer(
52 {.bytes = chunkBytes,
53 .usage = device::BufferUsage::Interop | device::BufferUsage::AccelBuildInput,
54 1048 .label = fmt::format("{} chunk {}", m_label, m_chunks.size())}),
55 0});
56 }
57 37886 Chunk& chunk = m_chunks.back();
58 37886 const uint64_t offset = RoundUp(chunk.used, alignment);
59 37886 chunk.used = offset + bytes;
60 37886 return {chunk.buffer.Get(), offset, bytes};
61 1048 }
62
63 345 void DeviceHeap::Free(const HeapBlock& block) {
64
1/2
✓ Branch 0 taken 345 times.
✗ Branch 1 not taken.
345 if (block) {
65 345 m_free[block.bytes].push_back(block);
66 }
67 345 }
68
69 }
70