Toast Engine
Loading...
Searching...
No Matches
cluster_lighting_pass.hpp
Go to the documentation of this file.
1
4
5#pragma once
8#include "../shader_layout.hpp"
9#include "../vulkan_common.hpp"
10#include "../vulkan_pipeline.hpp"
11
12#include <atomic>
13#include <glm/glm.hpp>
14#include <span>
15#include <vector>
16
17namespace renderer {
18class VulkanCore;
19
20class ClusterLightingPass : public IComputePass {
21public:
22 struct GridStats {
23 uint32_t occupied = 0;
24 float mean = 0.0f;
25 uint32_t p95 = 0;
26 uint32_t max_count = 0;
27 uint32_t overflowed = 0;
28 uint32_t dropped = 0;
29 };
30
31 explicit ClusterLightingPass(const renderer::VulkanCore& core);
32
33 void update(uint32_t frame_index, float dt) override;
34
35 void dispatch(vk::CommandBuffer cmd, uint32_t frame_index) override;
36
37 [[nodiscard]]
38 auto getClusterParamsBuffer(uint32_t frame_index) const -> vk::Buffer;
39
40 [[nodiscard]]
41 auto getLightsBuffer(uint32_t frame_index) const -> vk::Buffer;
42
43 [[nodiscard]]
44 auto getClusterLightGridBuffer(uint32_t frame_index) const -> vk::Buffer;
45
46 [[nodiscard]]
47 auto getLightIndexListBuffer(uint32_t frame_index) const -> vk::Buffer;
48
50 void requestGridReadback() const noexcept;
51
53 [[nodiscard]]
54 auto getClusterLightGridCounts(uint32_t frame_index) const -> std::span<const uint32_t>;
55
56 [[nodiscard]]
57 static auto summarizeGrid(std::span<const uint32_t> counts) -> GridStats;
58
59private:
61 struct ClusterParamsGpu {
62 glm::mat4 inverse_projection;
63 glm::uvec4 cluster_dims; // xyz dims w max lights per cluster
64 glm::vec4 screen_size_near_far; // xy screen size z camera near w camera far
65 glm::vec4 slice_depth; // x log range start y log range end z slices per log unit
66 glm::uvec4 light_counts; // x light count
67 };
68
69 static_assert(sizeof(ClusterParamsGpu) == 128, "ClusterParamsGpu must match the ClusterParams layout in the shaders");
70
71 enum class HostAccess : uint8_t {
72 none,
73 write,
74 read,
75 };
76
78 struct ClusterAabbGpu {
79 glm::vec4 min_point;
80 glm::vec4 max_point;
81 };
82
83 struct FrameBuffers {
84 FrameResources cluster_params;
85 FrameResources lights;
86 FrameResources cluster_aabb;
87 FrameResources cluster_light_grid;
88 FrameResources light_index_list;
89
90 FrameResources cluster_light_grid_readback;
91 bool readback_valid = false;
92 };
93
94 void createResources(const renderer::VulkanCore& core);
95
96 [[nodiscard]]
97 static auto createBuffer(const renderer::VulkanCore& core, vk::DeviceSize size, vk::BufferUsageFlags usage, HostAccess access)
98 -> vma::raii::Buffer;
99
100 VulkanPipeline m_build_clusters_pipeline;
101 VulkanPipeline m_cull_lights_pipeline;
102
103 ShaderLayout m_shader_layout;
104 std::vector<vk::raii::DescriptorSet> m_descriptor_sets;
105
106 std::vector<FrameBuffers> m_frame_buffers;
107
108 mutable std::atomic<uint32_t> m_readback_hold {0};
109};
110
111}
Definition compute_pass_base.hpp:9
auto getClusterLightGridCounts(uint32_t frame_index) const -> std::span< const uint32_t >
Unclamped counts and empty until a copy for this frame slot has landed.
Definition cluster_lighting_pass.cpp:285
void requestGridReadback() const noexcept
The grid is only copied back for a few frames after each call.
Definition cluster_lighting_pass.cpp:280
Definition vulkan_core.hpp:48
Definition cluster_lighting_pass.hpp:22