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