30 VoxelPass(
const VulkanCore& core, vk::Format scene_format, vk::Format depth_format, vk::Extent2D extent);
33 auto stage()
const -> RenderStage
override {
34 return RenderStage::voxel_gbuffer;
39 auto prepare(uint32_t frame_index) -> bool;
42 void recordCellCull(vk::CommandBuffer cmd, uint32_t frame_index, vk::Extent2D scene_extent);
45 void record(vk::CommandBuffer cmd, uint32_t frame_index, uint32_t image_index)
override;
50 return m_occlusion_active;
54 void recordOcclusion(vk::CommandBuffer cmd, uint32_t frame_index, vk::Extent2D scene_extent);
57 void recordLate(vk::CommandBuffer cmd, uint32_t frame_index);
62 return m_near_voxels > 0.0f && !m_mesh_shading;
66 void recordQuadDepth(vk::CommandBuffer cmd, uint32_t frame_index,
bool late);
69 void recordLighting(vk::CommandBuffer cmd, uint32_t frame_index, vk::Extent2D viewport);
75 auto name() const -> std::string_view
override {
79 static constexpr uint32_t k_max_instances = 4096;
83 std::chrono::steady_clock::time_point m_last_limit_warning;
86 struct PushConstants {
87 uint32_t instance_index = 0;
90 uint32_t quad_capacity = 0;
94 static constexpr uint32_t k_draw_volume = 0;
95 static constexpr uint32_t k_draw_cells = 1;
99 glm::mat4 view_projection {1.0f};
100 glm::vec4 camera_near {0.0f};
101 uint32_t total_cells = 0;
102 uint32_t instance_count = 0;
104 uint32_t quad_capacity = 0;
105 float near_voxels = 0.0f;
106 uint32_t hiz_levels = 0;
107 uint32_t hiz_width = 0;
108 uint32_t hiz_height = 0;
113 glm::mat4 view_projection {1.0f};
117 static constexpr uint32_t k_cell_bucket_count = 17;
118 static constexpr uint32_t k_late_list = k_cell_bucket_count;
119 static constexpr uint32_t k_cell_draw_count = k_cell_bucket_count + 1;
120 static constexpr uint32_t k_near_list = k_cell_draw_count;
121 static constexpr uint32_t k_near_band_count = 4;
122 static constexpr uint32_t k_retest_list = k_near_list + k_near_band_count;
123 static constexpr uint32_t k_late_near_list = k_retest_list + 1;
124 static constexpr uint32_t k_cell_list_count = k_late_near_list + 1;
125 static constexpr uint32_t k_cell_offsets_word = k_cell_draw_count * 4;
126 static constexpr uint32_t k_cell_cursors_word = k_cell_offsets_word + k_cell_list_count;
127 static constexpr uint32_t k_near_dispatch_word = k_cell_cursors_word + k_cell_list_count;
128 static constexpr uint32_t k_retest_dispatch_word = k_near_dispatch_word + 3;
129 static constexpr uint32_t k_late_mesh_dispatch_word = k_retest_dispatch_word + 3;
130 static constexpr uint32_t k_quad_draw_word = k_late_mesh_dispatch_word + 3;
131 static constexpr uint32_t k_late_quad_draw_word = k_quad_draw_word + 4;
132 static constexpr uint32_t k_near_task_word = k_late_quad_draw_word + 4;
133 static constexpr uint32_t k_late_task_word = k_near_task_word + 3;
134 static constexpr uint32_t k_occlusion_stats_word = k_late_task_word + 3;
135 static constexpr uint32_t k_cell_args_words = k_occlusion_stats_word + 2;
136 static constexpr uint32_t k_min_quad_capacity = 65536;
138 static constexpr uint32_t k_max_coarse_dim = 1024;
139 static constexpr uint32_t k_min_cell_capacity = 4096;
144 std::optional<vma::raii::Buffer> cells;
146 std::optional<vma::raii::Buffer> classes;
148 std::optional<vma::raii::Buffer> args;
149 uint32_t capacity = 0;
151 std::optional<vma::raii::Buffer> quads;
152 uint32_t quad_capacity = 0;
154 std::optional<vma::raii::Buffer> readback;
156 bool measured =
false;
158 std::optional<vma::raii::Buffer> hiz_view;
162 struct LightingPushConstants {
163 glm::mat4 inverse_view_projection {1.0f};
164 glm::vec4 camera_radius {0.0f};
165 glm::vec4 viewport {0.0f};
168 void createCells(
const VulkanCore& core);
169 void ensureCellCapacity(uint32_t frame_index, uint32_t cells);
170 void ensureQuadCapacity(uint32_t frame_index, uint32_t quads);
172 void afterCullWrites(vk::CommandBuffer cmd, uint32_t frame_index, sync::BarrierBatch& barriers);
174 void recordNearQuads(vk::CommandBuffer cmd, uint32_t frame_index,
bool late,
bool depth_only);
176 void recordReadback(vk::CommandBuffer cmd, uint32_t frame_index, sync::BarrierBatch& barriers);
178 void updateOcclusionMode(uint32_t retest_cells, uint32_t listed_cells);
179 void writeCellDescriptors(uint32_t frame_index);
181 void writeHizDescriptors();
182 void recordCellDraws(vk::CommandBuffer cmd, uint32_t frame_index);
184 enum class Cull : uint8_t {
189 enum class Depth : uint8_t {
197 uint32_t instance = 0;
198 Cull cull = Cull::back;
199 Depth depth = Depth::conservative;
202 void createInstanceBuffers(
const VulkanCore& core);
203 void createDescriptors(
const VulkanCore& core,
const ShaderReflection& reflection);
204 void createLighting(
const VulkanCore& core, vk::Format scene_format, vk::Extent2D extent);
206 void bindStorage(uint32_t frame_index,
const std::shared_ptr<const VoxelGpuStorage>& storage);
208 const VulkanCore* m_core =
nullptr;
209 ShaderLayout m_shader_layout;
212 std::array<std::array<VulkanPipeline, 2>, 2> m_pipelines;
214 SceneDescriptorSets m_scene_sets;
216 std::vector<vk::raii::DescriptorSet> m_storage_sets;
218 std::vector<vma::raii::Buffer> m_instance_buffers;
220 std::vector<std::shared_ptr<const VoxelGpuStorage>> m_bound_storage;
222 std::vector<Draw> m_draws;
224 ShaderLayout m_cell_layout;
225 VulkanPipeline m_cell_pipeline;
226 VulkanPipeline m_mesh_pipeline;
227 VulkanPipeline m_quad_pipeline;
228 VulkanPipeline m_quad_depth_pipeline;
230 VulkanPipeline m_mesh_quad_pipeline;
231 PFN_vkCmdDrawMeshTasksIndirectEXT m_draw_mesh_tasks_indirect =
nullptr;
233 bool m_mesh_shading =
false;
234 std::vector<vk::raii::DescriptorSet> m_cell_sets;
235 std::vector<CellBuffers> m_cell_buffers;
237 bool m_cells_active =
false;
238 bool m_occlusion_active =
false;
240 enum class OcclusionMode : uint8_t {
245 OcclusionMode m_occlusion_mode = OcclusionMode::engaged;
247 uint32_t m_occlusion_low_frames = 0;
249 uint32_t m_occlusion_idle_frames = 0;
251 uint64_t m_frame_count = 0;
252 uint64_t m_pyramid_frame = 0;
253 uint32_t m_total_cells = 0;
255 CellCullPush m_cull_push;
258 float m_near_voxels = 0.0f;
260 ShaderLayout m_lighting_layout;
261 VulkanPipeline m_lighting_pipeline;
262 SceneDescriptorSets m_lighting_scene_sets;
264 vk::raii::Sampler m_point_sampler =
nullptr;
265 std::vector<vk::raii::DescriptorSet> m_gbuffer_sets;
268 std::vector<std::array<vk::ImageView, 4>> m_bound_gbuffer;