sandbox
Loading...
Searching...
No Matches
graphics_module.hpp
1#ifndef LIBSBX_GRAPHICS_GRAPHICS_MODULE_HPP_
2#define LIBSBX_GRAPHICS_GRAPHICS_MODULE_HPP_
3
4#include <memory>
5#include <unordered_map>
6#include <vector>
7#include <typeindex>
8
9#include <libsbx/core/module.hpp>
11
12#include <libsbx/math/uuid.hpp>
13
14#include <libsbx/devices/devices_module.hpp>
15
17#include <libsbx/utility/concepts.hpp>
18
19#include <libsbx/graphics/devices/instance.hpp>
20#include <libsbx/graphics/devices/physical_device.hpp>
21#include <libsbx/graphics/devices/logical_device.hpp>
22#include <libsbx/graphics/devices/surface.hpp>
23
24#include <libsbx/graphics/commands/command_pool.hpp>
25#include <libsbx/graphics/commands/command_buffer.hpp>
26
27#include <libsbx/graphics/render_pass/swapchain.hpp>
28#include <libsbx/graphics/render_pass/fence.hpp>
29#include <libsbx/graphics/render_pass/semaphore.hpp>
30
31#include <libsbx/graphics/pipeline/pipeline.hpp>
32#include <libsbx/graphics/pipeline/shader.hpp>
33
34#include <libsbx/graphics/buffers/buffer.hpp>
35
36#include <libsbx/graphics/renderer.hpp>
37#include <libsbx/graphics/render_stage.hpp>
38
39namespace sbx::graphics {
40
46auto validate(VkResult result) -> void;
47
48template<typename VkEnum, typename Enum>
49requires ((std::is_enum_v<VkEnum> || std::is_same_v<VkEnum, VkFlags>) && std::is_enum_v<Enum>)
50constexpr auto to_vk_enum(Enum value) -> VkEnum {
51 return static_cast<VkEnum>(value);
52}
53
59class graphics_module final : public core::module<graphics_module> {
60
61 inline static const auto is_registered = register_module(stage::rendering, dependencies<devices::devices_module>{});
62
63 inline static constexpr auto max_deletion_queue_size = std::size_t{16u};
64
65public:
66
68
69 ~graphics_module() override;
70
71 auto update() -> void override;
72
73 auto instance() -> instance&;
74
76
78
79 auto surface() -> surface&;
80
81 auto command_pool(VkQueueFlagBits queue_type = VK_QUEUE_GRAPHICS_BIT, const std::thread::id& thread_id = std::this_thread::get_id()) -> const std::shared_ptr<command_pool>&;
82
83 auto swapchain() -> swapchain&;
84
85 template<utility::implements<renderer> Renderer, typename... Args>
86 requires (std::is_constructible_v<Renderer, Args...>)
87 auto set_renderer(Args&&... args) -> void {
88 _renderer = std::make_unique<Renderer>(std::forward<Args>(args)...);
89 _reset_render_stages();
90 _renderer->initialize();
91 }
92
94
95 auto current_frame() const noexcept -> std::uint32_t {
96 return _current_frame;
97 }
98
99 auto attachment(const std::string& name) const -> const descriptor&;
100
101 template<typename Type, typename... Args>
102 auto add_asset(Args&&... args) -> math::uuid {
103 const auto id = math::uuid{};
104 const auto type = std::type_index{typeid(Type)};
105
106 auto container = _asset_containers.find(type);
107
108 if (container == _asset_containers.end()) {
109 container = _asset_containers.insert({type, std::make_unique<asset_container<Type>>()}).first;
110 }
111
112 static_cast<asset_container<Type>*>(container->second.get())->add(id, std::forward<Args>(args)...);
113
114 return id;
115 }
116
117 template<typename Type>
118 auto add_asset(std::unique_ptr<Type>&& asset) -> math::uuid {
119 const auto id = math::uuid{};
120 const auto type = std::type_index{typeid(Type)};
121
122 auto container = _asset_containers.find(type);
123
124 if (container == _asset_containers.end()) {
125 container = _asset_containers.insert({type, std::make_unique<asset_container<Type>>()}).first;
126 }
127
128 static_cast<asset_container<Type>*>(container->second.get())->add(id, std::move(asset));
129
130 return id;
131 }
132
133 template<typename Type>
134 auto get_asset(const math::uuid& id) const -> const Type& {
135 const auto type = std::type_index{typeid(Type)};
136
137 auto container = _asset_containers.find(type);
138
139 if (container == _asset_containers.end()) {
140 throw std::runtime_error{"Asset does not exist"};
141 }
142
143 return static_cast<const asset_container<Type>*>(container->second.get())->get(id);
144 }
145
146 template<typename Type>
147 auto get_asset(const math::uuid& id) -> Type& {
148 const auto type = std::type_index{typeid(Type)};
149
150 auto container = _asset_containers.find(type);
151
152 if (container == _asset_containers.end()) {
153 throw std::runtime_error{"Asset does not exist"};
154 }
155
156 return static_cast<asset_container<Type>*>(container->second.get())->get(id);
157 }
158
159private:
160
161 auto _start_render_pass(graphics::render_stage& render_stage) -> void;
162
163 auto _end_render_pass(graphics::render_stage& render_stage) -> void;
164
165 auto _reset_render_stages() -> void;
166
167 auto _recreate_swapchain() -> void;
168
169 auto _recreate_per_frame_data() -> void;
170
171 auto _recreate_command_buffers() -> void;
172
173 auto _recreate_attachments() -> void;
174
175 struct per_frame_data {
176 // graphics
177 VkSemaphore image_available_semaphore{};
178 VkSemaphore render_finished_semaphore{};
179 VkFence graphics_in_flight_fence{};
180 // compute
181 VkSemaphore compute_finished_semaphore{};
182 VkFence compute_in_flight_fence{};
183 }; // struct per_frame_data
184
185 struct command_pool_key {
186 VkQueueFlagBits queue_type;
187 std::thread::id thread_id;
188 }; // struct command_pool_key
189
190 struct command_pool_key_hash {
191 auto operator()(const command_pool_key& key) const noexcept -> std::size_t {
192 auto hast = std::size_t{0};
193 utility::hash_combine(hast, key.queue_type, key.thread_id);
194 return hast;
195 }
196 }; // struct command_pool_key_hash
197
198 struct command_pool_key_equality {
199 auto operator()(const command_pool_key& lhs, const command_pool_key& rhs) const noexcept -> bool {
200 return lhs.queue_type == rhs.queue_type && lhs.thread_id == rhs.thread_id;
201 }
202 }; // struct command_pool_key_equal
203
204 std::unique_ptr<graphics::instance> _instance{};
205 std::unique_ptr<graphics::physical_device> _physical_device{};
206 std::unique_ptr<graphics::logical_device> _logical_device{};
207
208 std::unordered_map<command_pool_key, std::shared_ptr<graphics::command_pool>, command_pool_key_hash, command_pool_key_equality> _command_pools{};
209
210 std::map<std::string, memory::observer_ptr<const descriptor>> _attachments{};
211
212 std::unique_ptr<graphics::surface> _surface{};
213
214 std::unique_ptr<graphics::swapchain> _swapchain{};
215
216 std::vector<per_frame_data> _per_frame_data{};
217 std::vector<std::unique_ptr<graphics::command_buffer>> _graphics_command_buffers{};
218 std::vector<std::unique_ptr<graphics::command_buffer>> _compute_command_buffers{};
219
220 std::unique_ptr<graphics::renderer> _renderer{};
221
222 struct asset_container_base {
223 virtual ~asset_container_base() = default;
224 virtual auto remove(const math::uuid& id) -> void = 0;
225 virtual auto clear() -> void = 0;
226 };
227
228 template<typename Type>
229 class asset_container : public asset_container_base {
230
231 public:
232
233 asset_container() {
234
235 }
236
237 ~asset_container() override {
238
239 }
240
241 auto remove(const math::uuid& id) -> void override {
242 _assets.erase(id);
243 }
244
245 auto clear() -> void override {
246 _assets.clear();
247 }
248
249 template<typename... Args>
250 auto add(const math::uuid& id, Args&&... args) -> void {
251 _assets.insert({id, std::make_unique<Type>(std::forward<Args>(args)...)});
252 }
253
254 auto add(const math::uuid& id, std::unique_ptr<Type>&& asset) -> void {
255 _assets.insert({id, std::move(asset)});
256 }
257
258 auto get(const math::uuid& id) const -> const Type& {
259 return *_assets.at(id);
260 }
261
262 auto get(const math::uuid& id) -> Type& {
263 return *_assets.at(id);
264 }
265
266 private:
267
268 std::unordered_map<math::uuid, std::unique_ptr<Type>> _assets;
269
270 };
271
272 std::unordered_map<std::type_index, std::unique_ptr<asset_container_base>> _asset_containers;
273
274 std::uint32_t _current_frame{};
275 bool _is_framebuffer_resized{};
276
277}; // class graphics_module
278
279} // namespace sbx::graphics
280
281#endif // LIBSBX_GRAPHICS_GRAPHICS_MODULE_HPP_
Definition: module.hpp:72
Definition: render_stage.hpp:38
Definition: command_pool.hpp:12
Definition: descriptor.hpp:33
Module for managing rendering specific tasks.
Definition: graphics_module.hpp:59
Definition: instance.hpp:10
Definition: logical_device.hpp:55
Definition: physical_device.hpp:16
Definition: render_stage.hpp:216
Definition: surface.hpp:14
Definition: swapchain.hpp:12
Definition: uuid.hpp:16
Definition: pipeline.hpp:22