Toast Engine
Loading...
Searching...
No Matches
voxel_gpu_storage.hpp
Go to the documentation of this file.
1
6
7#pragma once
10
11#include <array>
12#include <cstdint>
13#include <glm/glm.hpp>
14#include <memory>
15#include <optional>
16#include <string>
18#include <vector>
19
20namespace renderer {
21
26
29 struct BrickCensus {
30 uint32_t uniform = 0;
31 uint32_t shared = 0;
32 uint32_t owned = 0;
33 };
34
36 std::vector<std::string> node_names;
37 std::vector<BrickCensus> bricks;
38
39 uint64_t sequence = 0;
40 double pack_ms = 0.0;
41 uint32_t packed_slots = 0;
42 uint32_t packed_palettes = 0;
43
44 bool patched = false;
45 uint32_t patched_bricks = 0;
46
48 std::shared_ptr<const VoxelPackedScene> mirror;
49};
50
52
55public:
57 enum class Section : uint8_t {
58 materials,
59 occupancy,
60 grids,
61 coarse,
62 palettes,
63 records,
64 };
65
66 static constexpr size_t k_section_count = 6;
67
69 VoxelGpuStorage(std::vector<uint64_t> node_rids, std::vector<glm::uvec3> brick_dims);
70
73 std::vector<uint64_t> node_rids, std::vector<glm::uvec3> brick_dims, const VoxelGpuStorage& previous,
74 uint64_t patch_sequence
75 );
76
78 [[nodiscard]]
79 auto generation() const noexcept -> uint64_t {
80 return m_generation;
81 }
82
83 [[nodiscard]]
84 auto recordIndexOf(uint64_t node_rid) const -> std::optional<uint32_t>;
85
86 [[nodiscard]]
87 auto recordBrickDims(uint32_t index) const -> glm::uvec3 {
88 return index < m_brick_dims.size() ? m_brick_dims[index] : glm::uvec3(0);
89 }
90
91 [[nodiscard]]
92 auto recordCount() const noexcept -> uint32_t {
93 return static_cast<uint32_t>(m_node_rids.size());
94 }
95
96 [[nodiscard]]
97 auto buffer(Section section) const -> vk::Buffer;
98
99 [[nodiscard]]
100 auto size(Section section) const -> vk::DeviceSize;
101
103 [[nodiscard]]
104 auto queuePatch(const VulkanCore& core, const voxel::gpu::ScenePatch& patch) const -> std::optional<uint64_t>;
105
107 void recordPendingPatches(vk::CommandBuffer cmd, std::vector<std::shared_ptr<void>>& retired) const;
108
109 [[nodiscard]]
110 auto nodeRid(uint32_t index) const -> uint64_t {
111 return index < m_node_rids.size() ? m_node_rids[index] : 0;
112 }
113
115 void setDebugInfo(VoxelStorageDebugInfo info) { m_debug = std::move(info); }
116
117 [[nodiscard]]
118 auto debugInfo() const -> const VoxelStorageDebugInfo& {
119 return m_debug;
120 }
121
123 void setChangeHistory(VoxelChangeHistory history) { m_history = std::move(history); }
124
125 [[nodiscard]]
126 auto changeHistory() const -> const VoxelChangeHistory& {
127 return m_history;
128 }
129
130private:
131 friend class VoxelSceneUpload;
132
133 std::vector<uint64_t> m_node_rids;
134 std::vector<glm::uvec3> m_brick_dims;
135
136 std::shared_ptr<VoxelGpuSections> m_sections;
137
139 uint64_t m_patch_sequence = 0;
140
141 uint64_t m_generation = 0;
142
143 VoxelStorageDebugInfo m_debug;
144
145 VoxelChangeHistory m_history;
146};
147
149 struct Volume {
150 glm::mat4 world_to_voxel {1.0f};
151 glm::vec3 bounds_center {0.0f};
152 float bounds_radius = 0.0f;
153 uint32_t record_index = 0;
154 };
155
156 std::shared_ptr<const VoxelGpuStorage> storage;
157 std::vector<Volume> volumes;
158};
159
162 glm::mat4 voxel_to_world {1.0f};
163 glm::mat4 world_to_voxel {1.0f};
164 glm::mat4 previous_voxel_to_world {1.0f};
165 uint32_t record_index = 0;
166 uint32_t pad0 = 0;
167 uint32_t flags = 0;
169 uint32_t cell_base = 0;
170};
171
172static_assert(sizeof(VoxelInstanceGpu) == 208, "VoxelInstanceGpu is mirrored by voxel_dda.slang VoxelInstance");
173
175inline constexpr uint32_t k_voxel_instance_no_motion = 1u << 0;
176
178inline constexpr uint32_t k_voxel_instance_mirrored = 1u << 1;
179
181[[nodiscard]]
182auto makeVoxelInstance(
183 const glm::mat4& model, const glm::mat4& inverse_model, const glm::mat4& previous_model, bool has_previous,
184 uint32_t record_index
186
189void writeVoxelStorageDescriptors(const vk::raii::Device& device, vk::DescriptorSet set, const VoxelGpuStorage& storage);
190
191class VoxelSceneUpload : public PendingResourceUpload {
192public:
193 VoxelSceneUpload(std::shared_ptr<VoxelGpuStorage> storage, std::shared_ptr<const VoxelPackedScene> packed);
194
195 void build(const VulkanCore& core) override;
196
197 void record(vk::CommandBuffer cmd) override;
198
199 void recordAcquire(sync::BarrierBatch& batch) override;
200
201 auto resource() -> IVulkanResource* override { return m_storage.get(); }
202
203private:
204 std::shared_ptr<VoxelGpuStorage> m_storage;
205
206 std::shared_ptr<const VoxelPackedScene> m_packed;
207
208 bool m_released = false;
209
210 vma::raii::Buffer m_staging = nullptr;
211 std::array<vk::DeviceSize, VoxelGpuStorage::k_section_count> m_offsets {};
212
213 std::array<vk::DeviceSize, VoxelGpuStorage::k_section_count> m_bytes {};
214};
215
216}
Definition vulkan_resource_base.hpp:12
Definition vulkan_resource_base.hpp:48
Regions each published voxel storage brought oldest first.
Definition voxel_change_history.hpp:30
Section buffers shared by every version patched in place since the last full upload.
Definition voxel_gpu_storage.cpp:88
Immutable scene version and versions from small carves share buffers patched in place.
Definition voxel_gpu_storage.hpp:54
Section
In voxel_dda.slang binding order.
Definition voxel_gpu_storage.hpp:57
void setDebugInfo(VoxelStorageDebugInfo info)
Definition voxel_gpu_storage.hpp:115
auto queuePatch(const VulkanCore &core, const voxel::gpu::ScenePatch &patch) const -> std::optional< uint64_t >
Tick thread on a ready storage and nullopt when the pool outgrew the buffers or staging failed.
Definition voxel_gpu_storage.cpp:218
auto generation() const noexcept -> uint64_t
Unique per storage so a cache keyed on it notices every upload.
Definition voxel_gpu_storage.hpp:79
void recordPendingPatches(vk::CommandBuffer cmd, std::vector< std::shared_ptr< void > > &retired) const
Render thread before anything reads the sections and retired must outlive the frame.
Definition voxel_gpu_storage.cpp:222
void setChangeHistory(VoxelChangeHistory history)
Definition voxel_gpu_storage.hpp:123
VoxelGpuStorage(std::vector< uint64_t > node_rids, std::vector< glm::uvec3 > brick_dims)
New section buffers that a VoxelSceneUpload fills.
Definition voxel_gpu_storage.cpp:201
void recordAcquire(sync::BarrierBatch &batch) override
On the consuming queue after the upload fence signalled. No op for an upload that stayed on one queue...
Definition voxel_gpu_storage.cpp:394
Definition vulkan_core.hpp:48
Skips a barrier only when neither side writes and the layout and next read stages are already covered...
Definition gpu_sync.hpp:105
Definition voxel_gpu_storage.hpp:149
Definition voxel_gpu_storage.hpp:148
Mirrors voxel_dda.slang VoxelInstance.
Definition voxel_gpu_storage.hpp:161
uint32_t cell_base
First global coarse cell of this instance in the VoxelPass cell cull.
Definition voxel_gpu_storage.hpp:169
Definition voxel_gpu_storage.hpp:22
Definition voxel_gpu_storage.hpp:29
Immutable once the storage is published.
Definition voxel_gpu_storage.hpp:28
std::shared_ptr< const VoxelPackedScene > mirror
Only kept while a voxel debug view is active.
Definition voxel_gpu_storage.hpp:48
std::vector< std::string > node_names
Per record.
Definition voxel_gpu_storage.hpp:36
Definition gpu_layout.hpp:62
Definition gpu_layout.hpp:76
constexpr uint32_t k_voxel_instance_mirrored
Bit 1 of VoxelInstanceGpu::flags so voxel.slang flips the box winding.
Definition voxel_gpu_storage.hpp:178
constexpr uint32_t k_voxel_instance_no_motion
Bit 0 of VoxelInstanceGpu::flags with the meaning of VulkanRenderer::k_instance_no_motion.
Definition voxel_gpu_storage.hpp:175