sandbox
Loading...
Searching...
No Matches
graphics_pipeline.hpp
1#ifndef LIBSBX_GRAPHICS_PIPELINE_GRAPHICS_PIPELINE_HPP_
2#define LIBSBX_GRAPHICS_PIPELINE_GRAPHICS_PIPELINE_HPP_
3
4#include <optional>
5#include <filesystem>
6#include <cinttypes>
7#include <vector>
8#include <unordered_map>
9#include <map>
10#include <memory>
11
12#include <vulkan/vulkan.hpp>
13
14#include <fmt/format.h>
15
16#include <libsbx/utility/enum.hpp>
17
18#include <libsbx/containers/static_vector.hpp>
19
20#include <libsbx/graphics/buffers/buffer.hpp>
21#include <libsbx/graphics/buffers/uniform_handler.hpp>
22
23#include <libsbx/graphics/pipeline/shader.hpp>
24#include <libsbx/graphics/pipeline/pipeline.hpp>
25#include <libsbx/graphics/pipeline/vertex_input_description.hpp>
26
27#include <libsbx/graphics/descriptor/descriptor.hpp>
28#include <libsbx/graphics/descriptor/descriptor_set.hpp>
29
30#include <libsbx/graphics/images/image2d.hpp>
31
32namespace sbx::graphics {
33
34enum class polygon_mode : std::uint8_t {
35 fill = VK_POLYGON_MODE_FILL,
36 line = VK_POLYGON_MODE_LINE,
37 point = VK_POLYGON_MODE_POINT
38}; // enum class polygon_mode
39
40enum class cull_mode : std::uint8_t {
41 none = VK_CULL_MODE_NONE,
42 front = VK_CULL_MODE_FRONT_BIT,
43 back = VK_CULL_MODE_BACK_BIT,
44 front_and_back = VK_CULL_MODE_FRONT_AND_BACK
45}; // enum class cull_mode
46
47enum class front_face : std::uint8_t {
48 counter_clockwise = VK_FRONT_FACE_COUNTER_CLOCKWISE,
49 clockwise = VK_FRONT_FACE_CLOCKWISE
50}; // enum class front_face
51
52struct depth_bias {
53 std::float_t constant_factor{0.0f};
54 std::float_t clamp{0.0f};
55 std::float_t slope_factor{0.0f};
56}; // struct depth_bias
57
59 graphics::polygon_mode polygon_mode{polygon_mode::fill};
60 std::float_t line_width{1.0f};
61 graphics::cull_mode cull_mode{cull_mode::back};
62 graphics::front_face front_face{front_face::counter_clockwise};
63 std::optional<graphics::depth_bias> depth_bias{};
64}; // struct rasterization_state
65
66enum class primitive_topology : std::uint8_t {
67 point_list = VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
68 line_list = VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
69 line_strip = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
70 triangle_list = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
71 triangle_strip = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
72 triangle_fan = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
73 line_list_with_adjacency = VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
74 line_strip_with_adjacency = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
75 triangle_list_with_adjacency = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,
76 triangle_strip_with_adjacency = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY,
77 patch_list = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
78}; // enum class primitive_topology
79
80enum class depth : std::uint8_t {
81 disabled = 0,
82 read_write = 1,
83 read_only = 2
84}; // enum class depth_test
85
87 graphics::depth depth{depth::read_write};
88 bool uses_transparency{false};
90 graphics::primitive_topology primitive_topology{graphics::primitive_topology::triangle_list};
93}; // struct pipeline_definition
94
96
97public:
98
99 graphics_pipeline(const std::filesystem::path& path, const pipeline::stage& stage, const pipeline_definition& default_definition = pipeline_definition{}, const VkSpecializationInfo* specialization_info = nullptr);
100
101 ~graphics_pipeline() override;
102
103 auto handle() const noexcept -> VkPipeline override;
104
105 auto has_variable_descriptors() const noexcept -> bool override {
106 return _has_variable_descriptors;
107 }
108
109 auto descriptor_counts(std::uint32_t set) const noexcept -> std::vector<std::uint32_t> override {
110 auto counts = std::vector<std::uint32_t>{};
111
112 for (const auto& binding_data : _set_data[set].binding_data) {
113 counts.push_back(binding_data.descriptor_count);
114 }
115
116 return counts;
117 }
118
119 auto descriptor_set_layout(std::uint32_t set) const noexcept -> VkDescriptorSetLayout override;
120
121 auto descriptor_pool() const noexcept -> VkDescriptorPool override;
122
123 auto layout() const noexcept -> VkPipelineLayout override;
124
125 auto bind_point() const noexcept -> VkPipelineBindPoint override;
126
127 auto stage() const noexcept -> const pipeline::stage& {
128 return _stage;
129 }
130
131 auto descriptor_block(const std::string& name, std::uint32_t set) const -> const shader::uniform_block& override {
132 if (auto it = _set_data[set].uniform_blocks.find(name); it != _set_data[set].uniform_blocks.end()) {
133 return it->second;
134 }
135
136 throw std::runtime_error(fmt::format("Failed to find descriptor block '{}' in graphics pipeline '{}'", name, _name));
137 }
138
139 auto push_constant() const noexcept -> const std::optional<shader::uniform_block>& override {
140 return _push_constant;
141 }
142
143 auto find_descriptor_binding(const std::string& name, std::uint32_t set) const -> std::optional<std::uint32_t> override {
144 if (auto it = _set_data[set].descriptor_bindings.find(name); it != _set_data[set].descriptor_bindings.end()) {
145 return it->second;
146 }
147
148 return std::nullopt;
149 }
150
151 auto find_descriptor_type_at_binding(std::uint32_t set, std::uint32_t binding) const -> std::optional<VkDescriptorType> override {
152 if (_set_data[set].binding_data.size() <= binding) {
153 return std::nullopt;
154 }
155
156 return _set_data[set].binding_data[binding].descriptor_type;
157 }
158
159private:
160
161 struct per_binding_data {
162 VkDescriptorType descriptor_type;
163 std::uint32_t descriptor_count;
164 }; // struct per_binding_data
165
166 struct per_set_data {
167 std::unordered_map<std::string, shader::uniform> uniforms;
168 std::unordered_map<std::string, shader::uniform_block> uniform_blocks;
169 std::unordered_map<std::string, std::uint32_t> descriptor_bindings;
170 std::unordered_map<std::string, std::uint32_t> descriptor_sizes;
171 std::vector<per_binding_data> binding_data;
172 VkDescriptorSetLayout layout;
173 }; // struct per_set_data
174
175 auto _update_definition(const std::filesystem::path& path, const pipeline_definition default_definition) -> pipeline_definition;
176
177 auto _get_stage_from_name(const std::string& name) const noexcept -> VkShaderStageFlagBits;
178
179 std::unordered_map<VkShaderStageFlagBits, std::unique_ptr<shader>> _shaders{};
180
181 std::vector<per_set_data> _set_data;
182 std::optional<shader::uniform_block> _push_constant;
183
184 std::string _name{};
185 VkPipelineLayout _layout{};
186 VkPipeline _handle{};
187 VkPipelineBindPoint _bind_point{};
188 bool _has_variable_descriptors;
189
190 pipeline::stage _stage{};
191
192 VkDescriptorPool _descriptor_pool{};
193
194}; // class graphics_pipeline
195
196} // namespace sbx::graphics
197
198template<>
199struct sbx::utility::enum_mapping<sbx::graphics::polygon_mode> {
200
202
203 static constexpr auto values = std::array<entry_type, 3u>{
204 entry_type{sbx::graphics::polygon_mode::fill, "fill"},
205 entry_type{sbx::graphics::polygon_mode::line, "line"},
206 entry_type{sbx::graphics::polygon_mode::point, "point"}
207 };
208
209}; // struct sbx::utility::enum_mapping
210
211template<>
212struct sbx::utility::enum_mapping<sbx::graphics::depth> {
213
215
216 static constexpr auto values = std::array<entry_type, 3u>{
217 entry_type{sbx::graphics::depth::disabled, "disabled"},
218 entry_type{sbx::graphics::depth::read_write, "read_write"},
219 entry_type{sbx::graphics::depth::read_only, "read_only"}
220 };
221
222}; // struct sbx::utility::enum_mapping
223
224template<>
225struct sbx::utility::enum_mapping<sbx::graphics::cull_mode> {
226
228
229 static constexpr auto values = std::array<entry_type, 4u>{
230 entry_type{sbx::graphics::cull_mode::back, "back"},
231 entry_type{sbx::graphics::cull_mode::front, "front"},
232 entry_type{sbx::graphics::cull_mode::front_and_back, "front_and_back"},
233 entry_type{sbx::graphics::cull_mode::none, "none"}
234 };
235
236}; // struct sbx::utility::enum_mapping
237
238template<>
239struct sbx::utility::enum_mapping<sbx::graphics::front_face> {
240
242
243 static constexpr auto values = std::array<entry_type, 2u>{
244 entry_type{sbx::graphics::front_face::clockwise, "clockwise"},
245 entry_type{sbx::graphics::front_face::counter_clockwise, "counter_clockwise"}
246 };
247
248}; // struct sbx::utility::enum_mapping
249
250#endif // LIBSBX_GRAPHICS_PIPELINE_GRAPHICS_PIPELINE_HPP_
static_vector implementation inspired by https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p08...
Definition: static_vector.hpp:24
Definition: graphics_pipeline.hpp:95
Definition: pipeline.hpp:18
Definition: shader.hpp:125
Definition: graphics_pipeline.hpp:52
Definition: pipeline.hpp:22
Definition: graphics_pipeline.hpp:86
Definition: graphics_pipeline.hpp:58
Definition: vertex_input_description.hpp:12
Definition: vertex_input_description.hpp:18
Definition: enum.hpp:131
Definition: enum.hpp:138