1 | // Copyright (C) 2023 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QSHADERDESCRIPTION_H |
5 | #define QSHADERDESCRIPTION_H |
6 | |
7 | // |
8 | // W A R N I N G |
9 | // ------------- |
10 | // |
11 | // This file is part of the RHI API, with limited compatibility guarantees. |
12 | // Usage of this API may make your code source and binary incompatible with |
13 | // future versions of Qt. |
14 | // |
15 | |
16 | #include <QtGui/qtguiglobal.h> |
17 | #include <QtCore/qstring.h> |
18 | #include <QtCore/qlist.h> |
19 | #include <array> |
20 | |
21 | QT_BEGIN_NAMESPACE |
22 | |
23 | struct QShaderDescriptionPrivate; |
24 | class QDataStream; |
25 | |
26 | class Q_GUI_EXPORT QShaderDescription |
27 | { |
28 | public: |
29 | QShaderDescription(); |
30 | QShaderDescription(const QShaderDescription &other); |
31 | QShaderDescription &operator=(const QShaderDescription &other); |
32 | ~QShaderDescription(); |
33 | void detach(); |
34 | |
35 | bool isValid() const; |
36 | |
37 | void serialize(QDataStream *stream, int version) const; |
38 | QByteArray toJson() const; |
39 | |
40 | static QShaderDescription deserialize(QDataStream *stream, int version); |
41 | |
42 | enum VariableType { |
43 | Unknown = 0, |
44 | |
45 | // do not reorder |
46 | Float, |
47 | Vec2, |
48 | Vec3, |
49 | Vec4, |
50 | Mat2, |
51 | Mat2x3, |
52 | Mat2x4, |
53 | Mat3, |
54 | Mat3x2, |
55 | Mat3x4, |
56 | Mat4, |
57 | Mat4x2, |
58 | Mat4x3, |
59 | |
60 | Int, |
61 | Int2, |
62 | Int3, |
63 | Int4, |
64 | |
65 | Uint, |
66 | Uint2, |
67 | Uint3, |
68 | Uint4, |
69 | |
70 | Bool, |
71 | Bool2, |
72 | Bool3, |
73 | Bool4, |
74 | |
75 | Double, |
76 | Double2, |
77 | Double3, |
78 | Double4, |
79 | DMat2, |
80 | DMat2x3, |
81 | DMat2x4, |
82 | DMat3, |
83 | DMat3x2, |
84 | DMat3x4, |
85 | DMat4, |
86 | DMat4x2, |
87 | DMat4x3, |
88 | |
89 | Sampler1D, |
90 | Sampler2D, |
91 | Sampler2DMS, |
92 | Sampler3D, |
93 | SamplerCube, |
94 | Sampler1DArray, |
95 | Sampler2DArray, |
96 | Sampler2DMSArray, |
97 | Sampler3DArray, |
98 | SamplerCubeArray, |
99 | SamplerRect, |
100 | SamplerBuffer, |
101 | SamplerExternalOES, |
102 | Sampler, |
103 | |
104 | Image1D, |
105 | Image2D, |
106 | Image2DMS, |
107 | Image3D, |
108 | ImageCube, |
109 | Image1DArray, |
110 | Image2DArray, |
111 | Image2DMSArray, |
112 | Image3DArray, |
113 | ImageCubeArray, |
114 | ImageRect, |
115 | ImageBuffer, |
116 | |
117 | Struct, |
118 | |
119 | Half, |
120 | Half2, |
121 | Half3, |
122 | Half4 |
123 | }; |
124 | |
125 | enum ImageFormat { |
126 | // must match SPIR-V's ImageFormat |
127 | ImageFormatUnknown = 0, |
128 | ImageFormatRgba32f = 1, |
129 | ImageFormatRgba16f = 2, |
130 | ImageFormatR32f = 3, |
131 | ImageFormatRgba8 = 4, |
132 | ImageFormatRgba8Snorm = 5, |
133 | ImageFormatRg32f = 6, |
134 | ImageFormatRg16f = 7, |
135 | ImageFormatR11fG11fB10f = 8, |
136 | ImageFormatR16f = 9, |
137 | ImageFormatRgba16 = 10, |
138 | ImageFormatRgb10A2 = 11, |
139 | ImageFormatRg16 = 12, |
140 | ImageFormatRg8 = 13, |
141 | ImageFormatR16 = 14, |
142 | ImageFormatR8 = 15, |
143 | ImageFormatRgba16Snorm = 16, |
144 | ImageFormatRg16Snorm = 17, |
145 | ImageFormatRg8Snorm = 18, |
146 | ImageFormatR16Snorm = 19, |
147 | ImageFormatR8Snorm = 20, |
148 | ImageFormatRgba32i = 21, |
149 | ImageFormatRgba16i = 22, |
150 | ImageFormatRgba8i = 23, |
151 | ImageFormatR32i = 24, |
152 | ImageFormatRg32i = 25, |
153 | ImageFormatRg16i = 26, |
154 | ImageFormatRg8i = 27, |
155 | ImageFormatR16i = 28, |
156 | ImageFormatR8i = 29, |
157 | ImageFormatRgba32ui = 30, |
158 | ImageFormatRgba16ui = 31, |
159 | ImageFormatRgba8ui = 32, |
160 | ImageFormatR32ui = 33, |
161 | ImageFormatRgb10a2ui = 34, |
162 | ImageFormatRg32ui = 35, |
163 | ImageFormatRg16ui = 36, |
164 | ImageFormatRg8ui = 37, |
165 | ImageFormatR16ui = 38, |
166 | ImageFormatR8ui = 39 |
167 | }; |
168 | |
169 | enum ImageFlag { |
170 | ReadOnlyImage = 1 << 0, |
171 | WriteOnlyImage = 1 << 1 |
172 | }; |
173 | Q_DECLARE_FLAGS(ImageFlags, ImageFlag) |
174 | |
175 | enum QualifierFlag { |
176 | QualifierReadOnly = 1 << 0, |
177 | QualifierWriteOnly = 1 << 1, |
178 | QualifierCoherent = 1 << 2, |
179 | QualifierVolatile = 1 << 3, |
180 | QualifierRestrict = 1 << 4, |
181 | }; |
182 | Q_DECLARE_FLAGS(QualifierFlags, QualifierFlag) |
183 | |
184 | // Optional data (like decorations) usually default to an otherwise invalid value (-1 or 0). This is intentional. |
185 | |
186 | struct BlockVariable { |
187 | QByteArray name; |
188 | VariableType type = Unknown; |
189 | int offset = 0; |
190 | int size = 0; |
191 | QList<int> arrayDims; |
192 | int arrayStride = 0; |
193 | int matrixStride = 0; |
194 | bool matrixIsRowMajor = false; |
195 | QList<BlockVariable> structMembers; |
196 | }; |
197 | |
198 | struct InOutVariable { |
199 | QByteArray name; |
200 | VariableType type = Unknown; |
201 | int location = -1; |
202 | int binding = -1; |
203 | int descriptorSet = -1; |
204 | ImageFormat imageFormat = ImageFormatUnknown; |
205 | ImageFlags imageFlags; |
206 | QList<int> arrayDims; |
207 | bool perPatch = false; |
208 | QList<BlockVariable> structMembers; |
209 | }; |
210 | |
211 | struct UniformBlock { |
212 | QByteArray blockName; |
213 | QByteArray structName; // instanceName |
214 | int size = 0; |
215 | int binding = -1; |
216 | int descriptorSet = -1; |
217 | QList<BlockVariable> members; |
218 | }; |
219 | |
220 | struct PushConstantBlock { |
221 | QByteArray name; |
222 | int size = 0; |
223 | QList<BlockVariable> members; |
224 | }; |
225 | |
226 | struct StorageBlock { |
227 | QByteArray blockName; |
228 | QByteArray instanceName; |
229 | int knownSize = 0; |
230 | int binding = -1; |
231 | int descriptorSet = -1; |
232 | QList<BlockVariable> members; |
233 | int runtimeArrayStride = 0; |
234 | QualifierFlags qualifierFlags; |
235 | }; |
236 | |
237 | QList<InOutVariable> inputVariables() const; |
238 | QList<InOutVariable> outputVariables() const; |
239 | QList<UniformBlock> uniformBlocks() const; |
240 | QList<PushConstantBlock> pushConstantBlocks() const; |
241 | QList<StorageBlock> storageBlocks() const; |
242 | QList<InOutVariable> combinedImageSamplers() const; |
243 | QList<InOutVariable> separateImages() const; |
244 | QList<InOutVariable> separateSamplers() const; |
245 | QList<InOutVariable> storageImages() const; |
246 | |
247 | enum BuiltinType { |
248 | // must match SpvBuiltIn |
249 | PositionBuiltin = 0, |
250 | PointSizeBuiltin = 1, |
251 | ClipDistanceBuiltin = 3, |
252 | CullDistanceBuiltin = 4, |
253 | VertexIdBuiltin = 5, |
254 | InstanceIdBuiltin = 6, |
255 | PrimitiveIdBuiltin = 7, |
256 | InvocationIdBuiltin = 8, |
257 | LayerBuiltin = 9, |
258 | ViewportIndexBuiltin = 10, |
259 | TessLevelOuterBuiltin = 11, |
260 | TessLevelInnerBuiltin = 12, |
261 | TessCoordBuiltin = 13, |
262 | PatchVerticesBuiltin = 14, |
263 | FragCoordBuiltin = 15, |
264 | PointCoordBuiltin = 16, |
265 | FrontFacingBuiltin = 17, |
266 | SampleIdBuiltin = 18, |
267 | SamplePositionBuiltin = 19, |
268 | SampleMaskBuiltin = 20, |
269 | FragDepthBuiltin = 22, |
270 | NumWorkGroupsBuiltin = 24, |
271 | WorkgroupSizeBuiltin = 25, |
272 | WorkgroupIdBuiltin = 26, |
273 | LocalInvocationIdBuiltin = 27, |
274 | GlobalInvocationIdBuiltin = 28, |
275 | LocalInvocationIndexBuiltin = 29, |
276 | VertexIndexBuiltin = 42, |
277 | InstanceIndexBuiltin = 43 |
278 | }; |
279 | |
280 | struct BuiltinVariable { |
281 | BuiltinType type; |
282 | VariableType varType; |
283 | QList<int> arrayDims; |
284 | }; |
285 | |
286 | QList<BuiltinVariable> inputBuiltinVariables() const; |
287 | QList<BuiltinVariable> outputBuiltinVariables() const; |
288 | |
289 | std::array<uint, 3> computeShaderLocalSize() const; |
290 | |
291 | uint tessellationOutputVertexCount() const; |
292 | |
293 | enum TessellationMode { |
294 | UnknownTessellationMode, |
295 | TrianglesTessellationMode, |
296 | QuadTessellationMode, |
297 | IsolineTessellationMode |
298 | }; |
299 | |
300 | TessellationMode tessellationMode() const; |
301 | |
302 | enum TessellationWindingOrder { |
303 | UnknownTessellationWindingOrder, |
304 | CwTessellationWindingOrder, |
305 | CcwTessellationWindingOrder |
306 | }; |
307 | |
308 | TessellationWindingOrder tessellationWindingOrder() const; |
309 | |
310 | enum TessellationPartitioning { |
311 | UnknownTessellationPartitioning, |
312 | EqualTessellationPartitioning, |
313 | FractionalEvenTessellationPartitioning, |
314 | FractionalOddTessellationPartitioning |
315 | }; |
316 | |
317 | TessellationPartitioning tessellationPartitioning() const; |
318 | |
319 | private: |
320 | QShaderDescriptionPrivate *d; |
321 | friend struct QShaderDescriptionPrivate; |
322 | #ifndef QT_NO_DEBUG_STREAM |
323 | friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription &); |
324 | #endif |
325 | friend Q_GUI_EXPORT bool operator==(const QShaderDescription &lhs, const QShaderDescription &rhs) noexcept; |
326 | }; |
327 | |
328 | Q_DECLARE_OPERATORS_FOR_FLAGS(QShaderDescription::ImageFlags) |
329 | Q_DECLARE_OPERATORS_FOR_FLAGS(QShaderDescription::QualifierFlags) |
330 | |
331 | #ifndef QT_NO_DEBUG_STREAM |
332 | Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription &); |
333 | Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription::InOutVariable &); |
334 | Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription::BlockVariable &); |
335 | Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription::UniformBlock &); |
336 | Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription::PushConstantBlock &); |
337 | Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription::StorageBlock &); |
338 | Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription::BuiltinVariable &); |
339 | #endif |
340 | |
341 | Q_GUI_EXPORT bool operator==(const QShaderDescription &lhs, const QShaderDescription &rhs) noexcept; |
342 | Q_GUI_EXPORT bool operator==(const QShaderDescription::InOutVariable &lhs, const QShaderDescription::InOutVariable &rhs) noexcept; |
343 | Q_GUI_EXPORT bool operator==(const QShaderDescription::BlockVariable &lhs, const QShaderDescription::BlockVariable &rhs) noexcept; |
344 | Q_GUI_EXPORT bool operator==(const QShaderDescription::UniformBlock &lhs, const QShaderDescription::UniformBlock &rhs) noexcept; |
345 | Q_GUI_EXPORT bool operator==(const QShaderDescription::PushConstantBlock &lhs, const QShaderDescription::PushConstantBlock &rhs) noexcept; |
346 | Q_GUI_EXPORT bool operator==(const QShaderDescription::StorageBlock &lhs, const QShaderDescription::StorageBlock &rhs) noexcept; |
347 | Q_GUI_EXPORT bool operator==(const QShaderDescription::BuiltinVariable &lhs, const QShaderDescription::BuiltinVariable &rhs) noexcept; |
348 | |
349 | inline bool operator!=(const QShaderDescription &lhs, const QShaderDescription &rhs) noexcept |
350 | { |
351 | return !(lhs == rhs); |
352 | } |
353 | |
354 | inline bool operator!=(const QShaderDescription::InOutVariable &lhs, const QShaderDescription::InOutVariable &rhs) noexcept |
355 | { |
356 | return !(lhs == rhs); |
357 | } |
358 | |
359 | inline bool operator!=(const QShaderDescription::BlockVariable &lhs, const QShaderDescription::BlockVariable &rhs) noexcept |
360 | { |
361 | return !(lhs == rhs); |
362 | } |
363 | |
364 | inline bool operator!=(const QShaderDescription::UniformBlock &lhs, const QShaderDescription::UniformBlock &rhs) noexcept |
365 | { |
366 | return !(lhs == rhs); |
367 | } |
368 | |
369 | inline bool operator!=(const QShaderDescription::PushConstantBlock &lhs, const QShaderDescription::PushConstantBlock &rhs) noexcept |
370 | { |
371 | return !(lhs == rhs); |
372 | } |
373 | |
374 | inline bool operator!=(const QShaderDescription::StorageBlock &lhs, const QShaderDescription::StorageBlock &rhs) noexcept |
375 | { |
376 | return !(lhs == rhs); |
377 | } |
378 | |
379 | inline bool operator!=(const QShaderDescription::BuiltinVariable &lhs, const QShaderDescription::BuiltinVariable &rhs) noexcept |
380 | { |
381 | return !(lhs == rhs); |
382 | } |
383 | |
384 | QT_END_NAMESPACE |
385 | |
386 | #endif |
387 | |