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 QRHI_H
38 #define QRHI_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 purely as an
45 // implementation detail. This header file may change from version to
46 // version without notice, or even be removed.
47 //
48 // We mean it.
49 //
50
51 #include <QtGui/qtguiglobal.h>
52 #include <QSize>
53 #include <QMatrix4x4>
54 #include <QVector>
55 #include <QVarLengthArray>
56 #include <QThread>
57 #include <QColor>
58 #include <QImage>
59 #include <functional>
60 #include <array>
61 #include <private/qshader_p.h>
62
63 QT_BEGIN_NAMESPACE
64
65 class QWindow;
66 class QRhiImplementation;
67 class QRhiBuffer;
68 class QRhiRenderBuffer;
69 class QRhiTexture;
70 class QRhiSampler;
71 class QRhiCommandBuffer;
72 class QRhiResourceUpdateBatch;
73 class QRhiResourceUpdateBatchPrivate;
74 class QRhiProfiler;
75
76 class Q_GUI_EXPORT QRhiDepthStencilClearValue
77 {
78 public:
79 QRhiDepthStencilClearValue() = default;
80 QRhiDepthStencilClearValue(float d, quint32 s);
81
depthClearValue()82 float depthClearValue() const { return m_d; }
setDepthClearValue(float d)83 void setDepthClearValue(float d) { m_d = d; }
84
stencilClearValue()85 quint32 stencilClearValue() const { return m_s; }
setStencilClearValue(quint32 s)86 void setStencilClearValue(quint32 s) { m_s = s; }
87
88 private:
89 float m_d = 1.0f;
90 quint32 m_s = 0;
91 };
92
93 Q_DECLARE_TYPEINFO(QRhiDepthStencilClearValue, Q_MOVABLE_TYPE);
94
95 Q_GUI_EXPORT bool operator==(const QRhiDepthStencilClearValue &a, const QRhiDepthStencilClearValue &b) Q_DECL_NOTHROW;
96 Q_GUI_EXPORT bool operator!=(const QRhiDepthStencilClearValue &a, const QRhiDepthStencilClearValue &b) Q_DECL_NOTHROW;
97 Q_GUI_EXPORT uint qHash(const QRhiDepthStencilClearValue &v, uint seed = 0) Q_DECL_NOTHROW;
98 #ifndef QT_NO_DEBUG_STREAM
99 Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiDepthStencilClearValue &);
100 #endif
101
102 class Q_GUI_EXPORT QRhiViewport
103 {
104 public:
105 QRhiViewport() = default;
106 QRhiViewport(float x, float y, float w, float h, float minDepth = 0.0f, float maxDepth = 1.0f);
107
viewport()108 std::array<float, 4> viewport() const { return m_rect; }
setViewport(float x,float y,float w,float h)109 void setViewport(float x, float y, float w, float h) {
110 m_rect[0] = x; m_rect[1] = y; m_rect[2] = w; m_rect[3] = h;
111 }
112
minDepth()113 float minDepth() const { return m_minDepth; }
setMinDepth(float minDepth)114 void setMinDepth(float minDepth) { m_minDepth = minDepth; }
115
maxDepth()116 float maxDepth() const { return m_maxDepth; }
setMaxDepth(float maxDepth)117 void setMaxDepth(float maxDepth) { m_maxDepth = maxDepth; }
118
119 private:
120 std::array<float, 4> m_rect { { 0.0f, 0.0f, 0.0f, 0.0f } };
121 float m_minDepth = 0.0f;
122 float m_maxDepth = 1.0f;
123 };
124
125 Q_DECLARE_TYPEINFO(QRhiViewport, Q_MOVABLE_TYPE);
126
127 Q_GUI_EXPORT bool operator==(const QRhiViewport &a, const QRhiViewport &b) Q_DECL_NOTHROW;
128 Q_GUI_EXPORT bool operator!=(const QRhiViewport &a, const QRhiViewport &b) Q_DECL_NOTHROW;
129 Q_GUI_EXPORT uint qHash(const QRhiViewport &v, uint seed = 0) Q_DECL_NOTHROW;
130 #ifndef QT_NO_DEBUG_STREAM
131 Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiViewport &);
132 #endif
133
134 class Q_GUI_EXPORT QRhiScissor
135 {
136 public:
137 QRhiScissor() = default;
138 QRhiScissor(int x, int y, int w, int h);
139
scissor()140 std::array<int, 4> scissor() const { return m_rect; }
setScissor(int x,int y,int w,int h)141 void setScissor(int x, int y, int w, int h) {
142 m_rect[0] = x; m_rect[1] = y; m_rect[2] = w; m_rect[3] = h;
143 }
144
145 private:
146 std::array<int, 4> m_rect { { 0, 0, 0, 0 } };
147 };
148
149 Q_DECLARE_TYPEINFO(QRhiScissor, Q_MOVABLE_TYPE);
150
151 Q_GUI_EXPORT bool operator==(const QRhiScissor &a, const QRhiScissor &b) Q_DECL_NOTHROW;
152 Q_GUI_EXPORT bool operator!=(const QRhiScissor &a, const QRhiScissor &b) Q_DECL_NOTHROW;
153 Q_GUI_EXPORT uint qHash(const QRhiScissor &v, uint seed = 0) Q_DECL_NOTHROW;
154 #ifndef QT_NO_DEBUG_STREAM
155 Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiScissor &);
156 #endif
157
158 class Q_GUI_EXPORT QRhiVertexInputBinding
159 {
160 public:
161 enum Classification {
162 PerVertex,
163 PerInstance
164 };
165
166 QRhiVertexInputBinding() = default;
167 QRhiVertexInputBinding(quint32 stride, Classification cls = PerVertex, int stepRate = 1);
168
stride()169 quint32 stride() const { return m_stride; }
setStride(quint32 s)170 void setStride(quint32 s) { m_stride = s; }
171
classification()172 Classification classification() const { return m_classification; }
setClassification(Classification c)173 void setClassification(Classification c) { m_classification = c; }
174
instanceStepRate()175 int instanceStepRate() const { return m_instanceStepRate; }
setInstanceStepRate(int rate)176 void setInstanceStepRate(int rate) { m_instanceStepRate = rate; }
177
178 private:
179 quint32 m_stride = 0;
180 Classification m_classification = PerVertex;
181 int m_instanceStepRate = 1;
182 };
183
184 Q_DECLARE_TYPEINFO(QRhiVertexInputBinding, Q_MOVABLE_TYPE);
185
186 Q_GUI_EXPORT bool operator==(const QRhiVertexInputBinding &a, const QRhiVertexInputBinding &b) Q_DECL_NOTHROW;
187 Q_GUI_EXPORT bool operator!=(const QRhiVertexInputBinding &a, const QRhiVertexInputBinding &b) Q_DECL_NOTHROW;
188 Q_GUI_EXPORT uint qHash(const QRhiVertexInputBinding &v, uint seed = 0) Q_DECL_NOTHROW;
189 #ifndef QT_NO_DEBUG_STREAM
190 Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiVertexInputBinding &);
191 #endif
192
193 class Q_GUI_EXPORT QRhiVertexInputAttribute
194 {
195 public:
196 enum Format {
197 Float4,
198 Float3,
199 Float2,
200 Float,
201 UNormByte4,
202 UNormByte2,
203 UNormByte
204 };
205
206 QRhiVertexInputAttribute() = default;
207 QRhiVertexInputAttribute(int binding, int location, Format format, quint32 offset);
208
binding()209 int binding() const { return m_binding; }
setBinding(int b)210 void setBinding(int b) { m_binding = b; }
211
location()212 int location() const { return m_location; }
setLocation(int loc)213 void setLocation(int loc) { m_location = loc; }
214
format()215 Format format() const { return m_format; }
setFormt(Format f)216 void setFormt(Format f) { m_format = f; }
217
offset()218 quint32 offset() const { return m_offset; }
setOffset(quint32 ofs)219 void setOffset(quint32 ofs) { m_offset = ofs; }
220
221 private:
222 int m_binding = 0;
223 int m_location = 0;
224 Format m_format = Float4;
225 quint32 m_offset = 0;
226 };
227
228 Q_DECLARE_TYPEINFO(QRhiVertexInputAttribute, Q_MOVABLE_TYPE);
229
230 Q_GUI_EXPORT bool operator==(const QRhiVertexInputAttribute &a, const QRhiVertexInputAttribute &b) Q_DECL_NOTHROW;
231 Q_GUI_EXPORT bool operator!=(const QRhiVertexInputAttribute &a, const QRhiVertexInputAttribute &b) Q_DECL_NOTHROW;
232 Q_GUI_EXPORT uint qHash(const QRhiVertexInputAttribute &v, uint seed = 0) Q_DECL_NOTHROW;
233 #ifndef QT_NO_DEBUG_STREAM
234 Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiVertexInputAttribute &);
235 #endif
236
237 class Q_GUI_EXPORT QRhiVertexInputLayout
238 {
239 public:
240 QRhiVertexInputLayout() = default;
241
setBindings(std::initializer_list<QRhiVertexInputBinding> list)242 void setBindings(std::initializer_list<QRhiVertexInputBinding> list) { m_bindings = list; }
243 template<typename InputIterator>
setBindings(InputIterator first,InputIterator last)244 void setBindings(InputIterator first, InputIterator last)
245 {
246 m_bindings.clear();
247 std::copy(first, last, std::back_inserter(m_bindings));
248 }
cbeginBindings()249 const QRhiVertexInputBinding *cbeginBindings() const { return m_bindings.cbegin(); }
cendBindings()250 const QRhiVertexInputBinding *cendBindings() const { return m_bindings.cend(); }
bindingAt(int index)251 const QRhiVertexInputBinding *bindingAt(int index) const { return &m_bindings.at(index); }
252
setAttributes(std::initializer_list<QRhiVertexInputAttribute> list)253 void setAttributes(std::initializer_list<QRhiVertexInputAttribute> list) { m_attributes = list; }
254 template<typename InputIterator>
setAttributes(InputIterator first,InputIterator last)255 void setAttributes(InputIterator first, InputIterator last)
256 {
257 m_attributes.clear();
258 std::copy(first, last, std::back_inserter(m_attributes));
259 }
cbeginAttributes()260 const QRhiVertexInputAttribute *cbeginAttributes() const { return m_attributes.cbegin(); }
cendAttributes()261 const QRhiVertexInputAttribute *cendAttributes() const { return m_attributes.cend(); }
262
263 private:
264 QVarLengthArray<QRhiVertexInputBinding, 8> m_bindings;
265 QVarLengthArray<QRhiVertexInputAttribute, 8> m_attributes;
266
267 friend Q_GUI_EXPORT bool operator==(const QRhiVertexInputLayout &a, const QRhiVertexInputLayout &b) Q_DECL_NOTHROW;
268 friend Q_GUI_EXPORT uint qHash(const QRhiVertexInputLayout &v, uint seed) Q_DECL_NOTHROW;
269 friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiVertexInputLayout &);
270 };
271
272 Q_DECLARE_TYPEINFO(QRhiVertexInputLayout, Q_MOVABLE_TYPE);
273
274 Q_GUI_EXPORT bool operator==(const QRhiVertexInputLayout &a, const QRhiVertexInputLayout &b) Q_DECL_NOTHROW;
275 Q_GUI_EXPORT bool operator!=(const QRhiVertexInputLayout &a, const QRhiVertexInputLayout &b) Q_DECL_NOTHROW;
276 Q_GUI_EXPORT uint qHash(const QRhiVertexInputLayout &v, uint seed = 0) Q_DECL_NOTHROW;
277 #ifndef QT_NO_DEBUG_STREAM
278 Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiVertexInputLayout &);
279 #endif
280
281 class Q_GUI_EXPORT QRhiShaderStage
282 {
283 public:
284 enum Type {
285 Vertex,
286 Fragment,
287 Compute
288 };
289
290 QRhiShaderStage() = default;
291 QRhiShaderStage(Type type, const QShader &shader,
292 QShader::Variant v = QShader::StandardShader);
293
type()294 Type type() const { return m_type; }
setType(Type t)295 void setType(Type t) { m_type = t; }
296
shader()297 QShader shader() const { return m_shader; }
setShader(const QShader & s)298 void setShader(const QShader &s) { m_shader = s; }
299
shaderVariant()300 QShader::Variant shaderVariant() const { return m_shaderVariant; }
setShaderVariant(QShader::Variant v)301 void setShaderVariant(QShader::Variant v) { m_shaderVariant = v; }
302
303 private:
304 Type m_type = Vertex;
305 QShader m_shader;
306 QShader::Variant m_shaderVariant = QShader::StandardShader;
307 };
308
309 Q_DECLARE_TYPEINFO(QRhiShaderStage, Q_MOVABLE_TYPE);
310
311 Q_GUI_EXPORT bool operator==(const QRhiShaderStage &a, const QRhiShaderStage &b) Q_DECL_NOTHROW;
312 Q_GUI_EXPORT bool operator!=(const QRhiShaderStage &a, const QRhiShaderStage &b) Q_DECL_NOTHROW;
313 Q_GUI_EXPORT uint qHash(const QRhiShaderStage &s, uint seed = 0) Q_DECL_NOTHROW;
314 #ifndef QT_NO_DEBUG_STREAM
315 Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderStage &);
316 #endif
317
318 using QRhiGraphicsShaderStage = QRhiShaderStage;
319
320 class Q_GUI_EXPORT QRhiShaderResourceBinding
321 {
322 public:
323 enum Type {
324 UniformBuffer,
325 SampledTexture,
326 ImageLoad,
327 ImageStore,
328 ImageLoadStore,
329 BufferLoad,
330 BufferStore,
331 BufferLoadStore
332 };
333
334 enum StageFlag {
335 VertexStage = 1 << 0,
336 FragmentStage = 1 << 1,
337 ComputeStage = 1 << 2
338 };
339 Q_DECLARE_FLAGS(StageFlags, StageFlag)
340
341 QRhiShaderResourceBinding();
342
343 bool isLayoutCompatible(const QRhiShaderResourceBinding &other) const;
344
345 static QRhiShaderResourceBinding uniformBuffer(int binding, StageFlags stage, QRhiBuffer *buf);
346 static QRhiShaderResourceBinding uniformBuffer(int binding, StageFlags stage, QRhiBuffer *buf, int offset, int size);
347 static QRhiShaderResourceBinding uniformBufferWithDynamicOffset(int binding, StageFlags stage, QRhiBuffer *buf, int size);
348
349 static QRhiShaderResourceBinding sampledTexture(int binding, StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler);
350
351 struct TextureAndSampler {
352 QRhiTexture *tex;
353 QRhiSampler *sampler;
354 };
355 static QRhiShaderResourceBinding sampledTextures(int binding, StageFlags stage, int count, const TextureAndSampler *texSamplers);
356
357 static QRhiShaderResourceBinding imageLoad(int binding, StageFlags stage, QRhiTexture *tex, int level);
358 static QRhiShaderResourceBinding imageStore(int binding, StageFlags stage, QRhiTexture *tex, int level);
359 static QRhiShaderResourceBinding imageLoadStore(int binding, StageFlags stage, QRhiTexture *tex, int level);
360
361 static QRhiShaderResourceBinding bufferLoad(int binding, StageFlags stage, QRhiBuffer *buf);
362 static QRhiShaderResourceBinding bufferLoad(int binding, StageFlags stage, QRhiBuffer *buf, int offset, int size);
363 static QRhiShaderResourceBinding bufferStore(int binding, StageFlags stage, QRhiBuffer *buf);
364 static QRhiShaderResourceBinding bufferStore(int binding, StageFlags stage, QRhiBuffer *buf, int offset, int size);
365 static QRhiShaderResourceBinding bufferLoadStore(int binding, StageFlags stage, QRhiBuffer *buf);
366 static QRhiShaderResourceBinding bufferLoadStore(int binding, StageFlags stage, QRhiBuffer *buf, int offset, int size);
367
368 struct Data
369 {
370 int binding;
371 QRhiShaderResourceBinding::StageFlags stage;
372 QRhiShaderResourceBinding::Type type;
373 struct UniformBufferData {
374 QRhiBuffer *buf;
375 int offset;
376 int maybeSize;
377 bool hasDynamicOffset;
378 };
379 static const int MAX_TEX_SAMPLER_ARRAY_SIZE = 16;
380 struct SampledTextureData {
381 int count;
382 TextureAndSampler texSamplers[MAX_TEX_SAMPLER_ARRAY_SIZE];
383 };
384 struct StorageImageData {
385 QRhiTexture *tex;
386 int level;
387 };
388 struct StorageBufferData {
389 QRhiBuffer *buf;
390 int offset;
391 int maybeSize;
392 };
393 union {
394 UniformBufferData ubuf;
395 SampledTextureData stex;
396 StorageImageData simage;
397 StorageBufferData sbuf;
398 } u;
399 };
400
data()401 Data *data() { return &d; }
data()402 const Data *data() const { return &d; }
403
404 private:
405 Data d;
406 };
407
408 Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiShaderResourceBinding::StageFlags)
409
410 Q_DECLARE_TYPEINFO(QRhiShaderResourceBinding, Q_MOVABLE_TYPE);
411
412 Q_GUI_EXPORT bool operator==(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) Q_DECL_NOTHROW;
413 Q_GUI_EXPORT bool operator!=(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) Q_DECL_NOTHROW;
414 Q_GUI_EXPORT uint qHash(const QRhiShaderResourceBinding &b, uint seed = 0) Q_DECL_NOTHROW;
415 #ifndef QT_NO_DEBUG_STREAM
416 Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderResourceBinding &);
417 #endif
418
419 class Q_GUI_EXPORT QRhiColorAttachment
420 {
421 public:
422 QRhiColorAttachment() = default;
423 QRhiColorAttachment(QRhiTexture *texture);
424 QRhiColorAttachment(QRhiRenderBuffer *renderBuffer);
425
texture()426 QRhiTexture *texture() const { return m_texture; }
setTexture(QRhiTexture * tex)427 void setTexture(QRhiTexture *tex) { m_texture = tex; }
428
renderBuffer()429 QRhiRenderBuffer *renderBuffer() const { return m_renderBuffer; }
setRenderBuffer(QRhiRenderBuffer * rb)430 void setRenderBuffer(QRhiRenderBuffer *rb) { m_renderBuffer = rb; }
431
layer()432 int layer() const { return m_layer; }
setLayer(int layer)433 void setLayer(int layer) { m_layer = layer; }
434
level()435 int level() const { return m_level; }
setLevel(int level)436 void setLevel(int level) { m_level = level; }
437
resolveTexture()438 QRhiTexture *resolveTexture() const { return m_resolveTexture; }
setResolveTexture(QRhiTexture * tex)439 void setResolveTexture(QRhiTexture *tex) { m_resolveTexture = tex; }
440
resolveLayer()441 int resolveLayer() const { return m_resolveLayer; }
setResolveLayer(int layer)442 void setResolveLayer(int layer) { m_resolveLayer = layer; }
443
resolveLevel()444 int resolveLevel() const { return m_resolveLevel; }
setResolveLevel(int level)445 void setResolveLevel(int level) { m_resolveLevel = level; }
446
447 private:
448 QRhiTexture *m_texture = nullptr;
449 QRhiRenderBuffer *m_renderBuffer = nullptr;
450 int m_layer = 0;
451 int m_level = 0;
452 QRhiTexture *m_resolveTexture = nullptr;
453 int m_resolveLayer = 0;
454 int m_resolveLevel = 0;
455 };
456
457 Q_DECLARE_TYPEINFO(QRhiColorAttachment, Q_MOVABLE_TYPE);
458
459 class Q_GUI_EXPORT QRhiTextureRenderTargetDescription
460 {
461 public:
462 QRhiTextureRenderTargetDescription() = default;
463 QRhiTextureRenderTargetDescription(const QRhiColorAttachment &colorAttachment);
464 QRhiTextureRenderTargetDescription(const QRhiColorAttachment &colorAttachment, QRhiRenderBuffer *depthStencilBuffer);
465 QRhiTextureRenderTargetDescription(const QRhiColorAttachment &colorAttachment, QRhiTexture *depthTexture);
466
setColorAttachments(std::initializer_list<QRhiColorAttachment> list)467 void setColorAttachments(std::initializer_list<QRhiColorAttachment> list) { m_colorAttachments = list; }
468 template<typename InputIterator>
setColorAttachments(InputIterator first,InputIterator last)469 void setColorAttachments(InputIterator first, InputIterator last)
470 {
471 m_colorAttachments.clear();
472 std::copy(first, last, std::back_inserter(m_colorAttachments));
473 }
cbeginColorAttachments()474 const QRhiColorAttachment *cbeginColorAttachments() const { return m_colorAttachments.cbegin(); }
cendColorAttachments()475 const QRhiColorAttachment *cendColorAttachments() const { return m_colorAttachments.cend(); }
colorAttachmentAt(int index)476 const QRhiColorAttachment *colorAttachmentAt(int index) const { return &m_colorAttachments.at(index); }
477
depthStencilBuffer()478 QRhiRenderBuffer *depthStencilBuffer() const { return m_depthStencilBuffer; }
setDepthStencilBuffer(QRhiRenderBuffer * renderBuffer)479 void setDepthStencilBuffer(QRhiRenderBuffer *renderBuffer) { m_depthStencilBuffer = renderBuffer; }
480
depthTexture()481 QRhiTexture *depthTexture() const { return m_depthTexture; }
setDepthTexture(QRhiTexture * texture)482 void setDepthTexture(QRhiTexture *texture) { m_depthTexture = texture; }
483
484 private:
485 QVarLengthArray<QRhiColorAttachment, 8> m_colorAttachments;
486 QRhiRenderBuffer *m_depthStencilBuffer = nullptr;
487 QRhiTexture *m_depthTexture = nullptr;
488 };
489
490 Q_DECLARE_TYPEINFO(QRhiTextureRenderTargetDescription, Q_MOVABLE_TYPE);
491
492 class Q_GUI_EXPORT QRhiTextureSubresourceUploadDescription
493 {
494 public:
495 QRhiTextureSubresourceUploadDescription() = default;
496 QRhiTextureSubresourceUploadDescription(const QImage &image);
497 QRhiTextureSubresourceUploadDescription(const void *data, int size);
498
image()499 QImage image() const { return m_image; }
setImage(const QImage & image)500 void setImage(const QImage &image) { m_image = image; }
501
data()502 QByteArray data() const { return m_data; }
setData(const QByteArray & data)503 void setData(const QByteArray &data) { m_data = data; }
504
destinationTopLeft()505 QPoint destinationTopLeft() const { return m_destinationTopLeft; }
setDestinationTopLeft(const QPoint & p)506 void setDestinationTopLeft(const QPoint &p) { m_destinationTopLeft = p; }
507
sourceSize()508 QSize sourceSize() const { return m_sourceSize; }
setSourceSize(const QSize & size)509 void setSourceSize(const QSize &size) { m_sourceSize = size; }
510
sourceTopLeft()511 QPoint sourceTopLeft() const { return m_sourceTopLeft; }
setSourceTopLeft(const QPoint & p)512 void setSourceTopLeft(const QPoint &p) { m_sourceTopLeft = p; }
513
514 private:
515 QImage m_image;
516 QByteArray m_data;
517 QPoint m_destinationTopLeft;
518 QSize m_sourceSize;
519 QPoint m_sourceTopLeft;
520 };
521
522 Q_DECLARE_TYPEINFO(QRhiTextureSubresourceUploadDescription, Q_MOVABLE_TYPE);
523
524 class Q_GUI_EXPORT QRhiTextureUploadEntry
525 {
526 public:
527 QRhiTextureUploadEntry() = default;
528 QRhiTextureUploadEntry(int layer, int level, const QRhiTextureSubresourceUploadDescription &desc);
529
layer()530 int layer() const { return m_layer; }
setLayer(int layer)531 void setLayer(int layer) { m_layer = layer; }
532
level()533 int level() const { return m_level; }
setLevel(int level)534 void setLevel(int level) { m_level = level; }
535
description()536 QRhiTextureSubresourceUploadDescription description() const { return m_desc; }
setDescription(const QRhiTextureSubresourceUploadDescription & desc)537 void setDescription(const QRhiTextureSubresourceUploadDescription &desc) { m_desc = desc; }
538
539 private:
540 int m_layer = 0;
541 int m_level = 0;
542 QRhiTextureSubresourceUploadDescription m_desc;
543 };
544
545 Q_DECLARE_TYPEINFO(QRhiTextureUploadEntry, Q_MOVABLE_TYPE);
546
547 class Q_GUI_EXPORT QRhiTextureUploadDescription
548 {
549 public:
550 QRhiTextureUploadDescription() = default;
551 QRhiTextureUploadDescription(const QRhiTextureUploadEntry &entry);
552 QRhiTextureUploadDescription(std::initializer_list<QRhiTextureUploadEntry> list);
553
setEntries(std::initializer_list<QRhiTextureUploadEntry> list)554 void setEntries(std::initializer_list<QRhiTextureUploadEntry> list) { m_entries = list; }
555 template<typename InputIterator>
setEntries(InputIterator first,InputIterator last)556 void setEntries(InputIterator first, InputIterator last)
557 {
558 m_entries.clear();
559 std::copy(first, last, std::back_inserter(m_entries));
560 }
cbeginEntries()561 const QRhiTextureUploadEntry *cbeginEntries() const { return m_entries.cbegin(); }
cendEntries()562 const QRhiTextureUploadEntry *cendEntries() const { return m_entries.cend(); }
563
564 private:
565 QVarLengthArray<QRhiTextureUploadEntry, 16> m_entries;
566 };
567
568 Q_DECLARE_TYPEINFO(QRhiTextureUploadDescription, Q_MOVABLE_TYPE);
569
570 class Q_GUI_EXPORT QRhiTextureCopyDescription
571 {
572 public:
573 QRhiTextureCopyDescription() = default;
574
pixelSize()575 QSize pixelSize() const { return m_pixelSize; }
setPixelSize(const QSize & sz)576 void setPixelSize(const QSize &sz) { m_pixelSize = sz; }
577
sourceLayer()578 int sourceLayer() const { return m_sourceLayer; }
setSourceLayer(int layer)579 void setSourceLayer(int layer) { m_sourceLayer = layer; }
580
sourceLevel()581 int sourceLevel() const { return m_sourceLevel; }
setSourceLevel(int level)582 void setSourceLevel(int level) { m_sourceLevel = level; }
583
sourceTopLeft()584 QPoint sourceTopLeft() const { return m_sourceTopLeft; }
setSourceTopLeft(const QPoint & p)585 void setSourceTopLeft(const QPoint &p) { m_sourceTopLeft = p; }
586
destinationLayer()587 int destinationLayer() const { return m_destinationLayer; }
setDestinationLayer(int layer)588 void setDestinationLayer(int layer) { m_destinationLayer = layer; }
589
destinationLevel()590 int destinationLevel() const { return m_destinationLevel; }
setDestinationLevel(int level)591 void setDestinationLevel(int level) { m_destinationLevel = level; }
592
destinationTopLeft()593 QPoint destinationTopLeft() const { return m_destinationTopLeft; }
setDestinationTopLeft(const QPoint & p)594 void setDestinationTopLeft(const QPoint &p) { m_destinationTopLeft = p; }
595
596 private:
597 QSize m_pixelSize;
598 int m_sourceLayer = 0;
599 int m_sourceLevel = 0;
600 QPoint m_sourceTopLeft;
601 int m_destinationLayer = 0;
602 int m_destinationLevel = 0;
603 QPoint m_destinationTopLeft;
604 };
605
606 Q_DECLARE_TYPEINFO(QRhiTextureCopyDescription, Q_MOVABLE_TYPE);
607
608 class Q_GUI_EXPORT QRhiReadbackDescription
609 {
610 public:
611 QRhiReadbackDescription() = default;
612 QRhiReadbackDescription(QRhiTexture *texture);
613
texture()614 QRhiTexture *texture() const { return m_texture; }
setTexture(QRhiTexture * tex)615 void setTexture(QRhiTexture *tex) { m_texture = tex; }
616
layer()617 int layer() const { return m_layer; }
setLayer(int layer)618 void setLayer(int layer) { m_layer = layer; }
619
level()620 int level() const { return m_level; }
setLevel(int level)621 void setLevel(int level) { m_level = level; }
622
623 private:
624 QRhiTexture *m_texture = nullptr;
625 int m_layer = 0;
626 int m_level = 0;
627 };
628
629 Q_DECLARE_TYPEINFO(QRhiReadbackDescription, Q_MOVABLE_TYPE);
630
631 struct Q_GUI_EXPORT QRhiNativeHandles
632 {
633 };
634
635 class Q_GUI_EXPORT QRhiResource
636 {
637 public:
638 enum Type {
639 Buffer,
640 Texture,
641 Sampler,
642 RenderBuffer,
643 RenderPassDescriptor,
644 RenderTarget,
645 TextureRenderTarget,
646 ShaderResourceBindings,
647 GraphicsPipeline,
648 SwapChain,
649 ComputePipeline,
650 CommandBuffer
651 };
652
653 virtual ~QRhiResource();
654
655 virtual Type resourceType() const = 0;
656
657 virtual void release() = 0;
658 void releaseAndDestroyLater();
659
660 QByteArray name() const;
661 void setName(const QByteArray &name);
662
663 quint64 globalResourceId() const;
664
665 protected:
666 QRhiResource(QRhiImplementation *rhi);
667 Q_DISABLE_COPY(QRhiResource)
668 friend class QRhiImplementation;
669 QRhiImplementation *m_rhi = nullptr;
670 quint64 m_id;
671 QByteArray m_objectName;
672 };
673
674 class Q_GUI_EXPORT QRhiBuffer : public QRhiResource
675 {
676 public:
677 enum Type {
678 Immutable,
679 Static,
680 Dynamic
681 };
682
683 enum UsageFlag {
684 VertexBuffer = 1 << 0,
685 IndexBuffer = 1 << 1,
686 UniformBuffer = 1 << 2,
687 StorageBuffer = 1 << 3
688 };
689 Q_DECLARE_FLAGS(UsageFlags, UsageFlag)
690
691 struct NativeBuffer {
692 const void *objects[3];
693 int slotCount;
694 };
695
696 QRhiResource::Type resourceType() const override;
697
type()698 Type type() const { return m_type; }
setType(Type t)699 void setType(Type t) { m_type = t; }
700
usage()701 UsageFlags usage() const { return m_usage; }
setUsage(UsageFlags u)702 void setUsage(UsageFlags u) { m_usage = u; }
703
size()704 int size() const { return m_size; }
setSize(int sz)705 void setSize(int sz) { m_size = sz; }
706
707 virtual bool build() = 0;
708
709 virtual NativeBuffer nativeBuffer();
710
711 protected:
712 QRhiBuffer(QRhiImplementation *rhi, Type type_, UsageFlags usage_, int size_);
713 Type m_type;
714 UsageFlags m_usage;
715 int m_size;
716 };
717
Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiBuffer::UsageFlags)718 Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiBuffer::UsageFlags)
719
720 class Q_GUI_EXPORT QRhiTexture : public QRhiResource
721 {
722 public:
723 enum Flag {
724 RenderTarget = 1 << 0,
725 CubeMap = 1 << 2,
726 MipMapped = 1 << 3,
727 sRGB = 1 << 4,
728 UsedAsTransferSource = 1 << 5,
729 UsedWithGenerateMips = 1 << 6,
730 UsedWithLoadStore = 1 << 7
731 };
732 Q_DECLARE_FLAGS(Flags, Flag)
733
734 enum Format {
735 UnknownFormat,
736
737 RGBA8,
738 BGRA8,
739 R8,
740 R16,
741 RED_OR_ALPHA8,
742
743 RGBA16F,
744 RGBA32F,
745 R16F,
746 R32F,
747
748 D16,
749 D32F,
750
751 BC1,
752 BC2,
753 BC3,
754 BC4,
755 BC5,
756 BC6H,
757 BC7,
758
759 ETC2_RGB8,
760 ETC2_RGB8A1,
761 ETC2_RGBA8,
762
763 ASTC_4x4,
764 ASTC_5x4,
765 ASTC_5x5,
766 ASTC_6x5,
767 ASTC_6x6,
768 ASTC_8x5,
769 ASTC_8x6,
770 ASTC_8x8,
771 ASTC_10x5,
772 ASTC_10x6,
773 ASTC_10x8,
774 ASTC_10x10,
775 ASTC_12x10,
776 ASTC_12x12
777 };
778
779 struct NativeTexture {
780 const void *object;
781 int layout;
782 };
783
784 QRhiResource::Type resourceType() const override;
785
786 Format format() const { return m_format; }
787 void setFormat(Format fmt) { m_format = fmt; }
788
789 QSize pixelSize() const { return m_pixelSize; }
790 void setPixelSize(const QSize &sz) { m_pixelSize = sz; }
791
792 Flags flags() const { return m_flags; }
793 void setFlags(Flags f) { m_flags = f; }
794
795 int sampleCount() const { return m_sampleCount; }
796 void setSampleCount(int s) { m_sampleCount = s; }
797
798 virtual bool build() = 0;
799 virtual NativeTexture nativeTexture();
800 virtual bool buildFrom(NativeTexture src);
801 virtual void setNativeLayout(int layout);
802
803 protected:
804 QRhiTexture(QRhiImplementation *rhi, Format format_, const QSize &pixelSize_,
805 int sampleCount_, Flags flags_);
806 Format m_format;
807 QSize m_pixelSize;
808 int m_sampleCount;
809 Flags m_flags;
810 };
811
Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiTexture::Flags)812 Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiTexture::Flags)
813
814 class Q_GUI_EXPORT QRhiSampler : public QRhiResource
815 {
816 public:
817 enum Filter {
818 None,
819 Nearest,
820 Linear
821 };
822
823 enum AddressMode {
824 Repeat,
825 ClampToEdge,
826 Mirror,
827 };
828
829 enum CompareOp {
830 Never,
831 Less,
832 Equal,
833 LessOrEqual,
834 Greater,
835 NotEqual,
836 GreaterOrEqual,
837 Always
838 };
839
840 QRhiResource::Type resourceType() const override;
841
842 Filter magFilter() const { return m_magFilter; }
843 void setMagFilter(Filter f) { m_magFilter = f; }
844
845 Filter minFilter() const { return m_minFilter; }
846 void setMinFilter(Filter f) { m_minFilter = f; }
847
848 Filter mipmapMode() const { return m_mipmapMode; }
849 void setMipmapMode(Filter f) { m_mipmapMode = f; }
850
851 AddressMode addressU() const { return m_addressU; }
852 void setAddressU(AddressMode mode) { m_addressU = mode; }
853
854 AddressMode addressV() const { return m_addressV; }
855 void setAddressV(AddressMode mode) { m_addressV = mode; }
856
857 AddressMode addressW() const { return m_addressW; }
858 void setAddressW(AddressMode mode) { m_addressW = mode; }
859
860 CompareOp textureCompareOp() const { return m_compareOp; }
861 void setTextureCompareOp(CompareOp op) { m_compareOp = op; }
862
863 virtual bool build() = 0;
864
865 protected:
866 QRhiSampler(QRhiImplementation *rhi,
867 Filter magFilter_, Filter minFilter_, Filter mipmapMode_,
868 AddressMode u_, AddressMode v_, AddressMode w_);
869 Filter m_magFilter;
870 Filter m_minFilter;
871 Filter m_mipmapMode;
872 AddressMode m_addressU;
873 AddressMode m_addressV;
874 AddressMode m_addressW;
875 CompareOp m_compareOp;
876 };
877
878 class Q_GUI_EXPORT QRhiRenderBuffer : public QRhiResource
879 {
880 public:
881 enum Type {
882 DepthStencil,
883 Color
884 };
885
886 enum Flag {
887 UsedWithSwapChainOnly = 1 << 0
888 };
889 Q_DECLARE_FLAGS(Flags, Flag)
890
891 QRhiResource::Type resourceType() const override;
892
type()893 Type type() const { return m_type; }
setType(Type t)894 void setType(Type t) { m_type = t; }
895
pixelSize()896 QSize pixelSize() const { return m_pixelSize; }
setPixelSize(const QSize & sz)897 void setPixelSize(const QSize &sz) { m_pixelSize = sz; }
898
sampleCount()899 int sampleCount() const { return m_sampleCount; }
setSampleCount(int s)900 void setSampleCount(int s) { m_sampleCount = s; }
901
flags()902 Flags flags() const { return m_flags; }
setFlags(Flags h)903 void setFlags(Flags h) { m_flags = h; }
904
905 virtual bool build() = 0;
906
907 virtual QRhiTexture::Format backingFormat() const = 0;
908
909 protected:
910 QRhiRenderBuffer(QRhiImplementation *rhi, Type type_, const QSize &pixelSize_,
911 int sampleCount_, Flags flags_);
912 Type m_type;
913 QSize m_pixelSize;
914 int m_sampleCount;
915 Flags m_flags;
916 };
917
Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiRenderBuffer::Flags)918 Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiRenderBuffer::Flags)
919
920 class Q_GUI_EXPORT QRhiRenderPassDescriptor : public QRhiResource
921 {
922 public:
923 QRhiResource::Type resourceType() const override;
924
925 virtual bool isCompatible(const QRhiRenderPassDescriptor *other) const = 0;
926 virtual const QRhiNativeHandles *nativeHandles();
927
928 protected:
929 QRhiRenderPassDescriptor(QRhiImplementation *rhi);
930 };
931
932 class Q_GUI_EXPORT QRhiRenderTarget : public QRhiResource
933 {
934 public:
935 QRhiResource::Type resourceType() const override;
936
937 virtual QSize pixelSize() const = 0;
938 virtual float devicePixelRatio() const = 0;
939 virtual int sampleCount() const = 0;
940
renderPassDescriptor()941 QRhiRenderPassDescriptor *renderPassDescriptor() const { return m_renderPassDesc; }
setRenderPassDescriptor(QRhiRenderPassDescriptor * desc)942 void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc) { m_renderPassDesc = desc; }
943
944 protected:
945 QRhiRenderTarget(QRhiImplementation *rhi);
946 QRhiRenderPassDescriptor *m_renderPassDesc = nullptr;
947 };
948
949 class Q_GUI_EXPORT QRhiTextureRenderTarget : public QRhiRenderTarget
950 {
951 public:
952 enum Flag {
953 PreserveColorContents = 1 << 0,
954 PreserveDepthStencilContents = 1 << 1
955 };
956 Q_DECLARE_FLAGS(Flags, Flag)
957
958 QRhiResource::Type resourceType() const override;
959
description()960 QRhiTextureRenderTargetDescription description() const { return m_desc; }
setDescription(const QRhiTextureRenderTargetDescription & desc)961 void setDescription(const QRhiTextureRenderTargetDescription &desc) { m_desc = desc; }
962
flags()963 Flags flags() const { return m_flags; }
setFlags(Flags f)964 void setFlags(Flags f) { m_flags = f; }
965
966 virtual QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() = 0;
967
968 virtual bool build() = 0;
969
970 protected:
971 QRhiTextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc_, Flags flags_);
972 QRhiTextureRenderTargetDescription m_desc;
973 Flags m_flags;
974 };
975
Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiTextureRenderTarget::Flags)976 Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiTextureRenderTarget::Flags)
977
978 class Q_GUI_EXPORT QRhiShaderResourceBindings : public QRhiResource
979 {
980 public:
981 QRhiResource::Type resourceType() const override;
982
983 void setBindings(std::initializer_list<QRhiShaderResourceBinding> list) { m_bindings = list; }
984
985 template<typename InputIterator>
986 void setBindings(InputIterator first, InputIterator last)
987 {
988 m_bindings.clear();
989 std::copy(first, last, std::back_inserter(m_bindings));
990 }
991
992 const QRhiShaderResourceBinding *cbeginBindings() const { return m_bindings.cbegin(); }
993 const QRhiShaderResourceBinding *cendBindings() const { return m_bindings.cend(); }
994
995 bool isLayoutCompatible(const QRhiShaderResourceBindings *other) const;
996
997 virtual bool build() = 0;
998
999 protected:
1000 QRhiShaderResourceBindings(QRhiImplementation *rhi);
1001 QVarLengthArray<QRhiShaderResourceBinding, 8> m_bindings;
1002 #ifndef QT_NO_DEBUG_STREAM
1003 friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderResourceBindings &);
1004 #endif
1005 };
1006
1007 #ifndef QT_NO_DEBUG_STREAM
1008 Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderResourceBindings &);
1009 #endif
1010
1011 class Q_GUI_EXPORT QRhiGraphicsPipeline : public QRhiResource
1012 {
1013 public:
1014 enum Flag {
1015 UsesBlendConstants = 1 << 0,
1016 UsesStencilRef = 1 << 1,
1017 UsesScissor = 1 << 2
1018 };
1019 Q_DECLARE_FLAGS(Flags, Flag)
1020
1021 enum Topology {
1022 Triangles,
1023 TriangleStrip,
1024 TriangleFan,
1025 Lines,
1026 LineStrip,
1027 Points
1028 };
1029
1030 enum CullMode {
1031 None,
1032 Front,
1033 Back
1034 };
1035
1036 enum FrontFace {
1037 CCW,
1038 CW
1039 };
1040
1041 enum ColorMaskComponent {
1042 R = 1 << 0,
1043 G = 1 << 1,
1044 B = 1 << 2,
1045 A = 1 << 3
1046 };
1047 Q_DECLARE_FLAGS(ColorMask, ColorMaskComponent)
1048
1049 enum BlendFactor {
1050 Zero,
1051 One,
1052 SrcColor,
1053 OneMinusSrcColor,
1054 DstColor,
1055 OneMinusDstColor,
1056 SrcAlpha,
1057 OneMinusSrcAlpha,
1058 DstAlpha,
1059 OneMinusDstAlpha,
1060 ConstantColor,
1061 OneMinusConstantColor,
1062 ConstantAlpha,
1063 OneMinusConstantAlpha,
1064 SrcAlphaSaturate,
1065 Src1Color,
1066 OneMinusSrc1Color,
1067 Src1Alpha,
1068 OneMinusSrc1Alpha
1069 };
1070
1071 enum BlendOp {
1072 Add,
1073 Subtract,
1074 ReverseSubtract,
1075 Min,
1076 Max
1077 };
1078
1079 struct TargetBlend {
1080 ColorMask colorWrite = ColorMask(0xF); // R | G | B | A
1081 bool enable = false;
1082 BlendFactor srcColor = One;
1083 BlendFactor dstColor = OneMinusSrcAlpha;
1084 BlendOp opColor = Add;
1085 BlendFactor srcAlpha = One;
1086 BlendFactor dstAlpha = OneMinusSrcAlpha;
1087 BlendOp opAlpha = Add;
1088 };
1089
1090 enum CompareOp {
1091 Never,
1092 Less,
1093 Equal,
1094 LessOrEqual,
1095 Greater,
1096 NotEqual,
1097 GreaterOrEqual,
1098 Always
1099 };
1100
1101 enum StencilOp {
1102 StencilZero,
1103 Keep,
1104 Replace,
1105 IncrementAndClamp,
1106 DecrementAndClamp,
1107 Invert,
1108 IncrementAndWrap,
1109 DecrementAndWrap
1110 };
1111
1112 struct StencilOpState {
1113 StencilOp failOp = Keep;
1114 StencilOp depthFailOp = Keep;
1115 StencilOp passOp = Keep;
1116 CompareOp compareOp = Always;
1117 };
1118
1119 QRhiResource::Type resourceType() const override;
1120
flags()1121 Flags flags() const { return m_flags; }
setFlags(Flags f)1122 void setFlags(Flags f) { m_flags = f; }
1123
topology()1124 Topology topology() const { return m_topology; }
setTopology(Topology t)1125 void setTopology(Topology t) { m_topology = t; }
1126
cullMode()1127 CullMode cullMode() const { return m_cullMode; }
setCullMode(CullMode mode)1128 void setCullMode(CullMode mode) { m_cullMode = mode; }
1129
frontFace()1130 FrontFace frontFace() const { return m_frontFace; }
setFrontFace(FrontFace f)1131 void setFrontFace(FrontFace f) { m_frontFace = f; }
1132
setTargetBlends(std::initializer_list<TargetBlend> list)1133 void setTargetBlends(std::initializer_list<TargetBlend> list) { m_targetBlends = list; }
1134 template<typename InputIterator>
setTargetBlends(InputIterator first,InputIterator last)1135 void setTargetBlends(InputIterator first, InputIterator last)
1136 {
1137 m_targetBlends.clear();
1138 std::copy(first, last, std::back_inserter(m_targetBlends));
1139 }
cbeginTargetBlends()1140 const TargetBlend *cbeginTargetBlends() const { return m_targetBlends.cbegin(); }
cendTargetBlends()1141 const TargetBlend *cendTargetBlends() const { return m_targetBlends.cend(); }
1142
hasDepthTest()1143 bool hasDepthTest() const { return m_depthTest; }
setDepthTest(bool enable)1144 void setDepthTest(bool enable) { m_depthTest = enable; }
1145
hasDepthWrite()1146 bool hasDepthWrite() const { return m_depthWrite; }
setDepthWrite(bool enable)1147 void setDepthWrite(bool enable) { m_depthWrite = enable; }
1148
depthOp()1149 CompareOp depthOp() const { return m_depthOp; }
setDepthOp(CompareOp op)1150 void setDepthOp(CompareOp op) { m_depthOp = op; }
1151
hasStencilTest()1152 bool hasStencilTest() const { return m_stencilTest; }
setStencilTest(bool enable)1153 void setStencilTest(bool enable) { m_stencilTest = enable; }
1154
stencilFront()1155 StencilOpState stencilFront() const { return m_stencilFront; }
setStencilFront(const StencilOpState & state)1156 void setStencilFront(const StencilOpState &state) { m_stencilFront = state; }
1157
stencilBack()1158 StencilOpState stencilBack() const { return m_stencilBack; }
setStencilBack(const StencilOpState & state)1159 void setStencilBack(const StencilOpState &state) { m_stencilBack = state; }
1160
stencilReadMask()1161 quint32 stencilReadMask() const { return m_stencilReadMask; }
setStencilReadMask(quint32 mask)1162 void setStencilReadMask(quint32 mask) { m_stencilReadMask = mask; }
1163
stencilWriteMask()1164 quint32 stencilWriteMask() const { return m_stencilWriteMask; }
setStencilWriteMask(quint32 mask)1165 void setStencilWriteMask(quint32 mask) { m_stencilWriteMask = mask; }
1166
sampleCount()1167 int sampleCount() const { return m_sampleCount; }
setSampleCount(int s)1168 void setSampleCount(int s) { m_sampleCount = s; }
1169
lineWidth()1170 float lineWidth() const { return m_lineWidth; }
setLineWidth(float width)1171 void setLineWidth(float width) { m_lineWidth = width; }
1172
depthBias()1173 int depthBias() const { return m_depthBias; }
setDepthBias(int bias)1174 void setDepthBias(int bias) { m_depthBias = bias; }
1175
slopeScaledDepthBias()1176 float slopeScaledDepthBias() const { return m_slopeScaledDepthBias; }
setSlopeScaledDepthBias(float bias)1177 void setSlopeScaledDepthBias(float bias) { m_slopeScaledDepthBias = bias; }
1178
setShaderStages(std::initializer_list<QRhiShaderStage> list)1179 void setShaderStages(std::initializer_list<QRhiShaderStage> list) { m_shaderStages = list; }
1180 template<typename InputIterator>
setShaderStages(InputIterator first,InputIterator last)1181 void setShaderStages(InputIterator first, InputIterator last)
1182 {
1183 m_shaderStages.clear();
1184 std::copy(first, last, std::back_inserter(m_shaderStages));
1185 }
cbeginShaderStages()1186 const QRhiShaderStage *cbeginShaderStages() const { return m_shaderStages.cbegin(); }
cendShaderStages()1187 const QRhiShaderStage *cendShaderStages() const { return m_shaderStages.cend(); }
1188
vertexInputLayout()1189 QRhiVertexInputLayout vertexInputLayout() const { return m_vertexInputLayout; }
setVertexInputLayout(const QRhiVertexInputLayout & layout)1190 void setVertexInputLayout(const QRhiVertexInputLayout &layout) { m_vertexInputLayout = layout; }
1191
shaderResourceBindings()1192 QRhiShaderResourceBindings *shaderResourceBindings() const { return m_shaderResourceBindings; }
setShaderResourceBindings(QRhiShaderResourceBindings * srb)1193 void setShaderResourceBindings(QRhiShaderResourceBindings *srb) { m_shaderResourceBindings = srb; }
1194
renderPassDescriptor()1195 QRhiRenderPassDescriptor *renderPassDescriptor() const { return m_renderPassDesc; }
setRenderPassDescriptor(QRhiRenderPassDescriptor * desc)1196 void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc) { m_renderPassDesc = desc; }
1197
1198 virtual bool build() = 0;
1199
1200 protected:
1201 QRhiGraphicsPipeline(QRhiImplementation *rhi);
1202 Flags m_flags;
1203 Topology m_topology = Triangles;
1204 CullMode m_cullMode = None;
1205 FrontFace m_frontFace = CCW;
1206 QVarLengthArray<TargetBlend, 8> m_targetBlends;
1207 bool m_depthTest = false;
1208 bool m_depthWrite = false;
1209 CompareOp m_depthOp = Less;
1210 bool m_stencilTest = false;
1211 StencilOpState m_stencilFront;
1212 StencilOpState m_stencilBack;
1213 quint32 m_stencilReadMask = 0xFF;
1214 quint32 m_stencilWriteMask = 0xFF;
1215 int m_sampleCount = 1;
1216 float m_lineWidth = 1.0f;
1217 int m_depthBias = 0;
1218 float m_slopeScaledDepthBias = 0.0f;
1219 QVarLengthArray<QRhiShaderStage, 4> m_shaderStages;
1220 QRhiVertexInputLayout m_vertexInputLayout;
1221 QRhiShaderResourceBindings *m_shaderResourceBindings = nullptr;
1222 QRhiRenderPassDescriptor *m_renderPassDesc = nullptr;
1223 };
1224
1225 Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiGraphicsPipeline::Flags)
1226 Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiGraphicsPipeline::ColorMask)
1227 Q_DECLARE_TYPEINFO(QRhiGraphicsPipeline::TargetBlend, Q_MOVABLE_TYPE);
1228
1229 class Q_GUI_EXPORT QRhiSwapChain : public QRhiResource
1230 {
1231 public:
1232 enum Flag {
1233 SurfaceHasPreMulAlpha = 1 << 0,
1234 SurfaceHasNonPreMulAlpha = 1 << 1,
1235 sRGB = 1 << 2,
1236 UsedAsTransferSource = 1 << 3,
1237 NoVSync = 1 << 4,
1238 MinimalBufferCount = 1 << 5
1239 };
1240 Q_DECLARE_FLAGS(Flags, Flag)
1241
1242 QRhiResource::Type resourceType() const override;
1243
window()1244 QWindow *window() const { return m_window; }
setWindow(QWindow * window)1245 void setWindow(QWindow *window) { m_window = window; }
1246
flags()1247 Flags flags() const { return m_flags; }
setFlags(Flags f)1248 void setFlags(Flags f) { m_flags = f; }
1249
depthStencil()1250 QRhiRenderBuffer *depthStencil() const { return m_depthStencil; }
setDepthStencil(QRhiRenderBuffer * ds)1251 void setDepthStencil(QRhiRenderBuffer *ds) { m_depthStencil = ds; }
1252
sampleCount()1253 int sampleCount() const { return m_sampleCount; }
setSampleCount(int samples)1254 void setSampleCount(int samples) { m_sampleCount = samples; }
1255
renderPassDescriptor()1256 QRhiRenderPassDescriptor *renderPassDescriptor() const { return m_renderPassDesc; }
setRenderPassDescriptor(QRhiRenderPassDescriptor * desc)1257 void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc) { m_renderPassDesc = desc; }
1258
currentPixelSize()1259 QSize currentPixelSize() const { return m_currentPixelSize; }
1260
1261 virtual QRhiCommandBuffer *currentFrameCommandBuffer() = 0;
1262 virtual QRhiRenderTarget *currentFrameRenderTarget() = 0;
1263 virtual QSize surfacePixelSize() = 0;
1264 virtual QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() = 0;
1265 virtual bool buildOrResize() = 0;
1266
1267 protected:
1268 QRhiSwapChain(QRhiImplementation *rhi);
1269 QWindow *m_window = nullptr;
1270 Flags m_flags;
1271 QRhiRenderBuffer *m_depthStencil = nullptr;
1272 int m_sampleCount = 1;
1273 QRhiRenderPassDescriptor *m_renderPassDesc = nullptr;
1274 QSize m_currentPixelSize;
1275 };
1276
Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiSwapChain::Flags)1277 Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiSwapChain::Flags)
1278
1279 class Q_GUI_EXPORT QRhiComputePipeline : public QRhiResource
1280 {
1281 public:
1282 QRhiResource::Type resourceType() const override;
1283 virtual bool build() = 0;
1284
1285 QRhiShaderStage shaderStage() const { return m_shaderStage; }
1286 void setShaderStage(const QRhiShaderStage &stage) { m_shaderStage = stage; }
1287
1288 QRhiShaderResourceBindings *shaderResourceBindings() const { return m_shaderResourceBindings; }
1289 void setShaderResourceBindings(QRhiShaderResourceBindings *srb) { m_shaderResourceBindings = srb; }
1290
1291 protected:
1292 QRhiComputePipeline(QRhiImplementation *rhi);
1293 QRhiShaderStage m_shaderStage;
1294 QRhiShaderResourceBindings *m_shaderResourceBindings = nullptr;
1295 };
1296
1297 class Q_GUI_EXPORT QRhiCommandBuffer : public QRhiResource
1298 {
1299 public:
1300 enum IndexFormat {
1301 IndexUInt16,
1302 IndexUInt32
1303 };
1304
1305 QRhiResource::Type resourceType() const override;
1306
1307 void resourceUpdate(QRhiResourceUpdateBatch *resourceUpdates);
1308
1309 void beginPass(QRhiRenderTarget *rt,
1310 const QColor &colorClearValue,
1311 const QRhiDepthStencilClearValue &depthStencilClearValue,
1312 QRhiResourceUpdateBatch *resourceUpdates = nullptr);
1313 void endPass(QRhiResourceUpdateBatch *resourceUpdates = nullptr);
1314
1315 void setGraphicsPipeline(QRhiGraphicsPipeline *ps);
1316 using DynamicOffset = QPair<int, quint32>; // binding, offset
1317 void setShaderResources(QRhiShaderResourceBindings *srb = nullptr,
1318 int dynamicOffsetCount = 0,
1319 const DynamicOffset *dynamicOffsets = nullptr);
1320 using VertexInput = QPair<QRhiBuffer *, quint32>; // buffer, offset
1321 void setVertexInput(int startBinding, int bindingCount, const VertexInput *bindings,
1322 QRhiBuffer *indexBuf = nullptr, quint32 indexOffset = 0,
1323 IndexFormat indexFormat = IndexUInt16);
1324
1325 void setViewport(const QRhiViewport &viewport);
1326 void setScissor(const QRhiScissor &scissor);
1327 void setBlendConstants(const QColor &c);
1328 void setStencilRef(quint32 refValue);
1329
1330 void draw(quint32 vertexCount,
1331 quint32 instanceCount = 1,
1332 quint32 firstVertex = 0,
1333 quint32 firstInstance = 0);
1334
1335 void drawIndexed(quint32 indexCount,
1336 quint32 instanceCount = 1,
1337 quint32 firstIndex = 0,
1338 qint32 vertexOffset = 0,
1339 quint32 firstInstance = 0);
1340
1341 void debugMarkBegin(const QByteArray &name);
1342 void debugMarkEnd();
1343 void debugMarkMsg(const QByteArray &msg);
1344
1345 void beginComputePass(QRhiResourceUpdateBatch *resourceUpdates = nullptr);
1346 void endComputePass(QRhiResourceUpdateBatch *resourceUpdates = nullptr);
1347 void setComputePipeline(QRhiComputePipeline *ps);
1348 void dispatch(int x, int y, int z);
1349
1350 const QRhiNativeHandles *nativeHandles();
1351 void beginExternal();
1352 void endExternal();
1353
1354 protected:
1355 QRhiCommandBuffer(QRhiImplementation *rhi);
1356 };
1357
1358 struct Q_GUI_EXPORT QRhiReadbackResult
1359 {
1360 std::function<void()> completed = nullptr;
1361 QRhiTexture::Format format;
1362 QSize pixelSize;
1363 QByteArray data;
1364 }; // non-movable due to the std::function
1365
1366 struct Q_GUI_EXPORT QRhiBufferReadbackResult
1367 {
1368 std::function<void()> completed = nullptr;
1369 QByteArray data;
1370 };
1371
1372 class Q_GUI_EXPORT QRhiResourceUpdateBatch
1373 {
1374 public:
1375 ~QRhiResourceUpdateBatch();
1376
1377 void release();
1378
1379 void merge(QRhiResourceUpdateBatch *other);
1380
1381 void updateDynamicBuffer(QRhiBuffer *buf, int offset, int size, const void *data);
1382 void uploadStaticBuffer(QRhiBuffer *buf, int offset, int size, const void *data);
1383 void uploadStaticBuffer(QRhiBuffer *buf, const void *data);
1384 void readBackBuffer(QRhiBuffer *buf, int offset, int size, QRhiBufferReadbackResult *result);
1385 void uploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc);
1386 void uploadTexture(QRhiTexture *tex, const QImage &image);
1387 void copyTexture(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc = QRhiTextureCopyDescription());
1388 void readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result);
1389 void generateMips(QRhiTexture *tex, int layer = 0);
1390
1391 private:
1392 QRhiResourceUpdateBatch(QRhiImplementation *rhi);
1393 Q_DISABLE_COPY(QRhiResourceUpdateBatch)
1394 QRhiResourceUpdateBatchPrivate *d;
1395 friend class QRhiResourceUpdateBatchPrivate;
1396 friend class QRhi;
1397 };
1398
1399 struct Q_GUI_EXPORT QRhiInitParams
1400 {
1401 };
1402
1403 class Q_GUI_EXPORT QRhi
1404 {
1405 public:
1406 enum Implementation {
1407 Null,
1408 Vulkan,
1409 OpenGLES2,
1410 D3D11,
1411 Metal
1412 };
1413
1414 enum Flag {
1415 EnableProfiling = 1 << 0,
1416 EnableDebugMarkers = 1 << 1,
1417 PreferSoftwareRenderer = 1 << 2
1418 };
1419 Q_DECLARE_FLAGS(Flags, Flag)
1420
1421 enum FrameOpResult {
1422 FrameOpSuccess = 0,
1423 FrameOpError,
1424 FrameOpSwapChainOutOfDate,
1425 FrameOpDeviceLost
1426 };
1427
1428 enum Feature {
1429 MultisampleTexture = 1,
1430 MultisampleRenderBuffer,
1431 DebugMarkers,
1432 Timestamps,
1433 Instancing,
1434 CustomInstanceStepRate,
1435 PrimitiveRestart,
1436 NonDynamicUniformBuffers,
1437 NonFourAlignedEffectiveIndexBufferOffset,
1438 NPOTTextureRepeat,
1439 RedOrAlpha8IsRed,
1440 ElementIndexUint,
1441 Compute,
1442 WideLines,
1443 VertexShaderPointSize,
1444 BaseVertex,
1445 BaseInstance,
1446 TriangleFanTopology,
1447 ReadBackNonUniformBuffer,
1448 ReadBackNonBaseMipLevel,
1449 TexelFetch
1450 };
1451
1452 enum BeginFrameFlag {
1453 ExternalContentsInPass = 0x01
1454 };
1455 Q_DECLARE_FLAGS(BeginFrameFlags, BeginFrameFlag)
1456
1457 enum EndFrameFlag {
1458 SkipPresent = 1 << 0
1459 };
1460 Q_DECLARE_FLAGS(EndFrameFlags, EndFrameFlag)
1461
1462 enum ResourceLimit {
1463 TextureSizeMin = 1,
1464 TextureSizeMax,
1465 MaxColorAttachments,
1466 FramesInFlight,
1467 MaxAsyncReadbackFrames
1468 };
1469
1470 ~QRhi();
1471
1472 static QRhi *create(Implementation impl,
1473 QRhiInitParams *params,
1474 Flags flags = Flags(),
1475 QRhiNativeHandles *importDevice = nullptr);
1476
1477 Implementation backend() const;
1478 QThread *thread() const;
1479
1480 using CleanupCallback = std::function<void(QRhi *)>;
1481 void addCleanupCallback(const CleanupCallback &callback);
1482 void runCleanup();
1483
1484 QRhiGraphicsPipeline *newGraphicsPipeline();
1485 QRhiComputePipeline *newComputePipeline();
1486 QRhiShaderResourceBindings *newShaderResourceBindings();
1487
1488 QRhiBuffer *newBuffer(QRhiBuffer::Type type,
1489 QRhiBuffer::UsageFlags usage,
1490 int size);
1491
1492 QRhiRenderBuffer *newRenderBuffer(QRhiRenderBuffer::Type type,
1493 const QSize &pixelSize,
1494 int sampleCount = 1,
1495 QRhiRenderBuffer::Flags flags = QRhiRenderBuffer::Flags());
1496
1497 QRhiTexture *newTexture(QRhiTexture::Format format,
1498 const QSize &pixelSize,
1499 int sampleCount = 1,
1500 QRhiTexture::Flags flags = QRhiTexture::Flags());
1501
1502 QRhiSampler *newSampler(QRhiSampler::Filter magFilter,
1503 QRhiSampler::Filter minFilter,
1504 QRhiSampler::Filter mipmapMode,
1505 QRhiSampler::AddressMode addressU,
1506 QRhiSampler::AddressMode addressV,
1507 QRhiSampler::AddressMode addressW = QRhiSampler::Repeat);
1508
1509 QRhiTextureRenderTarget *newTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc,
1510 QRhiTextureRenderTarget::Flags flags = QRhiTextureRenderTarget::Flags());
1511
1512 QRhiSwapChain *newSwapChain();
1513 FrameOpResult beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags flags = BeginFrameFlags());
1514 FrameOpResult endFrame(QRhiSwapChain *swapChain, EndFrameFlags flags = EndFrameFlags());
1515 bool isRecordingFrame() const;
1516 int currentFrameSlot() const;
1517
1518 FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, BeginFrameFlags flags = BeginFrameFlags());
1519 FrameOpResult endOffscreenFrame(EndFrameFlags flags = EndFrameFlags());
1520
1521 QRhi::FrameOpResult finish();
1522
1523 QRhiResourceUpdateBatch *nextResourceUpdateBatch();
1524
1525 QVector<int> supportedSampleCounts() const;
1526
1527 int ubufAlignment() const;
1528 int ubufAligned(int v) const;
1529
1530 int mipLevelsForSize(const QSize &size) const;
1531 QSize sizeForMipLevel(int mipLevel, const QSize &baseLevelSize) const;
1532
1533 bool isYUpInFramebuffer() const;
1534 bool isYUpInNDC() const;
1535 bool isClipDepthZeroToOne() const;
1536
1537 QMatrix4x4 clipSpaceCorrMatrix() const;
1538
1539 bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags = QRhiTexture::Flags()) const;
1540 bool isFeatureSupported(QRhi::Feature feature) const;
1541 int resourceLimit(ResourceLimit limit) const;
1542
1543 const QRhiNativeHandles *nativeHandles();
1544 bool makeThreadLocalNativeContextCurrent();
1545
1546 QRhiProfiler *profiler();
1547
1548 static const int MAX_LAYERS = 6; // cubemaps only
1549 static const int MAX_LEVELS = 16; // a width and/or height of 65536 should be enough for everyone
1550
1551 void releaseCachedResources();
1552
1553 bool isDeviceLost() const;
1554
1555 protected:
1556 QRhi();
1557
1558 private:
1559 Q_DISABLE_COPY(QRhi)
1560 QRhiImplementation *d = nullptr;
1561 };
1562
1563 Q_DECLARE_OPERATORS_FOR_FLAGS(QRhi::Flags)
1564 Q_DECLARE_OPERATORS_FOR_FLAGS(QRhi::BeginFrameFlags)
1565 Q_DECLARE_OPERATORS_FOR_FLAGS(QRhi::EndFrameFlags)
1566
1567 QT_END_NAMESPACE
1568
1569 #endif
1570