2#ifndef LIBSBX_GRAPHICS_RENDERER_HPP_
3#define LIBSBX_GRAPHICS_RENDERER_HPP_
9#include <easy/profiler.h>
11#include <libsbx/utility/noncopyable.hpp>
12#include <libsbx/utility/concepts.hpp>
14#include <libsbx/utility/type_id.hpp>
15#include <libsbx/utility/type_name.hpp>
17#include <libsbx/graphics/commands/command_buffer.hpp>
19#include <libsbx/graphics/pipeline/pipeline.hpp>
21#include <libsbx/graphics/task.hpp>
22#include <libsbx/graphics/subrenderer.hpp>
23#include <libsbx/graphics/render_graph.hpp>
24#include <libsbx/graphics/draw_list.hpp>
25#include <libsbx/graphics/viewport.hpp>
27namespace sbx::graphics {
40template<
typename Type>
52 for (
auto& [key,
draw_list] : _draw_lists) {
58 if (pass.index >= _tasks.size()) {
62 for (
const auto&
task : _tasks[pass.index]) {
68 if (pass.index >= _subrenderers.size()) {
72 for (
const auto&
subrenderer : _subrenderers[pass.index]) {
80 auto resize(
const std::string& viewport_name) ->
void {
81 _graph.resize(viewport_name);
85 return _graph.find_attachment(name);
88 template<
typename Type>
89 requires (std::is_base_of_v<graphics::draw_list, Type>)
93 if (
auto entry = _draw_lists.find(name); entry != _draw_lists.end()) {
94 return *
static_cast<Type*
>(entry->second.get());
100 template<
typename Type>
101 requires (std::is_base_of_v<graphics::task, Type>)
105 if (
auto entry = _task_by_id.find(type); entry != _task_by_id.end()) {
106 auto [pass, index] = entry->second;
114 template<
typename Type>
115 requires (std::is_base_of_v<graphics::task, Type>)
119 if (
auto entry = _task_by_id.find(type); entry != _task_by_id.end()) {
120 auto [pass, index] = entry->second;
130 template<
typename Type,
typename... Args>
131 requires (std::is_base_of_v<graphics::subrenderer, Type> && std::is_constructible_v<Type, const std::vector<sbx::graphics::attachment_description>&, Args...>)
132 auto add_subrenderer(
const pass_handle handle, Args&&... args) -> Type& {
133 utility::assert_that(handle.is_valid(),
"Invalid pass handle in add_subrenderer()");
135 if (_graph.pass_kind(handle) != pass_node::kind::graphics) {
139 _subrenderers.resize(std::max(_subrenderers.size(),
static_cast<std::size_t
>(handle.index + 1)));
141 auto& subrenderers = _subrenderers[handle.index];
143 subrenderers.emplace_back(std::make_unique<Type>(_graph.attachment_descriptions(handle), std::forward<Args>(args)...));
145 return *
static_cast<Type*
>(subrenderers.back().get());
148 template<
typename Type,
typename... Args>
149 requires (std::is_base_of_v<graphics::task, Type> && std::is_constructible_v<Type, Args...>)
150 auto add_task(
const pass_handle handle, Args&&... args) -> Type& {
151 utility::assert_that(handle.is_valid(),
"Invalid pass handle in add_compute_task()");
155 if (_graph.pass_kind(handle) != pass_node::kind::compute) {
159 _tasks.resize(std::max(_tasks.size(),
static_cast<std::size_t
>(handle.index + 1)));
161 auto& tasks = _tasks[handle.index];
163 _task_by_id.emplace(type, std::make_pair(handle.index, tasks.size()));
165 tasks.emplace_back(std::make_unique<Type>(std::forward<Args>(args)...));
167 return *
static_cast<Type*
>(tasks.back().get());
170 template<
typename Type,
typename... Args>
171 requires (std::is_constructible_v<Type, Args...>)
172 auto add_draw_list(Args&&... args) -> Type& {
175 auto result = _draw_lists.emplace(name, std::make_unique<Type>(std::forward<Args>(args)...));
177 return *
static_cast<Type*
>(result.first->second.get());
180 template<
typename... Args>
182 return _graph.create_attachment(std::forward<Args>(args)...);
185 template<
typename Callable>
186 auto create_pass(Callable&& callable) ->
pass_handle {
187 return _graph.create_pass(std::forward<Callable>(callable));
190 auto build_render_graph() ->
void {
194 auto attachment_descriptions(
const pass_handle handle)
const -> std::vector<attachment_description> {
195 return _graph.attachment_descriptions(handle);
200 std::vector<std::vector<std::unique_ptr<graphics::subrenderer>>> _subrenderers;
202 std::vector<std::vector<std::unique_ptr<graphics::task>>> _tasks;
203 std::unordered_map<std::uint32_t, std::pair<std::uint32_t, std::size_t>> _task_by_id;
205 std::unordered_map<utility::hashed_string, std::unique_ptr<graphics::draw_list>> _draw_lists;
Definition: render_graph.hpp:93
Definition: command_buffer.hpp:15
Definition: descriptor.hpp:38
Definition: draw_list.hpp:28
Definition: render_graph.hpp:240
Definition: renderer.hpp:43
Definition: subrenderer.hpp:14
Definition: swapchain.hpp:15
A non-owning pointer that can be used to observe the value of a pointer.
Definition: observer_ptr.hpp:29
Definition: hashed_string.hpp:17
Definition: render_graph.hpp:142
Definition: renderer.hpp:31
Definition: render_graph.hpp:152
Definition: noncopyable.hpp:7
Definition: exception.hpp:18
A scoped type ID generator. Allows for generating unique IDs for types within a specific scope.
Definition: type_id.hpp:31
static auto value() noexcept -> std::uint32_t
Generates a unique ID for the type.
Definition: type_id.hpp:41