GCC Code Coverage Report


ernie/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
12 / 13
92.3%
Branches:
6 / 16
37.5%
Functions:
-
-%

render/rt/bottom_levels.h
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 /// @file bottom_levels.h
3 /// @brief A bottom-level acceleration structure for each geometry, built on the device as the
4 /// geometry changes: static geometry traced fast and compacted, deforming geometry refitted.
5 #pragma once
6
7 #include "ernie/device/acceleration.h"
8 #include "ernie/device/column.h"
9 #include "ernie/device/staging.h"
10 #include "ernie/graph/graph.h"
11 #include "ernie/render/geometry.h"
12
13 #include <cstdint>
14 #include <memory>
15 #include <vector>
16
17 namespace ernie {
18
19 /// @brief The bottom levels of a geometry pool. Builds wait for the frame's graph, batched in one
20 /// call under a scratch budget; geometry whose bottom level is not built yet has address 0, which
21 /// a top level takes as an instance switched off.
22 ///
23 /// Static geometry is built to trace fast and compacted a few frames later, once its compacted
24 /// size has come back without a wait. Geometry refitted switches to a refittable build, and is
25 /// built anew after `kRefitsBeforeRebuild` refits, as refits loosen the tree.
26 class BottomLevels {
27 public:
28 static constexpr std::uint32_t kRefitsBeforeRebuild = 16;
29
30 /// @param arenas Where the address column lives.
31 /// @param scratchBudget The most scratch one frame's builds take; one build always goes.
32 BottomLevels(DeviceContext& context, Arenas& arenas, const GeometryPool& geometry,
33 std::uint64_t scratchBudget = std::uint64_t{64} << 20);
34 BottomLevels(const BottomLevels&) = delete;
35 BottomLevels& operator=(const BottomLevels&) = delete;
36
37 /// @brief Takes in what a geometry update changed: builds and refits to run, levels to free.
38 void Apply(const GeometryPool::Changes& changes);
39 /// @brief Adds the passes that compact finished levels, run this frame's builds and upload
40 /// the addresses, after the geometry's uploads and before the top levels' builds.
41 void AddBuilds(graph::Graph& graph);
42
43 /// @return Each geometry's bottom level address, a uint64 a geometry id; 0 until built.
44 22 const DeviceColumn& Addresses() const {
45 22 return *addresses_;
46 }
47 /// @return The pool the levels live in, which top-level builds import to read.
48 27 const AccelerationPool& Pool() const {
49 27 return pool_;
50 }
51 /// @return Builds and refits not run yet, as over the budget.
52 1 std::size_t Pending() const {
53
1/2
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
1 return pending_.size();
54 }
55 /// @brief What the levels have cost so far, for memory and profiler reports.
56 15 struct Statistics {
57 std::uint32_t built = 0;
58 std::uint32_t refitted = 0;
59 std::uint32_t compacted = 0;
60 /// Bytes compaction gave back.
61 std::uint64_t saved = 0;
62 };
63 const Statistics& Totals() const {
64 2 return totals_;
65 }
66
67 private:
68
5/14
<unknown function 52>:
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 1 time.
<unknown function 56>:
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
<unknown function 64>:
✗ Branch 0 not taken.
✗ Branch 1 not taken.
<unknown function 68>:
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
80 struct Level {
69 std::shared_ptr<AccelerationStructure> structure;
70 bool deforming = false;
71 std::uint32_t refits = 0;
72 /// Whether its compacted size is being read back.
73 bool compacting = false;
74 };
75 struct Work {
76 GeometryId geometry = 0;
77 bool refit = false;
78 };
79 /// Compacted sizes on their way back, for the levels built with them.
80 struct Compaction {
81 std::unique_ptr<CompactionQuery> query;
82 std::vector<GeometryId> geometries;
83 std::vector<std::shared_ptr<AccelerationStructure>> structures;
84 };
85
86 /// Levels moving into compacted copies: each source, then its copy.
87 using Moves = std::vector<
88 std::pair<std::shared_ptr<AccelerationStructure>, std::shared_ptr<AccelerationStructure>>>;
89 /// A frame's builds and refits, and the geometry they read.
90 struct FrameBuilds {
91 std::vector<TriangleGeometry> triangles;
92 std::vector<BoxGeometry> boxes;
93 std::vector<BottomBuild> builds;
94 std::vector<GeometryId> built;
95 std::uint64_t scratch = 0;
96 };
97
98 Level& At(GeometryId geometry);
99 void Queue(GeometryId geometry, bool refit);
100 void SetAddress(GeometryId geometry, std::uint64_t address);
101 /// @return The triangles or box a geometry's level is built over.
102 BottomBuild Build(GeometryId geometry, bool refit, std::vector<TriangleGeometry>& triangles,
103 std::vector<BoxGeometry>& boxes) const;
104 /// @return The moves of levels whose compacted sizes have come back.
105 Moves TakeCompactedSizes();
106 /// @return The pending builds that fit the scratch budget; the rest wait for a later frame.
107 FrameBuilds PlanBuilds();
108 /// @return The query reading back the compacted sizes of the static levels just built.
109 Compaction StartCompactionQuery(const std::vector<GeometryId>& built);
110 void AddAddressUpload(graph::Graph& graph);
111 void AddBuildPass(graph::Graph& graph, FrameBuilds builds, Moves moves,
112 const Compaction& compaction);
113
114 DeviceContext& context_;
115 const GeometryPool& geometry_;
116 std::uint64_t scratchBudget_;
117 AccelerationPool pool_;
118 Uploader uploader_;
119 std::vector<Level> levels_;
120 std::vector<Work> pending_;
121 std::vector<Compaction> compactions_;
122 std::vector<std::uint64_t> hostAddresses_;
123 std::vector<std::uint32_t> dirtyAddresses_;
124 std::unique_ptr<DeviceColumn> addresses_;
125 Statistics totals_;
126 };
127
128 } // namespace ernie
129