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