1#ifndef LIBSBX_GRAPHICS_GRAPHICS_MODULE_HPP_
2#define LIBSBX_GRAPHICS_GRAPHICS_MODULE_HPP_
5#include <unordered_map>
9#include <libsbx/core/module.hpp>
12#include <libsbx/math/uuid.hpp>
14#include <libsbx/devices/devices_module.hpp>
17#include <libsbx/utility/concepts.hpp>
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>
24#include <libsbx/graphics/commands/command_pool.hpp>
25#include <libsbx/graphics/commands/command_buffer.hpp>
27#include <libsbx/graphics/render_pass/swapchain.hpp>
28#include <libsbx/graphics/render_pass/fence.hpp>
29#include <libsbx/graphics/render_pass/semaphore.hpp>
31#include <libsbx/graphics/pipeline/pipeline.hpp>
32#include <libsbx/graphics/pipeline/shader.hpp>
34#include <libsbx/graphics/buffers/buffer.hpp>
36#include <libsbx/graphics/renderer.hpp>
37#include <libsbx/graphics/render_stage.hpp>
39namespace sbx::graphics {
46auto validate(VkResult result) -> void;
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);
61 inline static const auto is_registered = register_module(stage::rendering, dependencies<devices::devices_module>{});
63 inline static constexpr auto max_deletion_queue_size = std::size_t{16u};
71 auto update() ->
void override;
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>&;
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();
95 auto current_frame()
const noexcept -> std::uint32_t {
96 return _current_frame;
101 template<
typename Type,
typename... Args>
102 auto add_asset(Args&&... args) ->
math::uuid {
104 const auto type = std::type_index{
typeid(Type)};
106 auto container = _asset_containers.find(type);
108 if (container == _asset_containers.end()) {
109 container = _asset_containers.insert({type, std::make_unique<asset_container<Type>>()}).first;
112 static_cast<asset_container<Type>*
>(container->second.get())->add(
id, std::forward<Args>(args)...);
117 template<
typename Type>
118 auto add_asset(std::unique_ptr<Type>&& asset) ->
math::uuid {
120 const auto type = std::type_index{
typeid(Type)};
122 auto container = _asset_containers.find(type);
124 if (container == _asset_containers.end()) {
125 container = _asset_containers.insert({type, std::make_unique<asset_container<Type>>()}).first;
128 static_cast<asset_container<Type>*
>(container->second.get())->add(
id, std::move(asset));
133 template<
typename Type>
134 auto get_asset(
const math::uuid&
id)
const ->
const Type& {
135 const auto type = std::type_index{
typeid(Type)};
137 auto container = _asset_containers.find(type);
139 if (container == _asset_containers.end()) {
140 throw std::runtime_error{
"Asset does not exist"};
143 return static_cast<const asset_container<Type>*
>(container->second.get())->get(
id);
146 template<
typename Type>
147 auto get_asset(
const math::uuid&
id) -> Type& {
148 const auto type = std::type_index{
typeid(Type)};
150 auto container = _asset_containers.find(type);
152 if (container == _asset_containers.end()) {
153 throw std::runtime_error{
"Asset does not exist"};
156 return static_cast<asset_container<Type>*
>(container->second.get())->get(
id);
165 auto _reset_render_stages() -> void;
167 auto _recreate_swapchain() -> void;
169 auto _recreate_per_frame_data() -> void;
171 auto _recreate_command_buffers() -> void;
173 auto _recreate_attachments() -> void;
175 struct per_frame_data {
177 VkSemaphore image_available_semaphore{};
178 VkSemaphore render_finished_semaphore{};
179 VkFence graphics_in_flight_fence{};
181 VkSemaphore compute_finished_semaphore{};
182 VkFence compute_in_flight_fence{};
185 struct command_pool_key {
186 VkQueueFlagBits queue_type;
187 std::thread::id thread_id;
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);
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;
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{};
208 std::unordered_map<command_pool_key, std::shared_ptr<graphics::command_pool>, command_pool_key_hash, command_pool_key_equality> _command_pools{};
210 std::map<std::string, memory::observer_ptr<const descriptor>> _attachments{};
212 std::unique_ptr<graphics::surface> _surface{};
214 std::unique_ptr<graphics::swapchain> _swapchain{};
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{};
220 std::unique_ptr<graphics::renderer> _renderer{};
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;
228 template<
typename Type>
229 class asset_container :
public asset_container_base {
237 ~asset_container()
override {
241 auto remove(
const math::uuid&
id) ->
void override {
245 auto clear() ->
void override {
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)...)});
254 auto add(
const math::uuid&
id, std::unique_ptr<Type>&& asset) ->
void {
255 _assets.insert({id, std::move(asset)});
258 auto get(
const math::uuid&
id)
const ->
const Type& {
259 return *_assets.at(
id);
263 return *_assets.at(
id);
268 std::unordered_map<math::uuid, std::unique_ptr<Type>> _assets;
272 std::unordered_map<std::type_index, std::unique_ptr<asset_container_base>> _asset_containers;
274 std::uint32_t _current_frame{};
275 bool _is_framebuffer_resized{};
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: pipeline.hpp:22