sandbox
Loading...
Searching...
No Matches
shader.hpp
1#ifndef LIBSBX_GRAPHICS_PIPELINE_SHADER_HPP_
2#define LIBSBX_GRAPHICS_PIPELINE_SHADER_HPP_
3
4#include <filesystem>
5#include <map>
6#include <unordered_map>
7#include <optional>
8
9#include <spirv_cross/spirv_cross.hpp>
10
11#include <vulkan/vulkan.hpp>
12
13#include <libsbx/utility/noncopyable.hpp>
14
15#include <libsbx/containers/static_vector.hpp>
16
17namespace sbx::graphics {
18
20
21public:
22
23 enum class data_type : std::uint8_t {
24 unknown,
25 boolean,
26 int32,
27 uint32,
28 float32,
29 vec2,
30 ivec2,
31 uvec2,
32 vec3,
33 ivec3,
34 uvec3,
35 vec4,
36 ivec4,
37 uvec4,
38 mat2,
39 imat2,
40 umat2,
41 mat3,
42 imat3,
43 umat3,
44 mat4,
45 imat4,
46 umat4,
47 sampler2d,
48 sampler2d_array,
49 sampler_cube,
51 separate_image2d,
53 storage_image,
54 subpass_input,
55 structure
56 }; // enum class data_type
57
58 class uniform {
59
60 public:
61
62 explicit uniform(std::uint32_t set, std::uint32_t binding, std::uint32_t offset, std::uint32_t size, data_type type, bool is_readonly, bool is_writeonly, VkShaderStageFlags stage_flags)
63 : _set{set},
64 _binding{binding},
65 _offset{offset},
66 _size{size},
67 _type{type},
68 _is_readonly{is_readonly},
69 _is_writeonly{is_writeonly},
70 _stage_flags{stage_flags} { }
71
72 auto set() const noexcept -> std::uint32_t {
73 return _set;
74 }
75
76 auto binding() const noexcept -> std::uint32_t {
77 return _binding;
78 }
79
80 auto offset() const noexcept -> std::uint32_t {
81 return _offset;
82 }
83
84 auto size() const noexcept -> std::uint32_t {
85 return _size;
86 }
87
88 auto type() const noexcept -> data_type {
89 return _type;
90 }
91
92 auto is_readonly() const noexcept -> bool {
93 return _is_readonly;
94 }
95
96 auto is_writeonly() const noexcept -> bool {
97 return _is_writeonly;
98 }
99
100 auto stage_flags() const noexcept -> VkShaderStageFlags {
101 return _stage_flags;
102 }
103
104 auto add_stage_flag(VkShaderStageFlags stage) noexcept -> void {
105 _stage_flags |= stage;
106 }
107
108 auto operator==(const uniform& other) const noexcept -> bool {
109 return _set == other._set && _binding == other._binding && _offset == other._offset && _size == other._size && _type == other._type && _is_readonly == other._is_readonly && _is_writeonly == other._is_writeonly && _stage_flags == other._stage_flags;
110 }
111
112 private:
113
114 std::uint32_t _set{};
115 std::uint32_t _binding{};
116 std::uint32_t _offset{};
117 std::uint32_t _size{};
118 data_type _type{};
119 bool _is_readonly{};
120 bool _is_writeonly{};
121 VkShaderStageFlags _stage_flags{};
122
123 }; // class uniform
124
126
127 public:
128
129 enum class type : std::uint8_t {
130 uniform,
131 storage,
132 push
133 }; // enum class type
134
135 explicit uniform_block(std::uint32_t set, std::uint32_t binding, std::uint32_t size, VkShaderStageFlags stage_flags, type type, std::map<std::string, uniform> uniforms = {})
136 : _set{set},
137 _binding{binding},
138 _size{size},
139 _stage_flags{stage_flags},
140 _type{type},
141 _uniforms{std::move(uniforms)} { }
142
143 auto set() const noexcept -> std::uint32_t {
144 return _set;
145 }
146
147 auto binding() const noexcept -> std::uint32_t {
148 return _binding;
149 }
150
151 auto size() const noexcept -> std::uint32_t {
152 return _size;
153 }
154
155 auto stage_flags() const noexcept -> VkShaderStageFlags {
156 return _stage_flags;
157 }
158
159 auto add_stage_flag(VkShaderStageFlags stage) noexcept -> void {
160 _stage_flags |= stage;
161 }
162
163 auto buffer_type() const noexcept -> type {
164 return _type;
165 }
166
167 auto uniforms() const noexcept -> const std::map<std::string, uniform>& {
168 return _uniforms;
169 }
170
171 auto find_uniform(const std::string& name) const noexcept -> std::optional<uniform> {
172 if (auto entry = _uniforms.find(name); entry != _uniforms.end()) {
173 return entry->second;
174 }
175
176 return std::nullopt;
177 }
178
179 auto operator==(const uniform_block& other) const noexcept -> bool {
180 return _set == other._set && _binding == other._binding && _size == other._size && _stage_flags == other._stage_flags && _type == other._type && _uniforms == other._uniforms;
181 }
182
183 private:
184
185 std::uint32_t _set{};
186 std::uint32_t _binding{};
187 std::uint32_t _size{};
188 VkShaderStageFlags _stage_flags{};
189 type _type{};
190 std::map<std::string, uniform> _uniforms{};
191
192 }; // class uniform_block
193
194 class attribute {
195
196 public:
197
198 explicit attribute(std::uint32_t binding, std::uint32_t size, VkShaderStageFlags stage_flags, data_type type)
199 : _binding{binding},
200 _size{size},
201 _stage_flags{stage_flags},
202 _type{type} { }
203
204 auto binding() const noexcept -> std::uint32_t {
205 return _binding;
206 }
207
208 auto size() const noexcept -> std::uint32_t {
209 return _size;
210 }
211
212 auto stage_flags() const noexcept -> VkShaderStageFlags {
213 return _stage_flags;
214 }
215
216 auto type() const noexcept -> data_type {
217 return _type;
218 }
219
220 auto operator==(const attribute& other) const noexcept -> bool {
221 return _binding == other._binding && _size == other._size && _stage_flags == other._stage_flags && _type == other._type;
222 }
223
224 private:
225
226 std::uint32_t _binding{};
227 std::uint32_t _size{};
228 VkShaderStageFlags _stage_flags{};
229 data_type _type{};
230
231 }; // class attribute
232
233 struct define {
234 std::string name{};
235 std::string value{};
236 }; // struct define
237
238 using handle_type = VkShaderModule;
239
240 shader(const std::filesystem::path& path, VkShaderStageFlagBits stage, const containers::static_vector<define, 10u>& defines = {});
241
242 ~shader();
243
244 auto handle() const noexcept -> handle_type;
245
246 operator handle_type() const noexcept;
247
248 auto stage() const noexcept -> VkShaderStageFlagBits;
249
250 auto set_uniforms() const noexcept -> const std::vector<std::unordered_map<std::string, uniform>>& {
251 return _set_uniforms;
252 }
253
254 auto set_uniform_blocks() const noexcept -> const std::vector<std::unordered_map<std::string, uniform_block>>& {
255 return _set_uniform_blocks;
256 }
257
258 auto uniforms(std::uint32_t set) const noexcept -> const std::unordered_map<std::string, uniform>& {
259 return _set_uniforms[set];
260 }
261
262 auto uniform_blocks(std::uint32_t set) const noexcept -> const std::unordered_map<std::string, uniform_block>& {
263 return _set_uniform_blocks[set];
264 }
265
266private:
267
268 auto _create_reflection(const spirv_cross::Compiler& compiler) -> void;
269
270 auto _get_data_type(const spirv_cross::SPIRType& type) -> data_type;
271
272 auto _data_type_to_string(data_type type) -> std::string;
273
274 std::vector<std::unordered_map<std::string, uniform>> _set_uniforms{};
275 std::vector<std::unordered_map<std::string, uniform_block>> _set_uniform_blocks{};
276
277 VkShaderStageFlagBits _stage{};
278 handle_type _handle{};
279
280}; // class shader
281
282} // namespace sbx::graphics
283
284#endif // LIBSBX_GRAPHICS_PIPELINE_SHADER_HPP_
static_vector implementation inspired by https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p08...
Definition: static_vector.hpp:24
Definition: separate_image2d_array.hpp:15
Definition: separate_sampler.hpp:8
Definition: shader.hpp:194
Definition: shader.hpp:125
Definition: shader.hpp:58
Definition: shader.hpp:19
Definition: shader.hpp:233
Definition: noncopyable.hpp:6