sandbox
Loading...
Searching...
No Matches
render_stage.hpp
1#ifndef LIBSBX_GRAPHICS_RENDER_STAGE_HPP_
2#define LIBSBX_GRAPHICS_RENDER_STAGE_HPP_
3
4#include <string>
5#include <cinttypes>
6#include <optional>
7#include <vector>
8
9#include <vulkan/vulkan.hpp>
10
11#include <libsbx/devices/devices_module.hpp>
12
13#include <libsbx/math/color.hpp>
14#include <libsbx/math/vector2.hpp>
15
16#include <libsbx/graphics/images/depth_image.hpp>
17#include <libsbx/graphics/images/image2d.hpp>
18
19#include <libsbx/graphics/render_pass/swapchain.hpp>
20
21namespace sbx::graphics {
22
23enum class format : std::uint32_t {
24 undefined = VK_FORMAT_UNDEFINED,
25 r32_sfloat = VK_FORMAT_R32_SFLOAT,
26 r32_uint = VK_FORMAT_R32_UINT,
27 r64_uint = VK_FORMAT_R64_UINT,
28 r32g32_sfloat = VK_FORMAT_R32G32_SFLOAT,
29 r32g32_uint = VK_FORMAT_R32G32_UINT,
30 r8g8b8a8_unorm = VK_FORMAT_R8G8B8A8_UNORM,
31 b8g8r8a8_srgb = VK_FORMAT_B8G8R8A8_SRGB,
32 r32g32b32a32_sfloat = VK_FORMAT_R32G32B32A32_SFLOAT
33}; // enum class format
34
35enum class address_mode : std::uint32_t {
36 repeat = VK_SAMPLER_ADDRESS_MODE_REPEAT,
37 clamp_to_edge = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
38}; // enum class address_mode
39
41
42public:
43
44 enum class type {
45 image,
46 depth,
48 }; // enum class type
49
50 attachment(const std::uint32_t binding, const std::string& name, type type, const math::color& clear_color = math::color::black(), const format format = format::r8g8b8a8_unorm, const address_mode address_mode = address_mode::repeat) noexcept
51 : _binding{binding},
52 _name{std::move(name)},
53 _type{type},
54 _clear_color{clear_color},
55 _format{format},
56 _address_mode{address_mode} { }
57
58 auto binding() const noexcept -> std::uint32_t {
59 return _binding;
60 }
61
62 auto name() const noexcept -> const std::string& {
63 return _name;
64 }
65
66 auto image_type() const noexcept -> type {
67 return _type;
68 }
69
70 auto format() const noexcept -> graphics::format {
71 return _format;
72 }
73
74 auto address_mode() const noexcept -> graphics::address_mode {
75 return _address_mode;
76 }
77
78 auto clear_color() const noexcept -> const math::color& {
79 return _clear_color;
80 }
81
82private:
83
84 std::uint32_t _binding;
85 std::string _name;
86 type _type;
87 bool _is_multi_sampled;
88 math::color _clear_color;
89 graphics::format _format;
90 graphics::address_mode _address_mode;
91
92}; // class attachment
93
95
96public:
97
98 subpass_binding(std::uint32_t binding, std::vector<std::uint32_t> color_attachments, std::vector<std::uint32_t> input_attachments = {}) noexcept
99 : _binding{binding},
100 _color_attachments{std::move(color_attachments)},
101 _input_attachments{std::move(input_attachments)} { }
102
103 auto binding() const noexcept -> std::uint32_t {
104 return _binding;
105 }
106
107 auto color_attachments() const noexcept -> const std::vector<std::uint32_t>& {
108 return _color_attachments;
109 }
110
111 auto input_attachments() const noexcept -> const std::vector<std::uint32_t>& {
112 return _input_attachments;
113 }
114
115private:
116
117 std::uint32_t _binding;
118 std::vector<std::uint32_t> _color_attachments;
119 std::vector<std::uint32_t> _input_attachments;
120
121}; // class subpass_binding
122
123class viewport {
124
125 enum class type {
126 fixed,
127 window,
128 dynamic
129 }; // enum class type
130
131public:
132
133 static auto fixed(const math::vector2u& size) -> viewport {
134 return viewport{type::fixed, math::vector2f{1.0f, 1.0f}, math::vector2i{0, 0}, size};
135 }
136
137 static auto window() -> viewport {
138 return viewport{type::window, math::vector2f{1.0f, 1.0f}, math::vector2i{0, 0}, std::nullopt};
139 }
140
141 static auto dynamic() -> viewport {
142 throw std::runtime_error{"Dynamic viewport not implemented"};
143 }
144
145 auto scale() const noexcept -> const math::vector2f& {
146 return _scale;
147 }
148
149 auto set_scale(const math::vector2f& scale) noexcept -> void {
150 _scale = scale;
151 }
152
153 auto offset() const noexcept -> const math::vector2i& {
154 return _offset;
155 }
156
157 auto set_offset(const math::vector2i& offset) noexcept -> void {
158 _offset = offset;
159 }
160
161 auto size() const noexcept -> const std::optional<math::vector2u>& {
162 return _size;
163 }
164
165 auto set_size(const math::vector2u& size) noexcept -> void {
166 _size = size;
167 }
168
169 auto is_fixed() const noexcept -> bool {
170 return _type == type::fixed;
171 }
172
173 auto is_window() const noexcept -> bool {
174 return _type == type::window;
175 }
176
177 auto is_dynamic() const noexcept -> bool {
178 return _type == type::dynamic;
179 }
180
181private:
182
183 // viewport() noexcept
184 // : _scale{1.0f, 1.0f},
185 // _offset{0, 0},
186 // _size{std::nullopt} { }
187
188 // viewport(const math::vector2u& size) noexcept
189 // : _scale{1.0f, 1.0f},
190 // _offset{0, 0},
191 // _size{size} { }
192
193 viewport(const type type, const math::vector2f& scale, const math::vector2i& offset, const std::optional<math::vector2u>& size = std::nullopt) noexcept
194 : _type{type},
195 _scale{scale},
196 _offset{offset},
197 _size{size} { }
198
199 type _type;
200 math::vector2f _scale;
201 math::vector2i _offset;
202 std::optional<math::vector2u> _size;
203
204}; // class viewport
205
207
208public:
209
210 render_area(const math::vector2u& extent = math::vector2u{}, const math::vector2i& offset = math::vector2i{}) noexcept
211 : _extent{extent},
212 _offset{offset},
213 _aspect_ratio{static_cast<std::float_t>(extent.x()) / static_cast<std::float_t>(extent.y())} { }
214
215 auto operator==(const render_area& other) const noexcept -> bool {
216 return _extent == other._extent && _offset == other._offset;
217 }
218
219 auto extent() const noexcept -> const math::vector2u& {
220 return _extent;
221 }
222
223 auto set_extent(const math::vector2u& extent) noexcept -> void {
224 _extent = extent;
225 }
226
227 auto offset() const noexcept -> const math::vector2i& {
228 return _offset;
229 }
230
231 auto set_offset(const math::vector2i& offset) noexcept -> void {
232 _offset = offset;
233 }
234
235 auto aspect_ratio() const noexcept -> std::float_t {
236 return _aspect_ratio;
237 }
238
239 auto set_aspect_ratio(std::float_t aspect_ratio) noexcept -> void {
240 _aspect_ratio = aspect_ratio;
241 }
242
243private:
244
245 math::vector2u _extent;
246 math::vector2i _offset;
247 std::float_t _aspect_ratio;
248
249}; // class render_area
250
252
253public:
254
255 render_stage(std::vector<attachment>&& attachments, std::vector<subpass_binding>&& subpass_bindings, const graphics::viewport& viewport = graphics::viewport::window());
256
258
259 auto attachments() const noexcept -> const std::vector<graphics::attachment>&;
260
261 auto find_attachment(const std::string& name) const noexcept -> std::optional<graphics::attachment>;
262
263 auto find_attachment(std::uint32_t binding) const noexcept -> std::optional<graphics::attachment>;
264
265 auto subpasses() const noexcept -> const std::vector<subpass_binding>&;
266
267 auto attachment_count(std::uint32_t subpass) const -> std::uint32_t;
268
269 auto subpass_attachments(std::uint32_t subpass) const -> const std::vector<std::uint32_t>&;
270
271 auto clear_values() const noexcept -> const std::vector<VkClearValue>&;
272
273 auto has_depth_attachment() const noexcept -> bool;
274
275 auto has_swapchain_attachment() const noexcept -> bool;
276
277 auto viewport() const noexcept -> const viewport&;
278
279 auto render_area() const noexcept -> const render_area&;
280
281 auto render_pass() const noexcept -> const VkRenderPass&;
282
283 auto rebuild(const swapchain& swapchain) -> void;
284
285 auto framebuffer(std::uint32_t index) noexcept -> const VkFramebuffer&;
286
287 auto descriptor(const std::string& name) const noexcept -> memory::observer_ptr<const graphics::descriptor>;
288
289 auto descriptors() const noexcept -> const std::map<std::string, memory::observer_ptr<const graphics::descriptor>>&;
290
291private:
292
293 auto _create_render_pass(VkFormat depth_format, VkFormat surface_format) -> void;
294
295 auto _rebuild_framebuffers(const swapchain& swapchain) -> void;
296
297 auto _update_subpass_attachment_counts(const graphics::attachment& attachment) -> void;
298
299 auto _create_attachment_descriptions(VkFormat depth_format, VkFormat surface_format) -> std::vector<VkAttachmentDescription>;
300
301 auto _create_subpass_dependencies() -> std::vector<VkSubpassDependency>;
302
303 std::vector<graphics::attachment> _attachments;
304 std::vector<subpass_binding> _subpass_bindings;
305
306 graphics::viewport _viewport;
307
308 VkRenderPass _render_pass;
309
310 std::map<std::string, memory::observer_ptr<const graphics::descriptor>> _descriptors;
311
312 std::unique_ptr<graphics::depth_image> _depth_image;
313 std::unordered_map<std::uint32_t, std::unique_ptr<graphics::image2d>> _color_images;
314
315 std::vector<VkFramebuffer> _framebuffers;
316
317 std::vector<VkClearValue> _clear_values;
318 std::vector<std::uint32_t> _subpass_attachment_counts;
319 std::vector<std::vector<std::uint32_t>> _subpass_attachments;
320 std::optional<graphics::attachment> _depth_attachment;
321 std::optional<graphics::attachment> _swapchain_attachment;
322
323 graphics::render_area _render_area;
324
325}; // class render_stage
326
327} // namespace sbx::graphics
328
329#endif // LIBSBX_GRAPHICS_RENDER_STAGE_HPP_
Definition: render_stage.hpp:40
Definition: descriptor.hpp:37
Definition: image.hpp:20
Definition: render_stage.hpp:206
Definition: render_stage.hpp:251
Definition: render_stage.hpp:94
Definition: swapchain.hpp:12
Definition: render_stage.hpp:123
A vector in two-dimensional space.
Definition: vector2.hpp:27
Definition: color.hpp:14
A non-owning pointer that can be used to observe the value of a pointer.
Definition: observer_ptr.hpp:27