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>
15#include <libsbx/graphics/commands/command_buffer.hpp>
17#include <libsbx/graphics/pipeline/pipeline.hpp>
19#include <libsbx/graphics/task.hpp>
20#include <libsbx/graphics/subrenderer.hpp>
21#include <libsbx/graphics/render_graph.hpp>
22#include <libsbx/graphics/draw_list.hpp>
23#include <libsbx/graphics/viewport.hpp>
25namespace sbx::graphics {
36 for (
auto& [key,
draw_list] : _draw_lists) {
42 const auto kind = _graph.pass_kind(pass);
44 if (kind == pass_node::kind::compute) {
45 if (pass.index >= _tasks.size()) {
49 for (
const auto&
task : _tasks[pass.index]) {
50 task->execute(command_buffer);
53 if (pass.index >= _subrenderers.size()) {
57 for (
const auto&
subrenderer : _subrenderers[pass.index]) {
58 subrenderer->render(command_buffer);
65 auto resize(
const viewport::type flags) ->
void {
70 return _graph.find_attachment(name);
73 template<
typename Type>
74 requires (std::is_base_of_v<draw_list, Type>)
76 if (
auto entry = _draw_lists.find(name); entry != _draw_lists.end()) {
77 return *
static_cast<Type*
>(entry->second.get());
85 template<
typename Type,
typename... Args>
86 requires (std::is_base_of_v<graphics::subrenderer, Type> && std::is_constructible_v<Type, const std::vector<sbx::graphics::attachment_description>&, Args...>)
87 auto add_subrenderer(
const pass_handle handle, Args&&... args) -> Type& {
88 utility::assert_that(handle.is_valid(),
"Invalid pass handle in add_subrenderer()");
90 if (_graph.pass_kind(handle) != pass_node::kind::graphics) {
94 _subrenderers.resize(std::max(_subrenderers.size(),
static_cast<std::size_t
>(handle.index + 1)));
96 auto& subrenderers = _subrenderers[handle.index];
98 subrenderers.emplace_back(std::make_unique<Type>(_graph.attachment_descriptions(handle), std::forward<Args>(args)...));
100 return *
static_cast<Type*
>(subrenderers.back().get());
103 template<
typename Type,
typename... Args>
104 requires (std::is_base_of_v<graphics::task, Type> && std::is_constructible_v<Type, Args...>)
105 auto add_task(
const pass_handle handle, Args&&... args) -> Type& {
106 utility::assert_that(handle.is_valid(),
"Invalid pass handle in add_compute_task()");
108 if (_graph.pass_kind(handle) != pass_node::kind::compute) {
112 _tasks.resize(std::max(_tasks.size(),
static_cast<std::size_t
>(handle.index + 1)));
114 auto& tasks = _tasks[handle.index];
116 tasks.emplace_back(std::make_unique<Type>(std::forward<Args>(args)...));
118 return *
static_cast<Type*
>(tasks.back().get());
121 template<
typename Type,
typename... Args>
122 requires (std::is_constructible_v<Type, Args...>)
124 auto result = _draw_lists.emplace(name, std::make_unique<Type>(std::forward<Args>(args)...));
126 return *
static_cast<Type*
>(result.first->second.get());
129 template<
typename... Args>
131 return _graph.create_attachment(std::forward<Args>(args)...);
134 template<
typename Callable>
135 auto create_pass(Callable&& callable) ->
pass_handle {
136 return _graph.create_pass(std::forward<Callable>(callable));
139 auto build_render_graph() ->
void {
143 auto attachment_descriptions(
const pass_handle handle)
const -> std::vector<attachment_description> {
144 return _graph.attachment_descriptions(handle);
149 std::vector<std::vector<std::unique_ptr<graphics::subrenderer>>> _subrenderers;
150 std::vector<std::vector<std::unique_ptr<graphics::task>>> _tasks;
152 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:235
Definition: renderer.hpp:27
Definition: subrenderer.hpp:14
Definition: swapchain.hpp:15
Definition: hashed_string.hpp:17
Definition: render_graph.hpp:138
Definition: render_graph.hpp:148
Definition: noncopyable.hpp:7
Definition: exception.hpp:18