1 /****************************************************************************
2 **
3 ** Copyright (C) 2019 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Gui module
7 **
8 ** $QT_BEGIN_LICENSE:LGPL3$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or later as published by the Free
28 ** Software Foundation and appearing in the file LICENSE.GPL included in
29 ** the packaging of this file. Please review the following information to
30 ** ensure the GNU General Public License version 2.0 requirements will be
31 ** met: http://www.gnu.org/licenses/gpl-2.0.html.
32 **
33 ** $QT_END_LICENSE$
34 **
35 ****************************************************************************/
36 
37 #ifndef QSHADERDESCRIPTION_H
38 #define QSHADERDESCRIPTION_H
39 
40 //
41 //  W A R N I N G
42 //  -------------
43 //
44 // This file is not part of the Qt API.  It exists for the convenience
45 // of a number of Qt sources files.  This header file may change from
46 // version to version without notice, or even be removed.
47 //
48 // We mean it.
49 //
50 
51 #include <QtGui/qtguiglobal.h>
52 #include <QtCore/QString>
53 #include <QtCore/QVector>
54 #include <array>
55 
56 QT_BEGIN_NAMESPACE
57 
58 struct QShaderDescriptionPrivate;
59 class QDataStream;
60 
61 class Q_GUI_EXPORT QShaderDescription
62 {
63 public:
64     QShaderDescription();
65     QShaderDescription(const QShaderDescription &other);
66     QShaderDescription &operator=(const QShaderDescription &other);
67     ~QShaderDescription();
68     void detach();
69 
70     bool isValid() const;
71 
72     QByteArray toCbor() const;
73     void serialize(QDataStream *stream) const;
74     QByteArray toJson() const;
75 
76 #if QT_CONFIG(binaryjson) && QT_DEPRECATED_SINCE(5, 15)
77     QT_DEPRECATED_X("Use CBOR format instead")
78     static QShaderDescription fromBinaryJson(const QByteArray &data);
79 #endif
80     static QShaderDescription fromCbor(const QByteArray &data);
81     static QShaderDescription deserialize(QDataStream *stream, int version);
82 
83     enum VariableType {
84         Unknown = 0,
85 
86         // do not reorder
87         Float,
88         Vec2,
89         Vec3,
90         Vec4,
91         Mat2,
92         Mat2x3,
93         Mat2x4,
94         Mat3,
95         Mat3x2,
96         Mat3x4,
97         Mat4,
98         Mat4x2,
99         Mat4x3,
100 
101         Int,
102         Int2,
103         Int3,
104         Int4,
105 
106         Uint,
107         Uint2,
108         Uint3,
109         Uint4,
110 
111         Bool,
112         Bool2,
113         Bool3,
114         Bool4,
115 
116         Double,
117         Double2,
118         Double3,
119         Double4,
120         DMat2,
121         DMat2x3,
122         DMat2x4,
123         DMat3,
124         DMat3x2,
125         DMat3x4,
126         DMat4,
127         DMat4x2,
128         DMat4x3,
129 
130         Sampler1D,
131         Sampler2D,
132         Sampler2DMS,
133         Sampler3D,
134         SamplerCube,
135         Sampler1DArray,
136         Sampler2DArray,
137         Sampler2DMSArray,
138         Sampler3DArray,
139         SamplerCubeArray,
140         SamplerRect,
141         SamplerBuffer,
142 
143         Image1D,
144         Image2D,
145         Image2DMS,
146         Image3D,
147         ImageCube,
148         Image1DArray,
149         Image2DArray,
150         Image2DMSArray,
151         Image3DArray,
152         ImageCubeArray,
153         ImageRect,
154         ImageBuffer,
155 
156         Struct
157     };
158 
159     enum ImageFormat {
160         // must match SPIR-V's ImageFormat
161         ImageFormatUnknown = 0,
162         ImageFormatRgba32f = 1,
163         ImageFormatRgba16f = 2,
164         ImageFormatR32f = 3,
165         ImageFormatRgba8 = 4,
166         ImageFormatRgba8Snorm = 5,
167         ImageFormatRg32f = 6,
168         ImageFormatRg16f = 7,
169         ImageFormatR11fG11fB10f = 8,
170         ImageFormatR16f = 9,
171         ImageFormatRgba16 = 10,
172         ImageFormatRgb10A2 = 11,
173         ImageFormatRg16 = 12,
174         ImageFormatRg8 = 13,
175         ImageFormatR16 = 14,
176         ImageFormatR8 = 15,
177         ImageFormatRgba16Snorm = 16,
178         ImageFormatRg16Snorm = 17,
179         ImageFormatRg8Snorm = 18,
180         ImageFormatR16Snorm = 19,
181         ImageFormatR8Snorm = 20,
182         ImageFormatRgba32i = 21,
183         ImageFormatRgba16i = 22,
184         ImageFormatRgba8i = 23,
185         ImageFormatR32i = 24,
186         ImageFormatRg32i = 25,
187         ImageFormatRg16i = 26,
188         ImageFormatRg8i = 27,
189         ImageFormatR16i = 28,
190         ImageFormatR8i = 29,
191         ImageFormatRgba32ui = 30,
192         ImageFormatRgba16ui = 31,
193         ImageFormatRgba8ui = 32,
194         ImageFormatR32ui = 33,
195         ImageFormatRgb10a2ui = 34,
196         ImageFormatRg32ui = 35,
197         ImageFormatRg16ui = 36,
198         ImageFormatRg8ui = 37,
199         ImageFormatR16ui = 38,
200         ImageFormatR8ui = 39
201     };
202 
203     enum ImageFlag {
204         ReadOnlyImage = 1 << 0,
205         WriteOnlyImage = 1 << 1
206     };
207     Q_DECLARE_FLAGS(ImageFlags, ImageFlag)
208 
209     // Optional data (like decorations) usually default to an otherwise invalid value (-1 or 0). This is intentional.
210 
211     struct InOutVariable {
212         QString name;
213         VariableType type = Unknown;
214         int location = -1;
215         int binding = -1;
216         int descriptorSet = -1;
217         ImageFormat imageFormat = ImageFormatUnknown;
218         ImageFlags imageFlags;
219         QVector<int> arrayDims;
220     };
221 
222     struct BlockVariable {
223         QString name;
224         VariableType type = Unknown;
225         int offset = 0;
226         int size = 0;
227         QVector<int> arrayDims;
228         int arrayStride = 0;
229         int matrixStride = 0;
230         bool matrixIsRowMajor = false;
231         QVector<BlockVariable> structMembers;
232     };
233 
234     struct UniformBlock {
235         QString blockName;
236         QString structName; // instanceName
237         int size = 0;
238         int binding = -1;
239         int descriptorSet = -1;
240         QVector<BlockVariable> members;
241     };
242 
243     struct PushConstantBlock {
244         QString name;
245         int size = 0;
246         QVector<BlockVariable> members;
247     };
248 
249     struct StorageBlock {
250         QString blockName;
251         QString instanceName;
252         int knownSize = 0;
253         int binding = -1;
254         int descriptorSet = -1;
255         QVector<BlockVariable> members;
256     };
257 
258     QVector<InOutVariable> inputVariables() const;
259     QVector<InOutVariable> outputVariables() const;
260     QVector<UniformBlock> uniformBlocks() const;
261     QVector<PushConstantBlock> pushConstantBlocks() const;
262     QVector<StorageBlock> storageBlocks() const;
263     QVector<InOutVariable> combinedImageSamplers() const;
264     QVector<InOutVariable> storageImages() const;
265 
266     std::array<uint, 3> computeShaderLocalSize() const;
267 
268 private:
269     QShaderDescriptionPrivate *d;
270     friend struct QShaderDescriptionPrivate;
271 #ifndef QT_NO_DEBUG_STREAM
272     friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription &);
273 #endif
274     friend Q_GUI_EXPORT bool operator==(const QShaderDescription &lhs, const QShaderDescription &rhs) Q_DECL_NOTHROW;
275 };
276 
277 Q_DECLARE_OPERATORS_FOR_FLAGS(QShaderDescription::ImageFlags)
278 
279 #ifndef QT_NO_DEBUG_STREAM
280 Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription &);
281 Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription::InOutVariable &);
282 Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription::BlockVariable &);
283 Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription::UniformBlock &);
284 Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription::PushConstantBlock &);
285 Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription::StorageBlock &);
286 #endif
287 
288 Q_GUI_EXPORT bool operator==(const QShaderDescription &lhs, const QShaderDescription &rhs) Q_DECL_NOTHROW;
289 Q_GUI_EXPORT bool operator==(const QShaderDescription::InOutVariable &lhs, const QShaderDescription::InOutVariable &rhs) Q_DECL_NOTHROW;
290 Q_GUI_EXPORT bool operator==(const QShaderDescription::BlockVariable &lhs, const QShaderDescription::BlockVariable &rhs) Q_DECL_NOTHROW;
291 Q_GUI_EXPORT bool operator==(const QShaderDescription::UniformBlock &lhs, const QShaderDescription::UniformBlock &rhs) Q_DECL_NOTHROW;
292 Q_GUI_EXPORT bool operator==(const QShaderDescription::PushConstantBlock &lhs, const QShaderDescription::PushConstantBlock &rhs) Q_DECL_NOTHROW;
293 Q_GUI_EXPORT bool operator==(const QShaderDescription::StorageBlock &lhs, const QShaderDescription::StorageBlock &rhs) Q_DECL_NOTHROW;
294 
295 inline bool operator!=(const QShaderDescription &lhs, const QShaderDescription &rhs) Q_DECL_NOTHROW
296 {
297     return !(lhs == rhs);
298 }
299 
300 inline bool operator!=(const QShaderDescription::InOutVariable &lhs, const QShaderDescription::InOutVariable &rhs) Q_DECL_NOTHROW
301 {
302     return !(lhs == rhs);
303 }
304 
305 inline bool operator!=(const QShaderDescription::BlockVariable &lhs, const QShaderDescription::BlockVariable &rhs) Q_DECL_NOTHROW
306 {
307     return !(lhs == rhs);
308 }
309 
310 inline bool operator!=(const QShaderDescription::UniformBlock &lhs, const QShaderDescription::UniformBlock &rhs) Q_DECL_NOTHROW
311 {
312     return !(lhs == rhs);
313 }
314 
315 inline bool operator!=(const QShaderDescription::PushConstantBlock &lhs, const QShaderDescription::PushConstantBlock &rhs) Q_DECL_NOTHROW
316 {
317     return !(lhs == rhs);
318 }
319 
320 inline bool operator!=(const QShaderDescription::StorageBlock &lhs, const QShaderDescription::StorageBlock &rhs) Q_DECL_NOTHROW
321 {
322     return !(lhs == rhs);
323 }
324 
325 QT_END_NAMESPACE
326 
327 #endif
328