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