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
63QT_BEGIN_NAMESPACE
64
65class QWindow;
66class QRhiImplementation;
67class QRhiBuffer;
68class QRhiRenderBuffer;
69class QRhiTexture;
70class QRhiSampler;
71class QRhiCommandBuffer;
72class QRhiResourceUpdateBatch;
73class QRhiResourceUpdateBatchPrivate;
74class QRhiProfiler;
75
76class Q_GUI_EXPORT QRhiDepthStencilClearValue
77{
78public:
79 QRhiDepthStencilClearValue() = default;
80 QRhiDepthStencilClearValue(float d, quint32 s);
81
82 float depthClearValue() const { return m_d; }
83 void setDepthClearValue(float d) { m_d = d; }
84
85 quint32 stencilClearValue() const { return m_s; }
86 void setStencilClearValue(quint32 s) { m_s = s; }
87
88private:
89 float m_d = 1.0f;
90 quint32 m_s = 0;
91};
92
93Q_DECLARE_TYPEINFO(QRhiDepthStencilClearValue, Q_MOVABLE_TYPE);
94
95Q_GUI_EXPORT bool operator==(const QRhiDepthStencilClearValue &a, const QRhiDepthStencilClearValue &b) Q_DECL_NOTHROW;
96Q_GUI_EXPORT bool operator!=(const QRhiDepthStencilClearValue &a, const QRhiDepthStencilClearValue &b) Q_DECL_NOTHROW;
97Q_GUI_EXPORT uint qHash(const QRhiDepthStencilClearValue &v, uint seed = 0) Q_DECL_NOTHROW;
98#ifndef QT_NO_DEBUG_STREAM
99Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiDepthStencilClearValue &);
100#endif
101
102class Q_GUI_EXPORT QRhiViewport
103{
104public:
105 QRhiViewport() = default;
106 QRhiViewport(float x, float y, float w, float h, float minDepth = 0.0f, float maxDepth = 1.0f);
107
108 std::array<float, 4> viewport() const { return m_rect; }
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
113 float minDepth() const { return m_minDepth; }
114 void setMinDepth(float minDepth) { m_minDepth = minDepth; }
115
116 float maxDepth() const { return m_maxDepth; }
117 void setMaxDepth(float maxDepth) { m_maxDepth = maxDepth; }
118
119private:
120 std::array<float, 4> m_rect { ._M_elems: { 0.0f, 0.0f, 0.0f, 0.0f } };
121 float m_minDepth = 0.0f;
122 float m_maxDepth = 1.0f;
123};
124
125Q_DECLARE_TYPEINFO(QRhiViewport, Q_MOVABLE_TYPE);
126
127Q_GUI_EXPORT bool operator==(const QRhiViewport &a, const QRhiViewport &b) Q_DECL_NOTHROW;
128Q_GUI_EXPORT bool operator!=(const QRhiViewport &a, const QRhiViewport &b) Q_DECL_NOTHROW;
129Q_GUI_EXPORT uint qHash(const QRhiViewport &v, uint seed = 0) Q_DECL_NOTHROW;
130#ifndef QT_NO_DEBUG_STREAM
131Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiViewport &);
132#endif
133
134class Q_GUI_EXPORT QRhiScissor
135{
136public:
137 QRhiScissor() = default;
138 QRhiScissor(int x, int y, int w, int h);
139
140 std::array<int, 4> scissor() const { return m_rect; }
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
145private:
146 std::array<int, 4> m_rect { ._M_elems: { 0, 0, 0, 0 } };
147};
148
149Q_DECLARE_TYPEINFO(QRhiScissor, Q_MOVABLE_TYPE);
150
151Q_GUI_EXPORT bool operator==(const QRhiScissor &a, const QRhiScissor &b) Q_DECL_NOTHROW;
152Q_GUI_EXPORT bool operator!=(const QRhiScissor &a, const QRhiScissor &b) Q_DECL_NOTHROW;
153Q_GUI_EXPORT uint qHash(const QRhiScissor &v, uint seed = 0) Q_DECL_NOTHROW;
154#ifndef QT_NO_DEBUG_STREAM
155Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiScissor &);
156#endif
157
158class Q_GUI_EXPORT QRhiVertexInputBinding
159{
160public:
161 enum Classification {
162 PerVertex,
163 PerInstance
164 };
165
166 QRhiVertexInputBinding() = default;
167 QRhiVertexInputBinding(quint32 stride, Classification cls = PerVertex, int stepRate = 1);
168
169 quint32 stride() const { return m_stride; }
170 void setStride(quint32 s) { m_stride = s; }
171
172 Classification classification() const { return m_classification; }
173 void setClassification(Classification c) { m_classification = c; }
174
175 int instanceStepRate() const { return m_instanceStepRate; }
176 void setInstanceStepRate(int rate) { m_instanceStepRate = rate; }
177
178private:
179 quint32 m_stride = 0;
180 Classification m_classification = PerVertex;
181 int m_instanceStepRate = 1;
182};
183
184Q_DECLARE_TYPEINFO(QRhiVertexInputBinding, Q_MOVABLE_TYPE);
185
186Q_GUI_EXPORT bool operator==(const QRhiVertexInputBinding &a, const QRhiVertexInputBinding &b) Q_DECL_NOTHROW;
187Q_GUI_EXPORT bool operator!=(const QRhiVertexInputBinding &a, const QRhiVertexInputBinding &b) Q_DECL_NOTHROW;
188Q_GUI_EXPORT uint qHash(const QRhiVertexInputBinding &v, uint seed = 0) Q_DECL_NOTHROW;
189#ifndef QT_NO_DEBUG_STREAM
190Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiVertexInputBinding &);
191#endif
192
193class Q_GUI_EXPORT QRhiVertexInputAttribute
194{
195public:
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
209 int binding() const { return m_binding; }
210 void setBinding(int b) { m_binding = b; }
211
212 int location() const { return m_location; }
213 void setLocation(int loc) { m_location = loc; }
214
215 Format format() const { return m_format; }
216 void setFormt(Format f) { m_format = f; }
217
218 quint32 offset() const { return m_offset; }
219 void setOffset(quint32 ofs) { m_offset = ofs; }
220
221private:
222 int m_binding = 0;
223 int m_location = 0;
224 Format m_format = Float4;
225 quint32 m_offset = 0;
226};
227
228Q_DECLARE_TYPEINFO(QRhiVertexInputAttribute, Q_MOVABLE_TYPE);
229
230Q_GUI_EXPORT bool operator==(const QRhiVertexInputAttribute &a, const QRhiVertexInputAttribute &b) Q_DECL_NOTHROW;
231Q_GUI_EXPORT bool operator!=(const QRhiVertexInputAttribute &a, const QRhiVertexInputAttribute &b) Q_DECL_NOTHROW;
232Q_GUI_EXPORT uint qHash(const QRhiVertexInputAttribute &v, uint seed = 0) Q_DECL_NOTHROW;
233#ifndef QT_NO_DEBUG_STREAM
234Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiVertexInputAttribute &);
235#endif
236
237class Q_GUI_EXPORT QRhiVertexInputLayout
238{
239public:
240 QRhiVertexInputLayout() = default;
241
242 void setBindings(std::initializer_list<QRhiVertexInputBinding> list) { m_bindings = list; }
243 template<typename InputIterator>
244 void setBindings(InputIterator first, InputIterator last)
245 {
246 m_bindings.clear();
247 std::copy(first, last, std::back_inserter(x&: m_bindings));
248 }
249 const QRhiVertexInputBinding *cbeginBindings() const { return m_bindings.cbegin(); }
250 const QRhiVertexInputBinding *cendBindings() const { return m_bindings.cend(); }
251 const QRhiVertexInputBinding *bindingAt(int index) const { return &m_bindings.at(idx: index); }
252
253 void setAttributes(std::initializer_list<QRhiVertexInputAttribute> list) { m_attributes = list; }
254 template<typename InputIterator>
255 void setAttributes(InputIterator first, InputIterator last)
256 {
257 m_attributes.clear();
258 std::copy(first, last, std::back_inserter(x&: m_attributes));
259 }
260 const QRhiVertexInputAttribute *cbeginAttributes() const { return m_attributes.cbegin(); }
261 const QRhiVertexInputAttribute *cendAttributes() const { return m_attributes.cend(); }
262
263private:
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
272Q_DECLARE_TYPEINFO(QRhiVertexInputLayout, Q_MOVABLE_TYPE);
273
274Q_GUI_EXPORT bool operator==(const QRhiVertexInputLayout &a, const QRhiVertexInputLayout &b) Q_DECL_NOTHROW;
275Q_GUI_EXPORT bool operator!=(const QRhiVertexInputLayout &a, const QRhiVertexInputLayout &b) Q_DECL_NOTHROW;
276Q_GUI_EXPORT uint qHash(const QRhiVertexInputLayout &v, uint seed = 0) Q_DECL_NOTHROW;
277#ifndef QT_NO_DEBUG_STREAM
278Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiVertexInputLayout &);
279#endif
280
281class Q_GUI_EXPORT QRhiShaderStage
282{
283public:
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
294 Type type() const { return m_type; }
295 void setType(Type t) { m_type = t; }
296
297 QShader shader() const { return m_shader; }
298 void setShader(const QShader &s) { m_shader = s; }
299
300 QShader::Variant shaderVariant() const { return m_shaderVariant; }
301 void setShaderVariant(QShader::Variant v) { m_shaderVariant = v; }
302
303private:
304 Type m_type = Vertex;
305 QShader m_shader;
306 QShader::Variant m_shaderVariant = QShader::StandardShader;
307};
308
309Q_DECLARE_TYPEINFO(QRhiShaderStage, Q_MOVABLE_TYPE);
310
311Q_GUI_EXPORT bool operator==(const QRhiShaderStage &a, const QRhiShaderStage &b) Q_DECL_NOTHROW;
312Q_GUI_EXPORT bool operator!=(const QRhiShaderStage &a, const QRhiShaderStage &b) Q_DECL_NOTHROW;
313Q_GUI_EXPORT uint qHash(const QRhiShaderStage &s, uint seed = 0) Q_DECL_NOTHROW;
314#ifndef QT_NO_DEBUG_STREAM
315Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderStage &);
316#endif
317
318using QRhiGraphicsShaderStage = QRhiShaderStage;
319
320class Q_GUI_EXPORT QRhiShaderResourceBinding
321{
322public:
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
401 Data *data() { return &d; }
402 const Data *data() const { return &d; }
403
404private:
405 Data d;
406};
407
408Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiShaderResourceBinding::StageFlags)
409
410Q_DECLARE_TYPEINFO(QRhiShaderResourceBinding, Q_MOVABLE_TYPE);
411
412Q_GUI_EXPORT bool operator==(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) Q_DECL_NOTHROW;
413Q_GUI_EXPORT bool operator!=(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) Q_DECL_NOTHROW;
414Q_GUI_EXPORT uint qHash(const QRhiShaderResourceBinding &b, uint seed = 0) Q_DECL_NOTHROW;
415#ifndef QT_NO_DEBUG_STREAM
416Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderResourceBinding &);
417#endif
418
419class Q_GUI_EXPORT QRhiColorAttachment
420{
421public:
422 QRhiColorAttachment() = default;
423 QRhiColorAttachment(QRhiTexture *texture);
424 QRhiColorAttachment(QRhiRenderBuffer *renderBuffer);
425
426 QRhiTexture *texture() const { return m_texture; }
427 void setTexture(QRhiTexture *tex) { m_texture = tex; }
428
429 QRhiRenderBuffer *renderBuffer() const { return m_renderBuffer; }
430 void setRenderBuffer(QRhiRenderBuffer *rb) { m_renderBuffer = rb; }
431
432 int layer() const { return m_layer; }
433 void setLayer(int layer) { m_layer = layer; }
434
435 int level() const { return m_level; }
436 void setLevel(int level) { m_level = level; }
437
438 QRhiTexture *resolveTexture() const { return m_resolveTexture; }
439 void setResolveTexture(QRhiTexture *tex) { m_resolveTexture = tex; }
440
441 int resolveLayer() const { return m_resolveLayer; }
442 void setResolveLayer(int layer) { m_resolveLayer = layer; }
443
444 int resolveLevel() const { return m_resolveLevel; }
445 void setResolveLevel(int level) { m_resolveLevel = level; }
446
447private:
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
457Q_DECLARE_TYPEINFO(QRhiColorAttachment, Q_MOVABLE_TYPE);
458
459class Q_GUI_EXPORT QRhiTextureRenderTargetDescription
460{
461public:
462 QRhiTextureRenderTargetDescription() = default;
463 QRhiTextureRenderTargetDescription(const QRhiColorAttachment &colorAttachment);
464 QRhiTextureRenderTargetDescription(const QRhiColorAttachment &colorAttachment, QRhiRenderBuffer *depthStencilBuffer);
465 QRhiTextureRenderTargetDescription(const QRhiColorAttachment &colorAttachment, QRhiTexture *depthTexture);
466
467 void setColorAttachments(std::initializer_list<QRhiColorAttachment> list) { m_colorAttachments = list; }
468 template<typename InputIterator>
469 void setColorAttachments(InputIterator first, InputIterator last)
470 {
471 m_colorAttachments.clear();
472 std::copy(first, last, std::back_inserter(x&: m_colorAttachments));
473 }
474 const QRhiColorAttachment *cbeginColorAttachments() const { return m_colorAttachments.cbegin(); }
475 const QRhiColorAttachment *cendColorAttachments() const { return m_colorAttachments.cend(); }
476 const QRhiColorAttachment *colorAttachmentAt(int index) const { return &m_colorAttachments.at(idx: index); }
477
478 QRhiRenderBuffer *depthStencilBuffer() const { return m_depthStencilBuffer; }
479 void setDepthStencilBuffer(QRhiRenderBuffer *renderBuffer) { m_depthStencilBuffer = renderBuffer; }
480
481 QRhiTexture *depthTexture() const { return m_depthTexture; }
482 void setDepthTexture(QRhiTexture *texture) { m_depthTexture = texture; }
483
484private:
485 QVarLengthArray<QRhiColorAttachment, 8> m_colorAttachments;
486 QRhiRenderBuffer *m_depthStencilBuffer = nullptr;
487 QRhiTexture *m_depthTexture = nullptr;
488};
489
490Q_DECLARE_TYPEINFO(QRhiTextureRenderTargetDescription, Q_MOVABLE_TYPE);
491
492class Q_GUI_EXPORT QRhiTextureSubresourceUploadDescription
493{
494public:
495 QRhiTextureSubresourceUploadDescription() = default;
496 QRhiTextureSubresourceUploadDescription(const QImage &image);
497 QRhiTextureSubresourceUploadDescription(const void *data, int size);
498
499 QImage image() const { return m_image; }
500 void setImage(const QImage &image) { m_image = image; }
501
502 QByteArray data() const { return m_data; }
503 void setData(const QByteArray &data) { m_data = data; }
504
505 QPoint destinationTopLeft() const { return m_destinationTopLeft; }
506 void setDestinationTopLeft(const QPoint &p) { m_destinationTopLeft = p; }
507
508 QSize sourceSize() const { return m_sourceSize; }
509 void setSourceSize(const QSize &size) { m_sourceSize = size; }
510
511 QPoint sourceTopLeft() const { return m_sourceTopLeft; }
512 void setSourceTopLeft(const QPoint &p) { m_sourceTopLeft = p; }
513
514private:
515 QImage m_image;
516 QByteArray m_data;
517 QPoint m_destinationTopLeft;
518 QSize m_sourceSize;
519 QPoint m_sourceTopLeft;
520};
521
522Q_DECLARE_TYPEINFO(QRhiTextureSubresourceUploadDescription, Q_MOVABLE_TYPE);
523
524class Q_GUI_EXPORT QRhiTextureUploadEntry
525{
526public:
527 QRhiTextureUploadEntry() = default;
528 QRhiTextureUploadEntry(int layer, int level, const QRhiTextureSubresourceUploadDescription &desc);
529
530 int layer() const { return m_layer; }
531 void setLayer(int layer) { m_layer = layer; }
532
533 int level() const { return m_level; }
534 void setLevel(int level) { m_level = level; }
535
536 QRhiTextureSubresourceUploadDescription description() const { return m_desc; }
537 void setDescription(const QRhiTextureSubresourceUploadDescription &desc) { m_desc = desc; }
538
539private:
540 int m_layer = 0;
541 int m_level = 0;
542 QRhiTextureSubresourceUploadDescription m_desc;
543};
544
545Q_DECLARE_TYPEINFO(QRhiTextureUploadEntry, Q_MOVABLE_TYPE);
546
547class Q_GUI_EXPORT QRhiTextureUploadDescription
548{
549public:
550 QRhiTextureUploadDescription() = default;
551 QRhiTextureUploadDescription(const QRhiTextureUploadEntry &entry);
552 QRhiTextureUploadDescription(std::initializer_list<QRhiTextureUploadEntry> list);
553
554 void setEntries(std::initializer_list<QRhiTextureUploadEntry> list) { m_entries = list; }
555 template<typename InputIterator>
556 void setEntries(InputIterator first, InputIterator last)
557 {
558 m_entries.clear();
559 std::copy(first, last, std::back_inserter(x&: m_entries));
560 }
561 const QRhiTextureUploadEntry *cbeginEntries() const { return m_entries.cbegin(); }
562 const QRhiTextureUploadEntry *cendEntries() const { return m_entries.cend(); }
563
564private:
565 QVarLengthArray<QRhiTextureUploadEntry, 16> m_entries;
566};
567
568Q_DECLARE_TYPEINFO(QRhiTextureUploadDescription, Q_MOVABLE_TYPE);
569
570class Q_GUI_EXPORT QRhiTextureCopyDescription
571{
572public:
573 QRhiTextureCopyDescription() = default;
574
575 QSize pixelSize() const { return m_pixelSize; }
576 void setPixelSize(const QSize &sz) { m_pixelSize = sz; }
577
578 int sourceLayer() const { return m_sourceLayer; }
579 void setSourceLayer(int layer) { m_sourceLayer = layer; }
580
581 int sourceLevel() const { return m_sourceLevel; }
582 void setSourceLevel(int level) { m_sourceLevel = level; }
583
584 QPoint sourceTopLeft() const { return m_sourceTopLeft; }
585 void setSourceTopLeft(const QPoint &p) { m_sourceTopLeft = p; }
586
587 int destinationLayer() const { return m_destinationLayer; }
588 void setDestinationLayer(int layer) { m_destinationLayer = layer; }
589
590 int destinationLevel() const { return m_destinationLevel; }
591 void setDestinationLevel(int level) { m_destinationLevel = level; }
592
593 QPoint destinationTopLeft() const { return m_destinationTopLeft; }
594 void setDestinationTopLeft(const QPoint &p) { m_destinationTopLeft = p; }
595
596private:
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
606Q_DECLARE_TYPEINFO(QRhiTextureCopyDescription, Q_MOVABLE_TYPE);
607
608class Q_GUI_EXPORT QRhiReadbackDescription
609{
610public:
611 QRhiReadbackDescription() = default;
612 QRhiReadbackDescription(QRhiTexture *texture);
613
614 QRhiTexture *texture() const { return m_texture; }
615 void setTexture(QRhiTexture *tex) { m_texture = tex; }
616
617 int layer() const { return m_layer; }
618 void setLayer(int layer) { m_layer = layer; }
619
620 int level() const { return m_level; }
621 void setLevel(int level) { m_level = level; }
622
623private:
624 QRhiTexture *m_texture = nullptr;
625 int m_layer = 0;
626 int m_level = 0;
627};
628
629Q_DECLARE_TYPEINFO(QRhiReadbackDescription, Q_MOVABLE_TYPE);
630
631struct Q_GUI_EXPORT QRhiNativeHandles
632{
633};
634
635class Q_GUI_EXPORT QRhiResource
636{
637public:
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
665protected:
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
674class Q_GUI_EXPORT QRhiBuffer : public QRhiResource
675{
676public:
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
698 Type type() const { return m_type; }
699 void setType(Type t) { m_type = t; }
700
701 UsageFlags usage() const { return m_usage; }
702 void setUsage(UsageFlags u) { m_usage = u; }
703
704 int size() const { return m_size; }
705 void setSize(int sz) { m_size = sz; }
706
707 virtual bool build() = 0;
708
709 virtual NativeBuffer nativeBuffer();
710
711protected:
712 QRhiBuffer(QRhiImplementation *rhi, Type type_, UsageFlags usage_, int size_);
713 Type m_type;
714 UsageFlags m_usage;
715 int m_size;
716};
717
718Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiBuffer::UsageFlags)
719
720class Q_GUI_EXPORT QRhiTexture : public QRhiResource
721{
722public:
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
803protected:
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
812Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiTexture::Flags)
813
814class Q_GUI_EXPORT QRhiSampler : public QRhiResource
815{
816public:
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
865protected:
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
878class Q_GUI_EXPORT QRhiRenderBuffer : public QRhiResource
879{
880public:
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
893 Type type() const { return m_type; }
894 void setType(Type t) { m_type = t; }
895
896 QSize pixelSize() const { return m_pixelSize; }
897 void setPixelSize(const QSize &sz) { m_pixelSize = sz; }
898
899 int sampleCount() const { return m_sampleCount; }
900 void setSampleCount(int s) { m_sampleCount = s; }
901
902 Flags flags() const { return m_flags; }
903 void setFlags(Flags h) { m_flags = h; }
904
905 virtual bool build() = 0;
906
907 virtual QRhiTexture::Format backingFormat() const = 0;
908
909protected:
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
918Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiRenderBuffer::Flags)
919
920class Q_GUI_EXPORT QRhiRenderPassDescriptor : public QRhiResource
921{
922public:
923 QRhiResource::Type resourceType() const override;
924
925 virtual bool isCompatible(const QRhiRenderPassDescriptor *other) const = 0;
926 virtual const QRhiNativeHandles *nativeHandles();
927
928protected:
929 QRhiRenderPassDescriptor(QRhiImplementation *rhi);
930};
931
932class Q_GUI_EXPORT QRhiRenderTarget : public QRhiResource
933{
934public:
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
941 QRhiRenderPassDescriptor *renderPassDescriptor() const { return m_renderPassDesc; }
942 void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc) { m_renderPassDesc = desc; }
943
944protected:
945 QRhiRenderTarget(QRhiImplementation *rhi);
946 QRhiRenderPassDescriptor *m_renderPassDesc = nullptr;
947};
948
949class Q_GUI_EXPORT QRhiTextureRenderTarget : public QRhiRenderTarget
950{
951public:
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
960 QRhiTextureRenderTargetDescription description() const { return m_desc; }
961 void setDescription(const QRhiTextureRenderTargetDescription &desc) { m_desc = desc; }
962
963 Flags flags() const { return m_flags; }
964 void setFlags(Flags f) { m_flags = f; }
965
966 virtual QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() = 0;
967
968 virtual bool build() = 0;
969
970protected:
971 QRhiTextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc_, Flags flags_);
972 QRhiTextureRenderTargetDescription m_desc;
973 Flags m_flags;
974};
975
976Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiTextureRenderTarget::Flags)
977
978class Q_GUI_EXPORT QRhiShaderResourceBindings : public QRhiResource
979{
980public:
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(x&: 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
999protected:
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
1008Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderResourceBindings &);
1009#endif
1010
1011class Q_GUI_EXPORT QRhiGraphicsPipeline : public QRhiResource
1012{
1013public:
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
1121 Flags flags() const { return m_flags; }
1122 void setFlags(Flags f) { m_flags = f; }
1123
1124 Topology topology() const { return m_topology; }
1125 void setTopology(Topology t) { m_topology = t; }
1126
1127 CullMode cullMode() const { return m_cullMode; }
1128 void setCullMode(CullMode mode) { m_cullMode = mode; }
1129
1130 FrontFace frontFace() const { return m_frontFace; }
1131 void setFrontFace(FrontFace f) { m_frontFace = f; }
1132
1133 void setTargetBlends(std::initializer_list<TargetBlend> list) { m_targetBlends = list; }
1134 template<typename InputIterator>
1135 void setTargetBlends(InputIterator first, InputIterator last)
1136 {
1137 m_targetBlends.clear();
1138 std::copy(first, last, std::back_inserter(x&: m_targetBlends));
1139 }
1140 const TargetBlend *cbeginTargetBlends() const { return m_targetBlends.cbegin(); }
1141 const TargetBlend *cendTargetBlends() const { return m_targetBlends.cend(); }
1142
1143 bool hasDepthTest() const { return m_depthTest; }
1144 void setDepthTest(bool enable) { m_depthTest = enable; }
1145
1146 bool hasDepthWrite() const { return m_depthWrite; }
1147 void setDepthWrite(bool enable) { m_depthWrite = enable; }
1148
1149 CompareOp depthOp() const { return m_depthOp; }
1150 void setDepthOp(CompareOp op) { m_depthOp = op; }
1151
1152 bool hasStencilTest() const { return m_stencilTest; }
1153 void setStencilTest(bool enable) { m_stencilTest = enable; }
1154
1155 StencilOpState stencilFront() const { return m_stencilFront; }
1156 void setStencilFront(const StencilOpState &state) { m_stencilFront = state; }
1157
1158 StencilOpState stencilBack() const { return m_stencilBack; }
1159 void setStencilBack(const StencilOpState &state) { m_stencilBack = state; }
1160
1161 quint32 stencilReadMask() const { return m_stencilReadMask; }
1162 void setStencilReadMask(quint32 mask) { m_stencilReadMask = mask; }
1163
1164 quint32 stencilWriteMask() const { return m_stencilWriteMask; }
1165 void setStencilWriteMask(quint32 mask) { m_stencilWriteMask = mask; }
1166
1167 int sampleCount() const { return m_sampleCount; }
1168 void setSampleCount(int s) { m_sampleCount = s; }
1169
1170 float lineWidth() const { return m_lineWidth; }
1171 void setLineWidth(float width) { m_lineWidth = width; }
1172
1173 int depthBias() const { return m_depthBias; }
1174 void setDepthBias(int bias) { m_depthBias = bias; }
1175
1176 float slopeScaledDepthBias() const { return m_slopeScaledDepthBias; }
1177 void setSlopeScaledDepthBias(float bias) { m_slopeScaledDepthBias = bias; }
1178
1179 void setShaderStages(std::initializer_list<QRhiShaderStage> list) { m_shaderStages = list; }
1180 template<typename InputIterator>
1181 void setShaderStages(InputIterator first, InputIterator last)
1182 {
1183 m_shaderStages.clear();
1184 std::copy(first, last, std::back_inserter(x&: m_shaderStages));
1185 }
1186 const QRhiShaderStage *cbeginShaderStages() const { return m_shaderStages.cbegin(); }
1187 const QRhiShaderStage *cendShaderStages() const { return m_shaderStages.cend(); }
1188
1189 QRhiVertexInputLayout vertexInputLayout() const { return m_vertexInputLayout; }
1190 void setVertexInputLayout(const QRhiVertexInputLayout &layout) { m_vertexInputLayout = layout; }
1191
1192 QRhiShaderResourceBindings *shaderResourceBindings() const { return m_shaderResourceBindings; }
1193 void setShaderResourceBindings(QRhiShaderResourceBindings *srb) { m_shaderResourceBindings = srb; }
1194
1195 QRhiRenderPassDescriptor *renderPassDescriptor() const { return m_renderPassDesc; }
1196 void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc) { m_renderPassDesc = desc; }
1197
1198 virtual bool build() = 0;
1199
1200protected:
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
1225Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiGraphicsPipeline::Flags)
1226Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiGraphicsPipeline::ColorMask)
1227Q_DECLARE_TYPEINFO(QRhiGraphicsPipeline::TargetBlend, Q_MOVABLE_TYPE);
1228
1229class Q_GUI_EXPORT QRhiSwapChain : public QRhiResource
1230{
1231public:
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
1244 QWindow *window() const { return m_window; }
1245 void setWindow(QWindow *window) { m_window = window; }
1246
1247 Flags flags() const { return m_flags; }
1248 void setFlags(Flags f) { m_flags = f; }
1249
1250 QRhiRenderBuffer *depthStencil() const { return m_depthStencil; }
1251 void setDepthStencil(QRhiRenderBuffer *ds) { m_depthStencil = ds; }
1252
1253 int sampleCount() const { return m_sampleCount; }
1254 void setSampleCount(int samples) { m_sampleCount = samples; }
1255
1256 QRhiRenderPassDescriptor *renderPassDescriptor() const { return m_renderPassDesc; }
1257 void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc) { m_renderPassDesc = desc; }
1258
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
1267protected:
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
1277Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiSwapChain::Flags)
1278
1279class Q_GUI_EXPORT QRhiComputePipeline : public QRhiResource
1280{
1281public:
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
1291protected:
1292 QRhiComputePipeline(QRhiImplementation *rhi);
1293 QRhiShaderStage m_shaderStage;
1294 QRhiShaderResourceBindings *m_shaderResourceBindings = nullptr;
1295};
1296
1297class Q_GUI_EXPORT QRhiCommandBuffer : public QRhiResource
1298{
1299public:
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
1354protected:
1355 QRhiCommandBuffer(QRhiImplementation *rhi);
1356};
1357
1358struct 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
1366struct Q_GUI_EXPORT QRhiBufferReadbackResult
1367{
1368 std::function<void()> completed = nullptr;
1369 QByteArray data;
1370};
1371
1372class Q_GUI_EXPORT QRhiResourceUpdateBatch
1373{
1374public:
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
1391private:
1392 QRhiResourceUpdateBatch(QRhiImplementation *rhi);
1393 Q_DISABLE_COPY(QRhiResourceUpdateBatch)
1394 QRhiResourceUpdateBatchPrivate *d;
1395 friend class QRhiResourceUpdateBatchPrivate;
1396 friend class QRhi;
1397};
1398
1399struct Q_GUI_EXPORT QRhiInitParams
1400{
1401};
1402
1403class Q_GUI_EXPORT QRhi
1404{
1405public:
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
1555protected:
1556 QRhi();
1557
1558private:
1559 Q_DISABLE_COPY(QRhi)
1560 QRhiImplementation *d = nullptr;
1561};
1562
1563Q_DECLARE_OPERATORS_FOR_FLAGS(QRhi::Flags)
1564Q_DECLARE_OPERATORS_FOR_FLAGS(QRhi::BeginFrameFlags)
1565Q_DECLARE_OPERATORS_FOR_FLAGS(QRhi::EndFrameFlags)
1566
1567QT_END_NAMESPACE
1568
1569#endif
1570

source code of qtbase/src/gui/rhi/qrhi_p.h