sandbox
Loading...
Searching...
No Matches
descriptor_handler.hpp
1#ifndef LIBSBX_GRAPHICS_DESCRIPTOR_DESCRIPTOR_HANDLER_HPP_
2#define LIBSBX_GRAPHICS_DESCRIPTOR_DESCRIPTOR_HANDLER_HPP_
3
4#include <memory>
5#include <map>
6#include <vector>
7#include <optional>
8
9#include <libsbx/memory/observer_ptr.hpp>
10
11#include <libsbx/graphics/buffers/uniform_handler.hpp>
12#include <libsbx/graphics/buffers/storage_handler.hpp>
13#include <libsbx/graphics/buffers/push_handler.hpp>
14
15#include <libsbx/graphics/pipeline/pipeline.hpp>
16
17#include <libsbx/graphics/descriptor/descriptor.hpp>
18#include <libsbx/graphics/descriptor/descriptor_set.hpp>
19#include <libsbx/graphics/graphics_module.hpp>
20
21namespace sbx::graphics {
22
24
25public:
26
27 descriptor_handler() = default;
28
29 explicit descriptor_handler(const pipeline& pipeline)
30 : _pipeline{&pipeline} {
31 _descriptor_sets.resize(graphics::swapchain::max_frames_in_flight);
32
33 for (auto& descriptor_set : _descriptor_sets) {
34 descriptor_set = std::make_unique<graphics::descriptor_set>(pipeline);
35 }
36 }
37
39 _descriptor_sets.clear();
40 }
41
42 template<typename Descriptor>
43 requires (std::is_base_of_v<descriptor, Descriptor>)
44 auto push(const std::string& name, const Descriptor& descriptor) -> void {
45 if (_pipeline) {
46 _push(name, descriptor);
47 }
48 }
49
50 auto push(const std::string& name, uniform_handler& uniform_handler) -> void {
51 if (_pipeline) {
52 uniform_handler.update(_pipeline->descriptor_block(name));
53 _push(name, uniform_handler.uniform_buffer());
54 }
55 }
56
57 auto push(const std::string& name, storage_handler& storage_handler) -> void {
58 if (_pipeline) {
59 storage_handler.update(_pipeline->descriptor_block(name));
60 _push(name, storage_handler.storage_buffer());
61 }
62 }
63
64 auto push(const std::string& name, push_handler& push_handler) -> void {
65 if (_pipeline) {
66 push_handler.update(_pipeline->descriptor_block(name));
67 }
68 }
69
70 auto bind_descriptors(command_buffer& command_buffer) -> void {
71 auto& graphics_module = core::engine::get_module<graphics::graphics_module>();
72
73 const auto current_frame = graphics_module.current_frame();
74
75 _descriptor_sets[current_frame]->bind(command_buffer);
76 }
77
78 auto update(const pipeline& pipeline) -> bool {
79 if (_pipeline.get() != &pipeline) {
80 _pipeline = &pipeline;
81
82 _descriptors.clear();
83
84 _descriptor_sets.resize(graphics::swapchain::max_frames_in_flight);
85
86 for (auto& descriptor_set : _descriptor_sets) {
87 descriptor_set = std::make_unique<graphics::descriptor_set>(pipeline);
88 }
89
90 return false;
91 }
92
93 auto& graphics_module = core::engine::get_module<graphics::graphics_module>();
94
95 const auto current_frame = graphics_module.current_frame();
96
97 auto& descriptor_set = _descriptor_sets[current_frame];
98
99 auto write_descriptor_sets = std::vector<VkWriteDescriptorSet>{};
100 write_descriptor_sets.reserve(_descriptors.size());
101
102 for (const auto& [name, descriptor] : _descriptors) {
103 auto write_descriptor_set = descriptor.write_descriptor_set.handle();
105
106 write_descriptor_sets.push_back(write_descriptor_set);
107 }
108
109 descriptor_set->update(write_descriptor_sets);
110
111 _descriptors.clear();
112
113 return true;
114 }
115
116private:
117
118 struct descriptor_entry {
121 std::uint32_t binding;
122 }; // struct descriptor_entry
123
124 template<typename Descriptor>
125 requires (std::is_base_of_v<descriptor, Descriptor>)
126 auto _push(const std::string& name, const Descriptor& descriptor) -> void {
127 auto binding = _pipeline->find_descriptor_binding(name);
128
129 if (!binding) {
130 throw std::runtime_error(fmt::format("Failed to find descriptor binding for descriptor '{}'", name));
131 }
132
133 auto descriptor_type = _pipeline->find_descriptor_type_at_binding(*binding);
134
135 if (!descriptor_type) {
136 throw std::runtime_error(fmt::format("Failed to find descriptor type for descriptor '{}'", name));
137 }
138
139 auto write_descriptor_set = descriptor.write_descriptor_set(*binding, *descriptor_type);
140
141 _descriptors.insert({name, descriptor_entry{std::addressof(descriptor), std::move(write_descriptor_set), *binding}});
142 }
143
145
146 std::vector<std::unique_ptr<descriptor_set>> _descriptor_sets{};
147
148 std::map<std::string, descriptor_entry> _descriptors{};
149
150}; // class descriptor_handler
151
152} // namespace sbx::graphics
153
154#endif // LIBSBX_GRAPHICS_DESCRIPTOR_DESCRIPTOR_HANDLER_HPP_
Definition: command_buffer.hpp:14
Definition: descriptor_handler.hpp:23
Definition: descriptor_set.hpp:12
Definition: descriptor.hpp:33
Module for managing rendering specific tasks.
Definition: graphics_module.hpp:59
Definition: pipeline.hpp:18
Definition: push_handler.hpp:16
Definition: storage_handler.hpp:18
Definition: uniform_handler.hpp:17
Definition: descriptor.hpp:12
A non-owning pointer that can be used to observe the value of a pointer.
Definition: observer_ptr.hpp:27