2#ifndef LIBSBX_GRAPHICS_RENDER_GRAPH_HPP_
3#define LIBSBX_GRAPHICS_RENDER_GRAPH_HPP_
9#include <unordered_map>
14#include <vulkan/vulkan.h>
16#include <libsbx/utility/enum.hpp>
17#include <libsbx/utility/exception.hpp>
18#include <libsbx/utility/hashed_string.hpp>
19#include <libsbx/utility/logger.hpp>
20#include <libsbx/utility/overload.hpp>
24#include <libsbx/memory/observer_ptr.hpp>
26#include <libsbx/graphics/viewport.hpp>
27#include <libsbx/graphics/draw_list.hpp>
29#include <libsbx/graphics/images/image2d.hpp>
30#include <libsbx/graphics/images/depth_image.hpp>
32#include <libsbx/graphics/render_pass/swapchain.hpp>
34namespace sbx::graphics {
36enum class blend_factor : std::int32_t {
37 zero = VK_BLEND_FACTOR_ZERO,
38 one = VK_BLEND_FACTOR_ONE,
39 source_color = VK_BLEND_FACTOR_SRC_COLOR,
40 one_minus_source_color = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR,
41 source_alpha = VK_BLEND_FACTOR_SRC_ALPHA,
42 one_minus_source_alpha = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
43 destination_color = VK_BLEND_FACTOR_DST_COLOR,
44 one_minus_destination_color = VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR,
45 destination_alpha = VK_BLEND_FACTOR_DST_ALPHA,
46 one_minus_destination_alpha = VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA,
47 constant_color = VK_BLEND_FACTOR_CONSTANT_COLOR,
48 one_minus_constant_color = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR,
49 constant_alpha = VK_BLEND_FACTOR_CONSTANT_ALPHA,
50 one_minus_constant_alpha = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA,
51 source_alpha_saturate = VK_BLEND_FACTOR_SRC_ALPHA_SATURATE
54enum class blend_operation : std::int32_t {
55 add = VK_BLEND_OP_ADD,
56 subtract = VK_BLEND_OP_SUBTRACT,
57 reverse_subtract = VK_BLEND_OP_REVERSE_SUBTRACT,
58 min = VK_BLEND_OP_MIN,
62enum class color_component : std::int32_t {
63 r = VK_COLOR_COMPONENT_R_BIT,
64 g = VK_COLOR_COMPONENT_G_BIT,
65 b = VK_COLOR_COMPONENT_B_BIT,
66 a = VK_COLOR_COMPONENT_A_BIT
69inline constexpr auto operator|(
const color_component lhs,
const color_component rhs)
noexcept -> color_component {
70 return static_cast<color_component
>(
static_cast<std::underlying_type_t<color_component>
>(lhs) |
static_cast<std::underlying_type_t<color_component>
>(rhs));
73inline constexpr auto operator&(
const color_component lhs,
const color_component rhs)
noexcept -> color_component {
74 return static_cast<color_component
>(
static_cast<std::underlying_type_t<color_component>
>(lhs) &
static_cast<std::underlying_type_t<color_component>
>(rhs));
78 blend_factor color_source{blend_factor::source_alpha};
79 blend_factor color_destination{blend_factor::one_minus_source_alpha};
80 blend_operation color_operation{blend_operation::add};
81 blend_factor alpha_source{blend_factor::one};
82 blend_factor alpha_destination{blend_factor::zero};
83 blend_operation alpha_operation{blend_operation::add};
84 color_component color_write_mask{color_component::r | color_component::g | color_component::b | color_component::a};
87enum class attachment_load_operation : std::int32_t {
88 load = VK_ATTACHMENT_LOAD_OP_LOAD,
89 clear = VK_ATTACHMENT_LOAD_OP_CLEAR,
90 dont_care = VK_ATTACHMENT_LOAD_OP_DONT_CARE
110 auto image_type()
const noexcept -> type;
112 auto format()
const noexcept -> graphics::format;
114 auto address_mode()
const noexcept -> graphics::address_mode;
116 auto clear_color()
const noexcept ->
const math::color&;
120 auto array_layers()
const noexcept -> std::uint32_t;
127 graphics::format _format;
128 graphics::filter _filter;
129 graphics::address_mode _address_mode;
131 std::uint32_t _array_layers;
136 attachment::type image_type;
137 graphics::format format;
139 std::uint32_t array_layers{1u};
144 std::uint32_t index{0xFFFFFFFF};
146 [[nodiscard]]
auto is_valid()
const noexcept ->
bool {
147 return index != 0xFFFFFFFF;
154 std::uint32_t index{0xFFFFFFFF};
156 [[nodiscard]]
auto is_valid()
const noexcept ->
bool {
157 return index != 0xFFFFFFFF;
168 enum class kind : std::uint8_t {
182 template<
typename... Attachments>
183 requires (
sizeof...(Attachments) > 1u && (std::is_same_v<std::remove_cvref_t<Attachments>,
attachment_handle> && ...))
184 auto reads(Attachments&&... attachments) ->
void {
185 (reads(attachments), ...);
188 auto writes(
const attachment_handle attachment,
const attachment_load_operation load_operation = attachment_load_operation::clear) ->
void {
189 _writes.emplace_back(
attachment, load_operation);
193 _dependencies.emplace_back(pass);
196 template<
typename... Passes>
197 requires (
sizeof...(Passes) > 1u && (std::is_same_v<std::remove_cvref_t<Passes>,
pass_handle> && ...))
198 auto depends_on(Passes&&... passes) ->
void {
199 (depends_on(passes), ...);
205 std::vector<attachment_handle> _reads;
206 std::vector<std::pair<attachment_handle, attachment_load_operation>> _writes;
207 std::vector<pass_handle> _dependencies;
216 VkImageLayout new_layout;
221 std::vector<std::pair<attachment_handle, attachment_load_operation>> attachments;
228using instruction = std::variant<transition_instruction, pass_instruction, compute_instruction>;
233 VkImageLayout current_layout = VK_IMAGE_LAYOUT_UNDEFINED;
236 attachment::type type;
237 std::uint32_t array_layers{1u};
253 template<
typename... Args>
254 requires (std::is_constructible_v<
attachment, Args...>)
257 template<
typename Callable>
258 requires (std::is_invocable_r_v<pass_node, Callable, context&>)
259 auto create_pass(Callable&& callable) ->
pass_handle;
261 auto find_attachment(
const std::string& name)
const ->
const image2d&;
263 auto attachment_descriptions(
const pass_handle handle)
const -> std::vector<attachment_description>;
265 auto build() -> void;
267 auto resize(
const std::string& viewport_name) -> void;
269 auto pass_kind(
const pass_handle handle)
const -> pass_node::kind {
270 utility::assert_that(handle.is_valid() && handle.index < _passes.size(),
"Invalid pass handle");
272 return _passes[handle.index]._kind;
275 template<
typename PassCallback,
typename ComputeCallback>
276 requires (std::is_invocable_v<PassCallback, const pass_handle&> && std::is_invocable_v<ComputeCallback, const pass_handle&>)
278 for (
auto& state : _attachment_states) {
279 if (state.type == attachment::type::swapchain) {
280 state.current_layout = VK_IMAGE_LAYOUT_UNDEFINED;
284 for (
const auto& instruction : _instructions) {
285 std::visit(utility::overload{
286 [&](
const transition_instruction& instruction) { _execute_transition_instruction(command_buffer, swapchain, instruction); },
287 [&](
const pass_instruction& instruction) { _execute_pass_instruction(command_buffer, swapchain, instruction, std::forward<PassCallback>(pass_callback)); },
288 [&](
const compute_instruction& instruction) { _execute_compute_instruction(command_buffer, instruction, std::forward<ComputeCallback>(compute_callback)); },
295 auto _update_viewports() -> void;
297 auto _clear_attachments(
const std::string& viewport_name) -> void;
299 auto _create_attachments(
const pass_node&
node) -> void;
301 auto _pass_matches(
const pass_node& pass,
const std::string& viewport_name)
const -> bool;
303 auto _build_color_attachment_info(
const attachment& attachment,
const attachment_state& state,
const swapchain& swapchain,
const attachment_load_operation load_op) -> VkRenderingAttachmentInfo;
305 auto _build_depth_attachment_info(
const attachment& attachment,
const attachment_state& state,
const attachment_load_operation load_op) -> VkRenderingAttachmentInfo;
307 template<
typename Callable>
308 auto _execute_pass_instruction(command_buffer& command_buffer,
const swapchain& swapchain,
const pass_instruction& instruction, Callable&& callable) -> void;
310 template<
typename Callable>
311 auto _execute_compute_instruction(command_buffer& command_buffer,
const compute_instruction& instruction, Callable&& callable) -> void;
313 auto _execute_transition_instruction(command_buffer& command_buffer,
const swapchain& swapchain,
const transition_instruction& instruction) -> void;
315 std::vector<attachment> _attachments;
316 std::vector<pass_node> _passes;
318 std::vector<image2d_handle> _color_images;
319 std::vector<depth_image_handle> _depth_images;
321 std::vector<attachment_state> _attachment_states;
323 std::unordered_map<utility::hashed_string, std::uint32_t> _image_by_name;
325 std::vector<instruction> _instructions;
331#include <libsbx/graphics/render_graph.ipp>
Definition: render_graph.hpp:93
Definition: command_buffer.hpp:15
Definition: image2d.hpp:52
Definition: render_graph.hpp:162
Definition: viewport.hpp:81
Definition: render_graph.hpp:240
Definition: swapchain.hpp:15
Definition: viewport.hpp:13
RGBA color value type.
Definition: color.hpp:48
static auto black() noexcept -> color
Returns a black color.
Definition: color.cpp:45
Definition: hashed_string.hpp:17
RGBA color representation and utilities.
Definition: render_graph.hpp:135
Definition: render_graph.hpp:142
Definition: render_graph.hpp:230
Definition: render_graph.hpp:77
Definition: render_graph.hpp:224
Definition: render_graph.hpp:152
Definition: render_graph.hpp:219
Definition: render_graph.hpp:244
Definition: render_graph.hpp:214