1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QRHI_H
5#define QRHI_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is part of the RHI API, with limited compatibility guarantees.
12// Usage of this API may make your code source and binary incompatible with
13// future versions of Qt.
14//
15
16#include <QtGui/qtguiglobal.h>
17#include <QtCore/qsize.h>
18#include <QtCore/qlist.h>
19#include <QtCore/qvarlengtharray.h>
20#include <QtCore/qthread.h>
21#include <QtGui/qmatrix4x4.h>
22#include <QtGui/qcolor.h>
23#include <QtGui/qimage.h>
24#include <functional>
25#include <array>
26
27#include <rhi/qshader.h>
28
29QT_BEGIN_NAMESPACE
30
31class QWindow;
32class QRhi;
33class QRhiImplementation;
34class QRhiBuffer;
35class QRhiRenderBuffer;
36class QRhiTexture;
37class QRhiSampler;
38class QRhiCommandBuffer;
39class QRhiResourceUpdateBatch;
40class QRhiResourceUpdateBatchPrivate;
41class QRhiSwapChain;
42
43class Q_GUI_EXPORT QRhiDepthStencilClearValue
44{
45public:
46 QRhiDepthStencilClearValue() = default;
47 QRhiDepthStencilClearValue(float d, quint32 s);
48
49 float depthClearValue() const { return m_d; }
50 void setDepthClearValue(float d) { m_d = d; }
51
52 quint32 stencilClearValue() const { return m_s; }
53 void setStencilClearValue(quint32 s) { m_s = s; }
54
55private:
56 float m_d = 1.0f;
57 quint32 m_s = 0;
58
59 friend bool operator==(const QRhiDepthStencilClearValue &a, const QRhiDepthStencilClearValue &b) noexcept
60 {
61 return a.m_d == b.m_d && a.m_s == b.m_s;
62 }
63
64 friend bool operator!=(const QRhiDepthStencilClearValue &a, const QRhiDepthStencilClearValue &b) noexcept
65 {
66 return !(a == b);
67 }
68
69 friend size_t qHash(const QRhiDepthStencilClearValue &v, size_t seed = 0) noexcept
70 {
71 QtPrivate::QHashCombine hash;
72 seed = hash(seed, v.m_d);
73 seed = hash(seed, v.m_s);
74 return seed;
75 }
76};
77
78Q_DECLARE_TYPEINFO(QRhiDepthStencilClearValue, Q_RELOCATABLE_TYPE);
79
80#ifndef QT_NO_DEBUG_STREAM
81Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiDepthStencilClearValue &);
82#endif
83
84class Q_GUI_EXPORT QRhiViewport
85{
86public:
87 QRhiViewport() = default;
88 QRhiViewport(float x, float y, float w, float h, float minDepth = 0.0f, float maxDepth = 1.0f);
89
90 std::array<float, 4> viewport() const { return m_rect; }
91 void setViewport(float x, float y, float w, float h) {
92 m_rect[0] = x; m_rect[1] = y; m_rect[2] = w; m_rect[3] = h;
93 }
94
95 float minDepth() const { return m_minDepth; }
96 void setMinDepth(float minDepth) { m_minDepth = minDepth; }
97
98 float maxDepth() const { return m_maxDepth; }
99 void setMaxDepth(float maxDepth) { m_maxDepth = maxDepth; }
100
101private:
102 std::array<float, 4> m_rect { ._M_elems: { 0.0f, 0.0f, 0.0f, 0.0f } };
103 float m_minDepth = 0.0f;
104 float m_maxDepth = 1.0f;
105
106 friend bool operator==(const QRhiViewport &a, const QRhiViewport &b) noexcept
107 {
108 return a.m_rect == b.m_rect
109 && a.m_minDepth == b.m_minDepth
110 && a.m_maxDepth == b.m_maxDepth;
111 }
112
113 friend bool operator!=(const QRhiViewport &a, const QRhiViewport &b) noexcept
114 {
115 return !(a == b);
116 }
117
118 friend size_t qHash(const QRhiViewport &v, size_t seed = 0) noexcept
119 {
120 QtPrivate::QHashCombine hash;
121 seed = hash(seed, v.m_rect[0]);
122 seed = hash(seed, v.m_rect[1]);
123 seed = hash(seed, v.m_rect[2]);
124 seed = hash(seed, v.m_rect[3]);
125 seed = hash(seed, v.m_minDepth);
126 seed = hash(seed, v.m_maxDepth);
127 return seed;
128 }
129};
130
131Q_DECLARE_TYPEINFO(QRhiViewport, Q_RELOCATABLE_TYPE);
132
133#ifndef QT_NO_DEBUG_STREAM
134Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiViewport &);
135#endif
136
137class Q_GUI_EXPORT QRhiScissor
138{
139public:
140 QRhiScissor() = default;
141 QRhiScissor(int x, int y, int w, int h);
142
143 std::array<int, 4> scissor() const { return m_rect; }
144 void setScissor(int x, int y, int w, int h) {
145 m_rect[0] = x; m_rect[1] = y; m_rect[2] = w; m_rect[3] = h;
146 }
147
148private:
149 std::array<int, 4> m_rect { ._M_elems: { 0, 0, 0, 0 } };
150
151 friend bool operator==(const QRhiScissor &a, const QRhiScissor &b) noexcept
152 {
153 return a.m_rect == b.m_rect;
154 }
155
156 friend bool operator!=(const QRhiScissor &a, const QRhiScissor &b) noexcept
157 {
158 return !(a == b);
159 }
160
161 friend size_t qHash(const QRhiScissor &v, size_t seed = 0) noexcept
162 {
163 QtPrivate::QHashCombine hash;
164 seed = hash(seed, v.m_rect[0]);
165 seed = hash(seed, v.m_rect[1]);
166 seed = hash(seed, v.m_rect[2]);
167 seed = hash(seed, v.m_rect[3]);
168 return seed;
169 }
170};
171
172Q_DECLARE_TYPEINFO(QRhiScissor, Q_RELOCATABLE_TYPE);
173
174#ifndef QT_NO_DEBUG_STREAM
175Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiScissor &);
176#endif
177
178class Q_GUI_EXPORT QRhiVertexInputBinding
179{
180public:
181 enum Classification {
182 PerVertex,
183 PerInstance
184 };
185
186 QRhiVertexInputBinding() = default;
187 QRhiVertexInputBinding(quint32 stride, Classification cls = PerVertex, quint32 stepRate = 1);
188
189 quint32 stride() const { return m_stride; }
190 void setStride(quint32 s) { m_stride = s; }
191
192 Classification classification() const { return m_classification; }
193 void setClassification(Classification c) { m_classification = c; }
194
195 quint32 instanceStepRate() const { return m_instanceStepRate; }
196 void setInstanceStepRate(quint32 rate) { m_instanceStepRate = rate; }
197
198private:
199 quint32 m_stride = 0;
200 Classification m_classification = PerVertex;
201 quint32 m_instanceStepRate = 1;
202
203 friend bool operator==(const QRhiVertexInputBinding &a, const QRhiVertexInputBinding &b) noexcept
204 {
205 return a.m_stride == b.m_stride
206 && a.m_classification == b.m_classification
207 && a.m_instanceStepRate == b.m_instanceStepRate;
208 }
209
210 friend bool operator!=(const QRhiVertexInputBinding &a, const QRhiVertexInputBinding &b) noexcept
211 {
212 return !(a == b);
213 }
214
215 friend size_t qHash(const QRhiVertexInputBinding &v, size_t seed = 0) noexcept
216 {
217 QtPrivate::QHashCombine hash;
218 seed = hash(seed, v.m_stride);
219 seed = hash(seed, v.m_classification);
220 seed = hash(seed, v.m_instanceStepRate);
221 return seed;
222 }
223};
224
225Q_DECLARE_TYPEINFO(QRhiVertexInputBinding, Q_RELOCATABLE_TYPE);
226
227#ifndef QT_NO_DEBUG_STREAM
228Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiVertexInputBinding &);
229#endif
230
231class Q_GUI_EXPORT QRhiVertexInputAttribute
232{
233public:
234 enum Format {
235 Float4,
236 Float3,
237 Float2,
238 Float,
239 UNormByte4,
240 UNormByte2,
241 UNormByte,
242 UInt4,
243 UInt3,
244 UInt2,
245 UInt,
246 SInt4,
247 SInt3,
248 SInt2,
249 SInt,
250 Half4,
251 Half3,
252 Half2,
253 Half
254 };
255
256 QRhiVertexInputAttribute() = default;
257 QRhiVertexInputAttribute(int binding, int location, Format format, quint32 offset, int matrixSlice = -1);
258
259 int binding() const { return m_binding; }
260 void setBinding(int b) { m_binding = b; }
261
262 int location() const { return m_location; }
263 void setLocation(int loc) { m_location = loc; }
264
265 Format format() const { return m_format; }
266 void setFormat(Format f) { m_format = f; }
267
268 quint32 offset() const { return m_offset; }
269 void setOffset(quint32 ofs) { m_offset = ofs; }
270
271 int matrixSlice() const { return m_matrixSlice; }
272 void setMatrixSlice(int slice) { m_matrixSlice = slice; }
273
274private:
275 int m_binding = 0;
276 int m_location = 0;
277 Format m_format = Float4;
278 quint32 m_offset = 0;
279 int m_matrixSlice = -1;
280
281 friend bool operator==(const QRhiVertexInputAttribute &a, const QRhiVertexInputAttribute &b) noexcept
282 {
283 return a.m_binding == b.m_binding
284 && a.m_location == b.m_location
285 && a.m_format == b.m_format
286 && a.m_offset == b.m_offset;
287 // matrixSlice excluded intentionally
288 }
289
290 friend bool operator!=(const QRhiVertexInputAttribute &a, const QRhiVertexInputAttribute &b) noexcept
291 {
292 return !(a == b);
293 }
294
295 friend size_t qHash(const QRhiVertexInputAttribute &v, size_t seed = 0) noexcept
296 {
297 QtPrivate::QHashCombine hash;
298 seed = hash(seed, v.m_binding);
299 seed = hash(seed, v.m_location);
300 seed = hash(seed, v.m_format);
301 seed = hash(seed, v.m_offset);
302 return seed;
303 }
304};
305
306Q_DECLARE_TYPEINFO(QRhiVertexInputAttribute, Q_RELOCATABLE_TYPE);
307
308#ifndef QT_NO_DEBUG_STREAM
309Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiVertexInputAttribute &);
310#endif
311
312class Q_GUI_EXPORT QRhiVertexInputLayout
313{
314public:
315 QRhiVertexInputLayout() = default;
316
317 void setBindings(std::initializer_list<QRhiVertexInputBinding> list) { m_bindings = list; }
318 template<typename InputIterator>
319 void setBindings(InputIterator first, InputIterator last)
320 {
321 m_bindings.clear();
322 std::copy(first, last, std::back_inserter(x&: m_bindings));
323 }
324 const QRhiVertexInputBinding *cbeginBindings() const { return m_bindings.cbegin(); }
325 const QRhiVertexInputBinding *cendBindings() const { return m_bindings.cend(); }
326 const QRhiVertexInputBinding *bindingAt(qsizetype index) const { return &m_bindings.at(idx: index); }
327 qsizetype bindingCount() const { return m_bindings.count(); }
328
329 void setAttributes(std::initializer_list<QRhiVertexInputAttribute> list) { m_attributes = list; }
330 template<typename InputIterator>
331 void setAttributes(InputIterator first, InputIterator last)
332 {
333 m_attributes.clear();
334 std::copy(first, last, std::back_inserter(x&: m_attributes));
335 }
336 const QRhiVertexInputAttribute *cbeginAttributes() const { return m_attributes.cbegin(); }
337 const QRhiVertexInputAttribute *cendAttributes() const { return m_attributes.cend(); }
338 const QRhiVertexInputAttribute *attributeAt(qsizetype index) const { return &m_attributes.at(idx: index); }
339 qsizetype attributeCount() const { return m_attributes.count(); }
340
341private:
342 QVarLengthArray<QRhiVertexInputBinding, 8> m_bindings;
343 QVarLengthArray<QRhiVertexInputAttribute, 8> m_attributes;
344
345 friend bool operator==(const QRhiVertexInputLayout &a, const QRhiVertexInputLayout &b) noexcept
346 {
347 return a.m_bindings == b.m_bindings && a.m_attributes == b.m_attributes;
348 }
349
350 friend bool operator!=(const QRhiVertexInputLayout &a, const QRhiVertexInputLayout &b) noexcept
351 {
352 return !(a == b);
353 }
354
355 friend size_t qHash(const QRhiVertexInputLayout &v, size_t seed = 0) noexcept
356 {
357 QtPrivate::QHashCombine hash;
358 seed = hash(seed, v.m_bindings);
359 seed = hash(seed, v.m_attributes);
360 return seed;
361 }
362
363 friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiVertexInputLayout &);
364};
365
366#ifndef QT_NO_DEBUG_STREAM
367Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiVertexInputLayout &);
368#endif
369
370class Q_GUI_EXPORT QRhiShaderStage
371{
372public:
373 enum Type {
374 Vertex,
375 TessellationControl,
376 TessellationEvaluation,
377 Geometry,
378 Fragment,
379 Compute
380 };
381
382 QRhiShaderStage() = default;
383 QRhiShaderStage(Type type, const QShader &shader,
384 QShader::Variant v = QShader::StandardShader);
385
386 Type type() const { return m_type; }
387 void setType(Type t) { m_type = t; }
388
389 QShader shader() const { return m_shader; }
390 void setShader(const QShader &s) { m_shader = s; }
391
392 QShader::Variant shaderVariant() const { return m_shaderVariant; }
393 void setShaderVariant(QShader::Variant v) { m_shaderVariant = v; }
394
395private:
396 Type m_type = Vertex;
397 QShader m_shader;
398 QShader::Variant m_shaderVariant = QShader::StandardShader;
399
400 friend bool operator==(const QRhiShaderStage &a, const QRhiShaderStage &b) noexcept
401 {
402 return a.m_type == b.m_type
403 && a.m_shader == b.m_shader
404 && a.m_shaderVariant == b.m_shaderVariant;
405 }
406
407 friend bool operator!=(const QRhiShaderStage &a, const QRhiShaderStage &b) noexcept
408 {
409 return !(a == b);
410 }
411
412 friend size_t qHash(const QRhiShaderStage &v, size_t seed = 0) noexcept
413 {
414 QtPrivate::QHashCombine hash;
415 seed = hash(seed, v.m_type);
416 seed = hash(seed, v.m_shader);
417 seed = hash(seed, v.m_shaderVariant);
418 return seed;
419 }
420};
421
422Q_DECLARE_TYPEINFO(QRhiShaderStage, Q_RELOCATABLE_TYPE);
423
424#ifndef QT_NO_DEBUG_STREAM
425Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderStage &);
426#endif
427
428using QRhiGraphicsShaderStage = QRhiShaderStage;
429
430class Q_GUI_EXPORT QRhiShaderResourceBinding
431{
432public:
433 enum Type {
434 UniformBuffer,
435 SampledTexture,
436 Texture,
437 Sampler,
438 ImageLoad,
439 ImageStore,
440 ImageLoadStore,
441 BufferLoad,
442 BufferStore,
443 BufferLoadStore
444 };
445
446 enum StageFlag {
447 VertexStage = 1 << 0,
448 TessellationControlStage = 1 << 1,
449 TessellationEvaluationStage = 1 << 2,
450 GeometryStage = 1 << 3,
451 FragmentStage = 1 << 4,
452 ComputeStage = 1 << 5
453 };
454 Q_DECLARE_FLAGS(StageFlags, StageFlag)
455
456 QRhiShaderResourceBinding() = default;
457
458 bool isLayoutCompatible(const QRhiShaderResourceBinding &other) const;
459
460 static QRhiShaderResourceBinding uniformBuffer(int binding, StageFlags stage, QRhiBuffer *buf);
461 static QRhiShaderResourceBinding uniformBuffer(int binding, StageFlags stage, QRhiBuffer *buf, quint32 offset, quint32 size);
462 static QRhiShaderResourceBinding uniformBufferWithDynamicOffset(int binding, StageFlags stage, QRhiBuffer *buf, quint32 size);
463
464 static QRhiShaderResourceBinding sampledTexture(int binding, StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler);
465
466 struct TextureAndSampler {
467 QRhiTexture *tex;
468 QRhiSampler *sampler;
469 };
470 static QRhiShaderResourceBinding sampledTextures(int binding, StageFlags stage, int count, const TextureAndSampler *texSamplers);
471
472 static QRhiShaderResourceBinding texture(int binding, StageFlags stage, QRhiTexture *tex);
473 static QRhiShaderResourceBinding textures(int binding, StageFlags stage, int count, QRhiTexture **tex);
474 static QRhiShaderResourceBinding sampler(int binding, StageFlags stage, QRhiSampler *sampler);
475
476 static QRhiShaderResourceBinding imageLoad(int binding, StageFlags stage, QRhiTexture *tex, int level);
477 static QRhiShaderResourceBinding imageStore(int binding, StageFlags stage, QRhiTexture *tex, int level);
478 static QRhiShaderResourceBinding imageLoadStore(int binding, StageFlags stage, QRhiTexture *tex, int level);
479
480 static QRhiShaderResourceBinding bufferLoad(int binding, StageFlags stage, QRhiBuffer *buf);
481 static QRhiShaderResourceBinding bufferLoad(int binding, StageFlags stage, QRhiBuffer *buf, quint32 offset, quint32 size);
482 static QRhiShaderResourceBinding bufferStore(int binding, StageFlags stage, QRhiBuffer *buf);
483 static QRhiShaderResourceBinding bufferStore(int binding, StageFlags stage, QRhiBuffer *buf, quint32 offset, quint32 size);
484 static QRhiShaderResourceBinding bufferLoadStore(int binding, StageFlags stage, QRhiBuffer *buf);
485 static QRhiShaderResourceBinding bufferLoadStore(int binding, StageFlags stage, QRhiBuffer *buf, quint32 offset, quint32 size);
486
487 struct Data
488 {
489 int binding;
490 QRhiShaderResourceBinding::StageFlags stage;
491 QRhiShaderResourceBinding::Type type;
492 struct UniformBufferData {
493 QRhiBuffer *buf;
494 quint32 offset;
495 quint32 maybeSize;
496 bool hasDynamicOffset;
497 };
498 static const int MAX_TEX_SAMPLER_ARRAY_SIZE = 16;
499 struct TextureAndOrSamplerData {
500 int count;
501 TextureAndSampler texSamplers[MAX_TEX_SAMPLER_ARRAY_SIZE];
502 };
503 struct StorageImageData {
504 QRhiTexture *tex;
505 int level;
506 };
507 struct StorageBufferData {
508 QRhiBuffer *buf;
509 quint32 offset;
510 quint32 maybeSize;
511 };
512 union {
513 UniformBufferData ubuf;
514 TextureAndOrSamplerData stex;
515 StorageImageData simage;
516 StorageBufferData sbuf;
517 } u;
518
519 int arraySize() const
520 {
521 return type == QRhiShaderResourceBinding::SampledTexture || type == QRhiShaderResourceBinding::Texture
522 ? u.stex.count
523 : 1;
524 }
525
526 template<typename Output>
527 Output serialize(Output dst) const
528 {
529 // must write out exactly LAYOUT_DESC_ENTRIES_PER_BINDING elements here
530 *dst++ = quint32(binding);
531 *dst++ = quint32(stage);
532 *dst++ = quint32(type);
533 *dst++ = quint32(arraySize());
534 return dst;
535 }
536 };
537
538 static const int LAYOUT_DESC_ENTRIES_PER_BINDING = 4;
539
540 template<typename Output>
541 static void serializeLayoutDescription(const QRhiShaderResourceBinding *first,
542 const QRhiShaderResourceBinding *last,
543 Output dst)
544 {
545 while (first != last) {
546 dst = first->d.serialize(dst);
547 ++first;
548 }
549 }
550
551private:
552 Data d;
553 friend class QRhiImplementation;
554};
555
556Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiShaderResourceBinding::StageFlags)
557
558Q_DECLARE_TYPEINFO(QRhiShaderResourceBinding, Q_PRIMITIVE_TYPE);
559
560Q_GUI_EXPORT bool operator==(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) noexcept;
561Q_GUI_EXPORT bool operator!=(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) noexcept;
562Q_GUI_EXPORT size_t qHash(const QRhiShaderResourceBinding &b, size_t seed = 0) noexcept;
563#ifndef QT_NO_DEBUG_STREAM
564Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderResourceBinding &);
565#endif
566
567class Q_GUI_EXPORT QRhiColorAttachment
568{
569public:
570 QRhiColorAttachment() = default;
571 QRhiColorAttachment(QRhiTexture *texture);
572 QRhiColorAttachment(QRhiRenderBuffer *renderBuffer);
573
574 QRhiTexture *texture() const { return m_texture; }
575 void setTexture(QRhiTexture *tex) { m_texture = tex; }
576
577 QRhiRenderBuffer *renderBuffer() const { return m_renderBuffer; }
578 void setRenderBuffer(QRhiRenderBuffer *rb) { m_renderBuffer = rb; }
579
580 int layer() const { return m_layer; }
581 void setLayer(int layer) { m_layer = layer; }
582
583 int level() const { return m_level; }
584 void setLevel(int level) { m_level = level; }
585
586 QRhiTexture *resolveTexture() const { return m_resolveTexture; }
587 void setResolveTexture(QRhiTexture *tex) { m_resolveTexture = tex; }
588
589 int resolveLayer() const { return m_resolveLayer; }
590 void setResolveLayer(int layer) { m_resolveLayer = layer; }
591
592 int resolveLevel() const { return m_resolveLevel; }
593 void setResolveLevel(int level) { m_resolveLevel = level; }
594
595private:
596 QRhiTexture *m_texture = nullptr;
597 QRhiRenderBuffer *m_renderBuffer = nullptr;
598 int m_layer = 0;
599 int m_level = 0;
600 QRhiTexture *m_resolveTexture = nullptr;
601 int m_resolveLayer = 0;
602 int m_resolveLevel = 0;
603};
604
605Q_DECLARE_TYPEINFO(QRhiColorAttachment, Q_RELOCATABLE_TYPE);
606
607class Q_GUI_EXPORT QRhiTextureRenderTargetDescription
608{
609public:
610 QRhiTextureRenderTargetDescription() = default;
611 QRhiTextureRenderTargetDescription(const QRhiColorAttachment &colorAttachment);
612 QRhiTextureRenderTargetDescription(const QRhiColorAttachment &colorAttachment, QRhiRenderBuffer *depthStencilBuffer);
613 QRhiTextureRenderTargetDescription(const QRhiColorAttachment &colorAttachment, QRhiTexture *depthTexture);
614
615 void setColorAttachments(std::initializer_list<QRhiColorAttachment> list) { m_colorAttachments = list; }
616 template<typename InputIterator>
617 void setColorAttachments(InputIterator first, InputIterator last)
618 {
619 m_colorAttachments.clear();
620 std::copy(first, last, std::back_inserter(x&: m_colorAttachments));
621 }
622 const QRhiColorAttachment *cbeginColorAttachments() const { return m_colorAttachments.cbegin(); }
623 const QRhiColorAttachment *cendColorAttachments() const { return m_colorAttachments.cend(); }
624 const QRhiColorAttachment *colorAttachmentAt(qsizetype index) const { return &m_colorAttachments.at(idx: index); }
625 qsizetype colorAttachmentCount() const { return m_colorAttachments.count(); }
626
627 QRhiRenderBuffer *depthStencilBuffer() const { return m_depthStencilBuffer; }
628 void setDepthStencilBuffer(QRhiRenderBuffer *renderBuffer) { m_depthStencilBuffer = renderBuffer; }
629
630 QRhiTexture *depthTexture() const { return m_depthTexture; }
631 void setDepthTexture(QRhiTexture *texture) { m_depthTexture = texture; }
632
633private:
634 QVarLengthArray<QRhiColorAttachment, 8> m_colorAttachments;
635 QRhiRenderBuffer *m_depthStencilBuffer = nullptr;
636 QRhiTexture *m_depthTexture = nullptr;
637};
638
639class Q_GUI_EXPORT QRhiTextureSubresourceUploadDescription
640{
641public:
642 QRhiTextureSubresourceUploadDescription() = default;
643 explicit QRhiTextureSubresourceUploadDescription(const QImage &image);
644 QRhiTextureSubresourceUploadDescription(const void *data, quint32 size);
645 explicit QRhiTextureSubresourceUploadDescription(const QByteArray &data);
646
647 QImage image() const { return m_image; }
648 void setImage(const QImage &image) { m_image = image; }
649
650 QByteArray data() const { return m_data; }
651 void setData(const QByteArray &data) { m_data = data; }
652
653 quint32 dataStride() const { return m_dataStride; }
654 void setDataStride(quint32 stride) { m_dataStride = stride; }
655
656 QPoint destinationTopLeft() const { return m_destinationTopLeft; }
657 void setDestinationTopLeft(const QPoint &p) { m_destinationTopLeft = p; }
658
659 QSize sourceSize() const { return m_sourceSize; }
660 void setSourceSize(const QSize &size) { m_sourceSize = size; }
661
662 QPoint sourceTopLeft() const { return m_sourceTopLeft; }
663 void setSourceTopLeft(const QPoint &p) { m_sourceTopLeft = p; }
664
665private:
666 QImage m_image;
667 QByteArray m_data;
668 quint32 m_dataStride = 0;
669 QPoint m_destinationTopLeft;
670 QSize m_sourceSize;
671 QPoint m_sourceTopLeft;
672};
673
674Q_DECLARE_TYPEINFO(QRhiTextureSubresourceUploadDescription, Q_RELOCATABLE_TYPE);
675
676class Q_GUI_EXPORT QRhiTextureUploadEntry
677{
678public:
679 QRhiTextureUploadEntry() = default;
680 QRhiTextureUploadEntry(int layer, int level, const QRhiTextureSubresourceUploadDescription &desc);
681
682 int layer() const { return m_layer; }
683 void setLayer(int layer) { m_layer = layer; }
684
685 int level() const { return m_level; }
686 void setLevel(int level) { m_level = level; }
687
688 QRhiTextureSubresourceUploadDescription description() const { return m_desc; }
689 void setDescription(const QRhiTextureSubresourceUploadDescription &desc) { m_desc = desc; }
690
691private:
692 int m_layer = 0;
693 int m_level = 0;
694 QRhiTextureSubresourceUploadDescription m_desc;
695};
696
697Q_DECLARE_TYPEINFO(QRhiTextureUploadEntry, Q_RELOCATABLE_TYPE);
698
699class Q_GUI_EXPORT QRhiTextureUploadDescription
700{
701public:
702 QRhiTextureUploadDescription() = default;
703 QRhiTextureUploadDescription(const QRhiTextureUploadEntry &entry);
704 QRhiTextureUploadDescription(std::initializer_list<QRhiTextureUploadEntry> list);
705
706 void setEntries(std::initializer_list<QRhiTextureUploadEntry> list) { m_entries = list; }
707 template<typename InputIterator>
708 void setEntries(InputIterator first, InputIterator last)
709 {
710 m_entries.clear();
711 std::copy(first, last, std::back_inserter(x&: m_entries));
712 }
713 const QRhiTextureUploadEntry *cbeginEntries() const { return m_entries.cbegin(); }
714 const QRhiTextureUploadEntry *cendEntries() const { return m_entries.cend(); }
715 const QRhiTextureUploadEntry *entryAt(qsizetype index) const { return &m_entries.at(idx: index); }
716 qsizetype entryCount() const { return m_entries.count(); }
717
718private:
719 QVarLengthArray<QRhiTextureUploadEntry, 16> m_entries;
720};
721
722class Q_GUI_EXPORT QRhiTextureCopyDescription
723{
724public:
725 QRhiTextureCopyDescription() = default;
726
727 QSize pixelSize() const { return m_pixelSize; }
728 void setPixelSize(const QSize &sz) { m_pixelSize = sz; }
729
730 int sourceLayer() const { return m_sourceLayer; }
731 void setSourceLayer(int layer) { m_sourceLayer = layer; }
732
733 int sourceLevel() const { return m_sourceLevel; }
734 void setSourceLevel(int level) { m_sourceLevel = level; }
735
736 QPoint sourceTopLeft() const { return m_sourceTopLeft; }
737 void setSourceTopLeft(const QPoint &p) { m_sourceTopLeft = p; }
738
739 int destinationLayer() const { return m_destinationLayer; }
740 void setDestinationLayer(int layer) { m_destinationLayer = layer; }
741
742 int destinationLevel() const { return m_destinationLevel; }
743 void setDestinationLevel(int level) { m_destinationLevel = level; }
744
745 QPoint destinationTopLeft() const { return m_destinationTopLeft; }
746 void setDestinationTopLeft(const QPoint &p) { m_destinationTopLeft = p; }
747
748private:
749 QSize m_pixelSize;
750 int m_sourceLayer = 0;
751 int m_sourceLevel = 0;
752 QPoint m_sourceTopLeft;
753 int m_destinationLayer = 0;
754 int m_destinationLevel = 0;
755 QPoint m_destinationTopLeft;
756};
757
758Q_DECLARE_TYPEINFO(QRhiTextureCopyDescription, Q_RELOCATABLE_TYPE);
759
760class Q_GUI_EXPORT QRhiReadbackDescription
761{
762public:
763 QRhiReadbackDescription() = default;
764 QRhiReadbackDescription(QRhiTexture *texture);
765
766 QRhiTexture *texture() const { return m_texture; }
767 void setTexture(QRhiTexture *tex) { m_texture = tex; }
768
769 int layer() const { return m_layer; }
770 void setLayer(int layer) { m_layer = layer; }
771
772 int level() const { return m_level; }
773 void setLevel(int level) { m_level = level; }
774
775private:
776 QRhiTexture *m_texture = nullptr;
777 int m_layer = 0;
778 int m_level = 0;
779};
780
781Q_DECLARE_TYPEINFO(QRhiReadbackDescription, Q_RELOCATABLE_TYPE);
782
783struct Q_GUI_EXPORT QRhiNativeHandles
784{
785};
786
787class Q_GUI_EXPORT QRhiResource
788{
789public:
790 enum Type {
791 Buffer,
792 Texture,
793 Sampler,
794 RenderBuffer,
795 RenderPassDescriptor,
796 SwapChainRenderTarget,
797 TextureRenderTarget,
798 ShaderResourceBindings,
799 GraphicsPipeline,
800 SwapChain,
801 ComputePipeline,
802 CommandBuffer
803 };
804
805 virtual ~QRhiResource();
806
807 virtual Type resourceType() const = 0;
808
809 virtual void destroy() = 0;
810
811 void deleteLater();
812
813 QByteArray name() const;
814 void setName(const QByteArray &name);
815
816 quint64 globalResourceId() const;
817
818 QRhi *rhi() const;
819
820protected:
821 QRhiResource(QRhiImplementation *rhi);
822 Q_DISABLE_COPY(QRhiResource)
823 friend class QRhiImplementation;
824 QRhiImplementation *m_rhi = nullptr;
825 quint64 m_id;
826 QByteArray m_objectName;
827};
828
829class Q_GUI_EXPORT QRhiBuffer : public QRhiResource
830{
831public:
832 enum Type {
833 Immutable,
834 Static,
835 Dynamic
836 };
837
838 enum UsageFlag {
839 VertexBuffer = 1 << 0,
840 IndexBuffer = 1 << 1,
841 UniformBuffer = 1 << 2,
842 StorageBuffer = 1 << 3
843 };
844 Q_DECLARE_FLAGS(UsageFlags, UsageFlag)
845
846 struct NativeBuffer {
847 const void *objects[3];
848 int slotCount;
849 };
850
851 QRhiResource::Type resourceType() const override;
852
853 Type type() const { return m_type; }
854 void setType(Type t) { m_type = t; }
855
856 UsageFlags usage() const { return m_usage; }
857 void setUsage(UsageFlags u) { m_usage = u; }
858
859 quint32 size() const { return m_size; }
860 void setSize(quint32 sz) { m_size = sz; }
861
862 virtual bool create() = 0;
863
864 virtual NativeBuffer nativeBuffer();
865
866 virtual char *beginFullDynamicBufferUpdateForCurrentFrame();
867 virtual void endFullDynamicBufferUpdateForCurrentFrame();
868
869protected:
870 QRhiBuffer(QRhiImplementation *rhi, Type type_, UsageFlags usage_, quint32 size_);
871 Type m_type;
872 UsageFlags m_usage;
873 quint32 m_size;
874};
875
876Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiBuffer::UsageFlags)
877
878class Q_GUI_EXPORT QRhiTexture : public QRhiResource
879{
880public:
881 enum Flag {
882 RenderTarget = 1 << 0,
883 CubeMap = 1 << 2,
884 MipMapped = 1 << 3,
885 sRGB = 1 << 4,
886 UsedAsTransferSource = 1 << 5,
887 UsedWithGenerateMips = 1 << 6,
888 UsedWithLoadStore = 1 << 7,
889 UsedAsCompressedAtlas = 1 << 8,
890 ExternalOES = 1 << 9,
891 ThreeDimensional = 1 << 10,
892 TextureRectangleGL = 1 << 11,
893 TextureArray = 1 << 12,
894 OneDimensional = 1 << 13
895 };
896 Q_DECLARE_FLAGS(Flags, Flag)
897
898 enum Format {
899 UnknownFormat,
900
901 RGBA8,
902 BGRA8,
903 R8,
904 RG8,
905 R16,
906 RG16,
907 RED_OR_ALPHA8,
908
909 RGBA16F,
910 RGBA32F,
911 R16F,
912 R32F,
913
914 RGB10A2,
915
916 D16,
917 D24,
918 D24S8,
919 D32F,
920
921 BC1,
922 BC2,
923 BC3,
924 BC4,
925 BC5,
926 BC6H,
927 BC7,
928
929 ETC2_RGB8,
930 ETC2_RGB8A1,
931 ETC2_RGBA8,
932
933 ASTC_4x4,
934 ASTC_5x4,
935 ASTC_5x5,
936 ASTC_6x5,
937 ASTC_6x6,
938 ASTC_8x5,
939 ASTC_8x6,
940 ASTC_8x8,
941 ASTC_10x5,
942 ASTC_10x6,
943 ASTC_10x8,
944 ASTC_10x10,
945 ASTC_12x10,
946 ASTC_12x12
947 };
948
949 struct NativeTexture {
950 quint64 object;
951 int layout; // or state
952 };
953
954 QRhiResource::Type resourceType() const override;
955
956 Format format() const { return m_format; }
957 void setFormat(Format fmt) { m_format = fmt; }
958
959 QSize pixelSize() const { return m_pixelSize; }
960 void setPixelSize(const QSize &sz) { m_pixelSize = sz; }
961
962 int depth() const { return m_depth; }
963 void setDepth(int depth) { m_depth = depth; }
964
965 int arraySize() const { return m_arraySize; }
966 void setArraySize(int arraySize) { m_arraySize = arraySize; }
967
968 int arrayRangeStart() const { return m_arrayRangeStart; }
969 int arrayRangeLength() const { return m_arrayRangeLength; }
970 void setArrayRange(int startIndex, int count)
971 {
972 m_arrayRangeStart = startIndex;
973 m_arrayRangeLength = count;
974 }
975
976 Flags flags() const { return m_flags; }
977 void setFlags(Flags f) { m_flags = f; }
978
979 int sampleCount() const { return m_sampleCount; }
980 void setSampleCount(int s) { m_sampleCount = s; }
981
982 virtual bool create() = 0;
983 virtual NativeTexture nativeTexture();
984 virtual bool createFrom(NativeTexture src);
985 virtual void setNativeLayout(int layout);
986
987protected:
988 QRhiTexture(QRhiImplementation *rhi, Format format_, const QSize &pixelSize_, int depth_,
989 int arraySize_, int sampleCount_, Flags flags_);
990 Format m_format;
991 QSize m_pixelSize;
992 int m_depth;
993 int m_arraySize;
994 int m_sampleCount;
995 Flags m_flags;
996 int m_arrayRangeStart = -1;
997 int m_arrayRangeLength = -1;
998};
999
1000Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiTexture::Flags)
1001
1002class Q_GUI_EXPORT QRhiSampler : public QRhiResource
1003{
1004public:
1005 enum Filter {
1006 None,
1007 Nearest,
1008 Linear
1009 };
1010
1011 enum AddressMode {
1012 Repeat,
1013 ClampToEdge,
1014 Mirror,
1015 };
1016
1017 enum CompareOp {
1018 Never,
1019 Less,
1020 Equal,
1021 LessOrEqual,
1022 Greater,
1023 NotEqual,
1024 GreaterOrEqual,
1025 Always
1026 };
1027
1028 QRhiResource::Type resourceType() const override;
1029
1030 Filter magFilter() const { return m_magFilter; }
1031 void setMagFilter(Filter f) { m_magFilter = f; }
1032
1033 Filter minFilter() const { return m_minFilter; }
1034 void setMinFilter(Filter f) { m_minFilter = f; }
1035
1036 Filter mipmapMode() const { return m_mipmapMode; }
1037 void setMipmapMode(Filter f) { m_mipmapMode = f; }
1038
1039 AddressMode addressU() const { return m_addressU; }
1040 void setAddressU(AddressMode mode) { m_addressU = mode; }
1041
1042 AddressMode addressV() const { return m_addressV; }
1043 void setAddressV(AddressMode mode) { m_addressV = mode; }
1044
1045 AddressMode addressW() const { return m_addressW; }
1046 void setAddressW(AddressMode mode) { m_addressW = mode; }
1047
1048 CompareOp textureCompareOp() const { return m_compareOp; }
1049 void setTextureCompareOp(CompareOp op) { m_compareOp = op; }
1050
1051 virtual bool create() = 0;
1052
1053protected:
1054 QRhiSampler(QRhiImplementation *rhi,
1055 Filter magFilter_, Filter minFilter_, Filter mipmapMode_,
1056 AddressMode u_, AddressMode v_, AddressMode w_);
1057 Filter m_magFilter;
1058 Filter m_minFilter;
1059 Filter m_mipmapMode;
1060 AddressMode m_addressU;
1061 AddressMode m_addressV;
1062 AddressMode m_addressW;
1063 CompareOp m_compareOp;
1064};
1065
1066class Q_GUI_EXPORT QRhiRenderBuffer : public QRhiResource
1067{
1068public:
1069 enum Type {
1070 DepthStencil,
1071 Color
1072 };
1073
1074 enum Flag {
1075 UsedWithSwapChainOnly = 1 << 0
1076 };
1077 Q_DECLARE_FLAGS(Flags, Flag)
1078
1079 struct NativeRenderBuffer {
1080 quint64 object;
1081 };
1082
1083 QRhiResource::Type resourceType() const override;
1084
1085 Type type() const { return m_type; }
1086 void setType(Type t) { m_type = t; }
1087
1088 QSize pixelSize() const { return m_pixelSize; }
1089 void setPixelSize(const QSize &sz) { m_pixelSize = sz; }
1090
1091 int sampleCount() const { return m_sampleCount; }
1092 void setSampleCount(int s) { m_sampleCount = s; }
1093
1094 Flags flags() const { return m_flags; }
1095 void setFlags(Flags f) { m_flags = f; }
1096
1097 virtual bool create() = 0;
1098 virtual bool createFrom(NativeRenderBuffer src);
1099
1100 virtual QRhiTexture::Format backingFormat() const = 0;
1101
1102protected:
1103 QRhiRenderBuffer(QRhiImplementation *rhi, Type type_, const QSize &pixelSize_,
1104 int sampleCount_, Flags flags_, QRhiTexture::Format backingFormatHint_);
1105 Type m_type;
1106 QSize m_pixelSize;
1107 int m_sampleCount;
1108 Flags m_flags;
1109 QRhiTexture::Format m_backingFormatHint;
1110};
1111
1112Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiRenderBuffer::Flags)
1113
1114class Q_GUI_EXPORT QRhiRenderPassDescriptor : public QRhiResource
1115{
1116public:
1117 QRhiResource::Type resourceType() const override;
1118
1119 virtual bool isCompatible(const QRhiRenderPassDescriptor *other) const = 0;
1120 virtual const QRhiNativeHandles *nativeHandles();
1121
1122 virtual QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() const = 0;
1123
1124 virtual QVector<quint32> serializedFormat() const = 0;
1125
1126protected:
1127 QRhiRenderPassDescriptor(QRhiImplementation *rhi);
1128};
1129
1130class Q_GUI_EXPORT QRhiRenderTarget : public QRhiResource
1131{
1132public:
1133 virtual QSize pixelSize() const = 0;
1134 virtual float devicePixelRatio() const = 0;
1135 virtual int sampleCount() const = 0;
1136
1137 QRhiRenderPassDescriptor *renderPassDescriptor() const { return m_renderPassDesc; }
1138 void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc) { m_renderPassDesc = desc; }
1139
1140protected:
1141 QRhiRenderTarget(QRhiImplementation *rhi);
1142 QRhiRenderPassDescriptor *m_renderPassDesc = nullptr;
1143};
1144
1145class Q_GUI_EXPORT QRhiSwapChainRenderTarget : public QRhiRenderTarget
1146{
1147public:
1148 QRhiResource::Type resourceType() const override;
1149 QRhiSwapChain *swapChain() const { return m_swapchain; }
1150
1151protected:
1152 QRhiSwapChainRenderTarget(QRhiImplementation *rhi, QRhiSwapChain *swapchain_);
1153 QRhiSwapChain *m_swapchain;
1154};
1155
1156class Q_GUI_EXPORT QRhiTextureRenderTarget : public QRhiRenderTarget
1157{
1158public:
1159 enum Flag {
1160 PreserveColorContents = 1 << 0,
1161 PreserveDepthStencilContents = 1 << 1
1162 };
1163 Q_DECLARE_FLAGS(Flags, Flag)
1164
1165 QRhiResource::Type resourceType() const override;
1166
1167 QRhiTextureRenderTargetDescription description() const { return m_desc; }
1168 void setDescription(const QRhiTextureRenderTargetDescription &desc) { m_desc = desc; }
1169
1170 Flags flags() const { return m_flags; }
1171 void setFlags(Flags f) { m_flags = f; }
1172
1173 virtual QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() = 0;
1174
1175 virtual bool create() = 0;
1176
1177protected:
1178 QRhiTextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc_, Flags flags_);
1179 QRhiTextureRenderTargetDescription m_desc;
1180 Flags m_flags;
1181};
1182
1183Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiTextureRenderTarget::Flags)
1184
1185class Q_GUI_EXPORT QRhiShaderResourceBindings : public QRhiResource
1186{
1187public:
1188 QRhiResource::Type resourceType() const override;
1189
1190 void setBindings(std::initializer_list<QRhiShaderResourceBinding> list) { m_bindings = list; }
1191 template<typename InputIterator>
1192 void setBindings(InputIterator first, InputIterator last)
1193 {
1194 m_bindings.clear();
1195 std::copy(first, last, std::back_inserter(x&: m_bindings));
1196 }
1197 const QRhiShaderResourceBinding *cbeginBindings() const { return m_bindings.cbegin(); }
1198 const QRhiShaderResourceBinding *cendBindings() const { return m_bindings.cend(); }
1199 const QRhiShaderResourceBinding *bindingAt(qsizetype index) const { return &m_bindings.at(idx: index); }
1200 qsizetype bindingCount() const { return m_bindings.count(); }
1201
1202 bool isLayoutCompatible(const QRhiShaderResourceBindings *other) const;
1203
1204 QVector<quint32> serializedLayoutDescription() const { return m_layoutDesc; }
1205
1206 virtual bool create() = 0;
1207
1208 enum UpdateFlag {
1209 BindingsAreSorted = 0x01
1210 };
1211 Q_DECLARE_FLAGS(UpdateFlags, UpdateFlag)
1212
1213 virtual void updateResources(UpdateFlags flags = {}) = 0;
1214
1215protected:
1216 static const int BINDING_PREALLOC = 12;
1217 QRhiShaderResourceBindings(QRhiImplementation *rhi);
1218 QVarLengthArray<QRhiShaderResourceBinding, BINDING_PREALLOC> m_bindings;
1219 size_t m_layoutDescHash = 0;
1220 // Intentionally not using QVLA for m_layoutDesc: clients like Qt Quick are much
1221 // better served with an implicitly shared container here, because they will likely
1222 // throw this directly into structs serving as cache keys.
1223 QVector<quint32> m_layoutDesc;
1224 friend class QRhiImplementation;
1225#ifndef QT_NO_DEBUG_STREAM
1226 friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderResourceBindings &);
1227#endif
1228};
1229
1230Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiShaderResourceBindings::UpdateFlags)
1231
1232#ifndef QT_NO_DEBUG_STREAM
1233Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderResourceBindings &);
1234#endif
1235
1236class Q_GUI_EXPORT QRhiGraphicsPipeline : public QRhiResource
1237{
1238public:
1239 enum Flag {
1240 UsesBlendConstants = 1 << 0,
1241 UsesStencilRef = 1 << 1,
1242 UsesScissor = 1 << 2,
1243 CompileShadersWithDebugInfo = 1 << 3
1244 };
1245 Q_DECLARE_FLAGS(Flags, Flag)
1246
1247 enum Topology {
1248 Triangles,
1249 TriangleStrip,
1250 TriangleFan,
1251 Lines,
1252 LineStrip,
1253 Points,
1254 Patches
1255 };
1256
1257 enum CullMode {
1258 None,
1259 Front,
1260 Back
1261 };
1262
1263 enum FrontFace {
1264 CCW,
1265 CW
1266 };
1267
1268 enum ColorMaskComponent {
1269 R = 1 << 0,
1270 G = 1 << 1,
1271 B = 1 << 2,
1272 A = 1 << 3
1273 };
1274 Q_DECLARE_FLAGS(ColorMask, ColorMaskComponent)
1275
1276 enum BlendFactor {
1277 Zero,
1278 One,
1279 SrcColor,
1280 OneMinusSrcColor,
1281 DstColor,
1282 OneMinusDstColor,
1283 SrcAlpha,
1284 OneMinusSrcAlpha,
1285 DstAlpha,
1286 OneMinusDstAlpha,
1287 ConstantColor,
1288 OneMinusConstantColor,
1289 ConstantAlpha,
1290 OneMinusConstantAlpha,
1291 SrcAlphaSaturate,
1292 Src1Color,
1293 OneMinusSrc1Color,
1294 Src1Alpha,
1295 OneMinusSrc1Alpha
1296 };
1297
1298 enum BlendOp {
1299 Add,
1300 Subtract,
1301 ReverseSubtract,
1302 Min,
1303 Max
1304 };
1305
1306 struct TargetBlend {
1307 ColorMask colorWrite = ColorMask(0xF); // R | G | B | A
1308 bool enable = false;
1309 BlendFactor srcColor = One;
1310 BlendFactor dstColor = OneMinusSrcAlpha;
1311 BlendOp opColor = Add;
1312 BlendFactor srcAlpha = One;
1313 BlendFactor dstAlpha = OneMinusSrcAlpha;
1314 BlendOp opAlpha = Add;
1315 };
1316
1317 enum CompareOp {
1318 Never,
1319 Less,
1320 Equal,
1321 LessOrEqual,
1322 Greater,
1323 NotEqual,
1324 GreaterOrEqual,
1325 Always
1326 };
1327
1328 enum StencilOp {
1329 StencilZero,
1330 Keep,
1331 Replace,
1332 IncrementAndClamp,
1333 DecrementAndClamp,
1334 Invert,
1335 IncrementAndWrap,
1336 DecrementAndWrap
1337 };
1338
1339 struct StencilOpState {
1340 StencilOp failOp = Keep;
1341 StencilOp depthFailOp = Keep;
1342 StencilOp passOp = Keep;
1343 CompareOp compareOp = Always;
1344 };
1345
1346 enum PolygonMode {
1347 Fill,
1348 Line
1349 };
1350
1351 QRhiResource::Type resourceType() const override;
1352
1353 Flags flags() const { return m_flags; }
1354 void setFlags(Flags f) { m_flags = f; }
1355
1356 Topology topology() const { return m_topology; }
1357 void setTopology(Topology t) { m_topology = t; }
1358
1359 CullMode cullMode() const { return m_cullMode; }
1360 void setCullMode(CullMode mode) { m_cullMode = mode; }
1361
1362 FrontFace frontFace() const { return m_frontFace; }
1363 void setFrontFace(FrontFace f) { m_frontFace = f; }
1364
1365 void setTargetBlends(std::initializer_list<TargetBlend> list) { m_targetBlends = list; }
1366 template<typename InputIterator>
1367 void setTargetBlends(InputIterator first, InputIterator last)
1368 {
1369 m_targetBlends.clear();
1370 std::copy(first, last, std::back_inserter(x&: m_targetBlends));
1371 }
1372 const TargetBlend *cbeginTargetBlends() const { return m_targetBlends.cbegin(); }
1373 const TargetBlend *cendTargetBlends() const { return m_targetBlends.cend(); }
1374 const TargetBlend *targetBlendAt(qsizetype index) const { return &m_targetBlends.at(idx: index); }
1375 qsizetype targetBlendCount() const { return m_targetBlends.count(); }
1376
1377 bool hasDepthTest() const { return m_depthTest; }
1378 void setDepthTest(bool enable) { m_depthTest = enable; }
1379
1380 bool hasDepthWrite() const { return m_depthWrite; }
1381 void setDepthWrite(bool enable) { m_depthWrite = enable; }
1382
1383 CompareOp depthOp() const { return m_depthOp; }
1384 void setDepthOp(CompareOp op) { m_depthOp = op; }
1385
1386 bool hasStencilTest() const { return m_stencilTest; }
1387 void setStencilTest(bool enable) { m_stencilTest = enable; }
1388
1389 StencilOpState stencilFront() const { return m_stencilFront; }
1390 void setStencilFront(const StencilOpState &state) { m_stencilFront = state; }
1391
1392 StencilOpState stencilBack() const { return m_stencilBack; }
1393 void setStencilBack(const StencilOpState &state) { m_stencilBack = state; }
1394
1395 quint32 stencilReadMask() const { return m_stencilReadMask; }
1396 void setStencilReadMask(quint32 mask) { m_stencilReadMask = mask; }
1397
1398 quint32 stencilWriteMask() const { return m_stencilWriteMask; }
1399 void setStencilWriteMask(quint32 mask) { m_stencilWriteMask = mask; }
1400
1401 int sampleCount() const { return m_sampleCount; }
1402 void setSampleCount(int s) { m_sampleCount = s; }
1403
1404 float lineWidth() const { return m_lineWidth; }
1405 void setLineWidth(float width) { m_lineWidth = width; }
1406
1407 int depthBias() const { return m_depthBias; }
1408 void setDepthBias(int bias) { m_depthBias = bias; }
1409
1410 float slopeScaledDepthBias() const { return m_slopeScaledDepthBias; }
1411 void setSlopeScaledDepthBias(float bias) { m_slopeScaledDepthBias = bias; }
1412
1413 void setShaderStages(std::initializer_list<QRhiShaderStage> list) { m_shaderStages = list; }
1414 template<typename InputIterator>
1415 void setShaderStages(InputIterator first, InputIterator last)
1416 {
1417 m_shaderStages.clear();
1418 std::copy(first, last, std::back_inserter(x&: m_shaderStages));
1419 }
1420 const QRhiShaderStage *cbeginShaderStages() const { return m_shaderStages.cbegin(); }
1421 const QRhiShaderStage *cendShaderStages() const { return m_shaderStages.cend(); }
1422 const QRhiShaderStage *shaderStageAt(qsizetype index) const { return &m_shaderStages.at(idx: index); }
1423 qsizetype shaderStageCount() const { return m_shaderStages.count(); }
1424
1425 QRhiVertexInputLayout vertexInputLayout() const { return m_vertexInputLayout; }
1426 void setVertexInputLayout(const QRhiVertexInputLayout &layout) { m_vertexInputLayout = layout; }
1427
1428 QRhiShaderResourceBindings *shaderResourceBindings() const { return m_shaderResourceBindings; }
1429 void setShaderResourceBindings(QRhiShaderResourceBindings *srb) { m_shaderResourceBindings = srb; }
1430
1431 QRhiRenderPassDescriptor *renderPassDescriptor() const { return m_renderPassDesc; }
1432 void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc) { m_renderPassDesc = desc; }
1433
1434 int patchControlPointCount() const { return m_patchControlPointCount; }
1435 void setPatchControlPointCount(int count) { m_patchControlPointCount = count; }
1436
1437 PolygonMode polygonMode() const {return m_polygonMode; }
1438 void setPolygonMode(PolygonMode mode) {m_polygonMode = mode; }
1439
1440 virtual bool create() = 0;
1441
1442protected:
1443 QRhiGraphicsPipeline(QRhiImplementation *rhi);
1444 Flags m_flags;
1445 Topology m_topology = Triangles;
1446 CullMode m_cullMode = None;
1447 FrontFace m_frontFace = CCW;
1448 QVarLengthArray<TargetBlend, 8> m_targetBlends;
1449 bool m_depthTest = false;
1450 bool m_depthWrite = false;
1451 CompareOp m_depthOp = Less;
1452 bool m_stencilTest = false;
1453 StencilOpState m_stencilFront;
1454 StencilOpState m_stencilBack;
1455 quint32 m_stencilReadMask = 0xFF;
1456 quint32 m_stencilWriteMask = 0xFF;
1457 int m_sampleCount = 1;
1458 float m_lineWidth = 1.0f;
1459 int m_depthBias = 0;
1460 float m_slopeScaledDepthBias = 0.0f;
1461 int m_patchControlPointCount = 3;
1462 PolygonMode m_polygonMode = Fill;
1463 QVarLengthArray<QRhiShaderStage, 4> m_shaderStages;
1464 QRhiVertexInputLayout m_vertexInputLayout;
1465 QRhiShaderResourceBindings *m_shaderResourceBindings = nullptr;
1466 QRhiRenderPassDescriptor *m_renderPassDesc = nullptr;
1467};
1468
1469Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiGraphicsPipeline::Flags)
1470Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiGraphicsPipeline::ColorMask)
1471Q_DECLARE_TYPEINFO(QRhiGraphicsPipeline::TargetBlend, Q_RELOCATABLE_TYPE);
1472
1473struct QRhiSwapChainHdrInfo
1474{
1475 bool isHardCodedDefaults;
1476 enum LimitsType {
1477 LuminanceInNits,
1478 ColorComponentValue
1479 };
1480 LimitsType limitsType;
1481 union {
1482 struct {
1483 float minLuminance;
1484 float maxLuminance;
1485 } luminanceInNits;
1486 struct {
1487 float maxColorComponentValue;
1488 float maxPotentialColorComponentValue;
1489 } colorComponentValue;
1490 } limits;
1491};
1492
1493Q_DECLARE_TYPEINFO(QRhiSwapChainHdrInfo, Q_RELOCATABLE_TYPE);
1494
1495#ifndef QT_NO_DEBUG_STREAM
1496Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiSwapChainHdrInfo &);
1497#endif
1498
1499struct QRhiSwapChainProxyData
1500{
1501 void *reserved[2] = {};
1502};
1503
1504class Q_GUI_EXPORT QRhiSwapChain : public QRhiResource
1505{
1506public:
1507 enum Flag {
1508 SurfaceHasPreMulAlpha = 1 << 0,
1509 SurfaceHasNonPreMulAlpha = 1 << 1,
1510 sRGB = 1 << 2,
1511 UsedAsTransferSource = 1 << 3,
1512 NoVSync = 1 << 4,
1513 MinimalBufferCount = 1 << 5
1514 };
1515 Q_DECLARE_FLAGS(Flags, Flag)
1516
1517 enum Format {
1518 SDR,
1519 HDRExtendedSrgbLinear,
1520 HDR10
1521 };
1522
1523 enum StereoTargetBuffer {
1524 LeftBuffer,
1525 RightBuffer
1526 };
1527
1528 QRhiResource::Type resourceType() const override;
1529
1530 QWindow *window() const { return m_window; }
1531 void setWindow(QWindow *window) { m_window = window; }
1532
1533 QRhiSwapChainProxyData proxyData() const { return m_proxyData; }
1534 void setProxyData(const QRhiSwapChainProxyData &d) { m_proxyData = d; }
1535
1536 Flags flags() const { return m_flags; }
1537 void setFlags(Flags f) { m_flags = f; }
1538
1539 Format format() const { return m_format; }
1540 void setFormat(Format f) { m_format = f; }
1541
1542 QRhiRenderBuffer *depthStencil() const { return m_depthStencil; }
1543 void setDepthStencil(QRhiRenderBuffer *ds) { m_depthStencil = ds; }
1544
1545 int sampleCount() const { return m_sampleCount; }
1546 void setSampleCount(int samples) { m_sampleCount = samples; }
1547
1548 QRhiRenderPassDescriptor *renderPassDescriptor() const { return m_renderPassDesc; }
1549 void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc) { m_renderPassDesc = desc; }
1550
1551 QSize currentPixelSize() const { return m_currentPixelSize; }
1552
1553 virtual QRhiCommandBuffer *currentFrameCommandBuffer() = 0;
1554 virtual QRhiRenderTarget *currentFrameRenderTarget() = 0;
1555 virtual QRhiRenderTarget *currentFrameRenderTarget(StereoTargetBuffer targetBuffer);
1556 virtual QSize surfacePixelSize() = 0;
1557 virtual bool isFormatSupported(Format f) = 0;
1558 virtual QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() = 0;
1559 virtual bool createOrResize() = 0;
1560 virtual QRhiSwapChainHdrInfo hdrInfo();
1561
1562protected:
1563 QRhiSwapChain(QRhiImplementation *rhi);
1564 QWindow *m_window = nullptr;
1565 Flags m_flags;
1566 Format m_format = SDR;
1567 QRhiRenderBuffer *m_depthStencil = nullptr;
1568 int m_sampleCount = 1;
1569 QRhiRenderPassDescriptor *m_renderPassDesc = nullptr;
1570 QSize m_currentPixelSize;
1571 QRhiSwapChainProxyData m_proxyData;
1572};
1573
1574Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiSwapChain::Flags)
1575
1576class Q_GUI_EXPORT QRhiComputePipeline : public QRhiResource
1577{
1578public:
1579 enum Flag {
1580 CompileShadersWithDebugInfo = 1 << 0
1581 };
1582 Q_DECLARE_FLAGS(Flags, Flag)
1583
1584 QRhiResource::Type resourceType() const override;
1585 virtual bool create() = 0;
1586
1587 Flags flags() const { return m_flags; }
1588 void setFlags(Flags f) { m_flags = f; }
1589
1590 QRhiShaderStage shaderStage() const { return m_shaderStage; }
1591 void setShaderStage(const QRhiShaderStage &stage) { m_shaderStage = stage; }
1592
1593 QRhiShaderResourceBindings *shaderResourceBindings() const { return m_shaderResourceBindings; }
1594 void setShaderResourceBindings(QRhiShaderResourceBindings *srb) { m_shaderResourceBindings = srb; }
1595
1596protected:
1597 QRhiComputePipeline(QRhiImplementation *rhi);
1598 Flags m_flags;
1599 QRhiShaderStage m_shaderStage;
1600 QRhiShaderResourceBindings *m_shaderResourceBindings = nullptr;
1601};
1602
1603Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiComputePipeline::Flags)
1604
1605class Q_GUI_EXPORT QRhiCommandBuffer : public QRhiResource
1606{
1607public:
1608 enum IndexFormat {
1609 IndexUInt16,
1610 IndexUInt32
1611 };
1612
1613 enum BeginPassFlag {
1614 ExternalContent = 0x01,
1615 DoNotTrackResourcesForCompute = 0x02
1616 };
1617 Q_DECLARE_FLAGS(BeginPassFlags, BeginPassFlag)
1618
1619 QRhiResource::Type resourceType() const override;
1620
1621 void resourceUpdate(QRhiResourceUpdateBatch *resourceUpdates);
1622
1623 void beginPass(QRhiRenderTarget *rt,
1624 const QColor &colorClearValue,
1625 const QRhiDepthStencilClearValue &depthStencilClearValue,
1626 QRhiResourceUpdateBatch *resourceUpdates = nullptr,
1627 BeginPassFlags flags = {});
1628 void endPass(QRhiResourceUpdateBatch *resourceUpdates = nullptr);
1629
1630 void setGraphicsPipeline(QRhiGraphicsPipeline *ps);
1631 using DynamicOffset = QPair<int, quint32>; // binding, offset
1632 void setShaderResources(QRhiShaderResourceBindings *srb = nullptr,
1633 int dynamicOffsetCount = 0,
1634 const DynamicOffset *dynamicOffsets = nullptr);
1635 using VertexInput = QPair<QRhiBuffer *, quint32>; // buffer, offset
1636 void setVertexInput(int startBinding, int bindingCount, const VertexInput *bindings,
1637 QRhiBuffer *indexBuf = nullptr, quint32 indexOffset = 0,
1638 IndexFormat indexFormat = IndexUInt16);
1639
1640 void setViewport(const QRhiViewport &viewport);
1641 void setScissor(const QRhiScissor &scissor);
1642 void setBlendConstants(const QColor &c);
1643 void setStencilRef(quint32 refValue);
1644
1645 void draw(quint32 vertexCount,
1646 quint32 instanceCount = 1,
1647 quint32 firstVertex = 0,
1648 quint32 firstInstance = 0);
1649
1650 void drawIndexed(quint32 indexCount,
1651 quint32 instanceCount = 1,
1652 quint32 firstIndex = 0,
1653 qint32 vertexOffset = 0,
1654 quint32 firstInstance = 0);
1655
1656 void debugMarkBegin(const QByteArray &name);
1657 void debugMarkEnd();
1658 void debugMarkMsg(const QByteArray &msg);
1659
1660 void beginComputePass(QRhiResourceUpdateBatch *resourceUpdates = nullptr, BeginPassFlags flags = {});
1661 void endComputePass(QRhiResourceUpdateBatch *resourceUpdates = nullptr);
1662 void setComputePipeline(QRhiComputePipeline *ps);
1663 void dispatch(int x, int y, int z);
1664
1665 const QRhiNativeHandles *nativeHandles();
1666 void beginExternal();
1667 void endExternal();
1668
1669 double lastCompletedGpuTime();
1670
1671protected:
1672 QRhiCommandBuffer(QRhiImplementation *rhi);
1673};
1674
1675Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiCommandBuffer::BeginPassFlags)
1676
1677struct Q_GUI_EXPORT QRhiReadbackResult
1678{
1679 std::function<void()> completed = nullptr;
1680 QRhiTexture::Format format;
1681 QSize pixelSize;
1682 QByteArray data;
1683};
1684
1685class Q_GUI_EXPORT QRhiResourceUpdateBatch
1686{
1687public:
1688 ~QRhiResourceUpdateBatch();
1689
1690 void release();
1691
1692 void merge(QRhiResourceUpdateBatch *other);
1693 bool hasOptimalCapacity() const;
1694
1695 void updateDynamicBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, const void *data);
1696 void uploadStaticBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, const void *data);
1697 void uploadStaticBuffer(QRhiBuffer *buf, const void *data);
1698 void readBackBuffer(QRhiBuffer *buf, quint32 offset, quint32 size, QRhiReadbackResult *result);
1699 void uploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc);
1700 void uploadTexture(QRhiTexture *tex, const QImage &image);
1701 void copyTexture(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc = QRhiTextureCopyDescription());
1702 void readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result);
1703 void generateMips(QRhiTexture *tex);
1704
1705private:
1706 QRhiResourceUpdateBatch(QRhiImplementation *rhi);
1707 Q_DISABLE_COPY(QRhiResourceUpdateBatch)
1708 QRhiResourceUpdateBatchPrivate *d;
1709 friend class QRhiResourceUpdateBatchPrivate;
1710 friend class QRhi;
1711};
1712
1713struct Q_GUI_EXPORT QRhiDriverInfo
1714{
1715 enum DeviceType {
1716 UnknownDevice,
1717 IntegratedDevice,
1718 DiscreteDevice,
1719 ExternalDevice,
1720 VirtualDevice,
1721 CpuDevice
1722 };
1723
1724 QByteArray deviceName;
1725 quint64 deviceId = 0;
1726 quint64 vendorId = 0;
1727 DeviceType deviceType = UnknownDevice;
1728};
1729
1730Q_DECLARE_TYPEINFO(QRhiDriverInfo, Q_RELOCATABLE_TYPE);
1731
1732#ifndef QT_NO_DEBUG_STREAM
1733Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiDriverInfo &);
1734#endif
1735
1736struct Q_GUI_EXPORT QRhiStats
1737{
1738 qint64 totalPipelineCreationTime = 0;
1739 // Vulkan or D3D12 memory allocator statistics
1740 quint32 blockCount = 0;
1741 quint32 allocCount = 0;
1742 quint64 usedBytes = 0;
1743 quint64 unusedBytes = 0;
1744 // D3D12 only, from IDXGIAdapter3::QueryVideoMemoryInfo(), incl. all resources
1745 quint64 totalUsageBytes = 0;
1746};
1747
1748Q_DECLARE_TYPEINFO(QRhiStats, Q_RELOCATABLE_TYPE);
1749
1750#ifndef QT_NO_DEBUG_STREAM
1751Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiStats &);
1752#endif
1753
1754struct Q_GUI_EXPORT QRhiInitParams
1755{
1756};
1757
1758class Q_GUI_EXPORT QRhi
1759{
1760public:
1761 enum Implementation {
1762 Null,
1763 Vulkan,
1764 OpenGLES2,
1765 D3D11,
1766 Metal,
1767 D3D12
1768 };
1769
1770 enum Flag {
1771 EnableDebugMarkers = 1 << 0,
1772 PreferSoftwareRenderer = 1 << 1,
1773 EnablePipelineCacheDataSave = 1 << 2,
1774 EnableTimestamps = 1 << 3
1775 };
1776 Q_DECLARE_FLAGS(Flags, Flag)
1777
1778 enum FrameOpResult {
1779 FrameOpSuccess = 0,
1780 FrameOpError,
1781 FrameOpSwapChainOutOfDate,
1782 FrameOpDeviceLost
1783 };
1784
1785 enum Feature {
1786 MultisampleTexture = 1,
1787 MultisampleRenderBuffer,
1788 DebugMarkers,
1789 Timestamps,
1790 Instancing,
1791 CustomInstanceStepRate,
1792 PrimitiveRestart,
1793 NonDynamicUniformBuffers,
1794 NonFourAlignedEffectiveIndexBufferOffset,
1795 NPOTTextureRepeat,
1796 RedOrAlpha8IsRed,
1797 ElementIndexUint,
1798 Compute,
1799 WideLines,
1800 VertexShaderPointSize,
1801 BaseVertex,
1802 BaseInstance,
1803 TriangleFanTopology,
1804 ReadBackNonUniformBuffer,
1805 ReadBackNonBaseMipLevel,
1806 TexelFetch,
1807 RenderToNonBaseMipLevel,
1808 IntAttributes,
1809 ScreenSpaceDerivatives,
1810 ReadBackAnyTextureFormat,
1811 PipelineCacheDataLoadSave,
1812 ImageDataStride,
1813 RenderBufferImport,
1814 ThreeDimensionalTextures,
1815 RenderTo3DTextureSlice,
1816 TextureArrays,
1817 Tessellation,
1818 GeometryShader,
1819 TextureArrayRange,
1820 NonFillPolygonMode,
1821 OneDimensionalTextures,
1822 OneDimensionalTextureMipmaps,
1823 HalfAttributes,
1824 RenderToOneDimensionalTexture,
1825 ThreeDimensionalTextureMipmaps
1826 };
1827
1828 enum BeginFrameFlag {
1829 };
1830 Q_DECLARE_FLAGS(BeginFrameFlags, BeginFrameFlag)
1831
1832 enum EndFrameFlag {
1833 SkipPresent = 1 << 0
1834 };
1835 Q_DECLARE_FLAGS(EndFrameFlags, EndFrameFlag)
1836
1837 enum ResourceLimit {
1838 TextureSizeMin = 1,
1839 TextureSizeMax,
1840 MaxColorAttachments,
1841 FramesInFlight,
1842 MaxAsyncReadbackFrames,
1843 MaxThreadGroupsPerDimension,
1844 MaxThreadsPerThreadGroup,
1845 MaxThreadGroupX,
1846 MaxThreadGroupY,
1847 MaxThreadGroupZ,
1848 TextureArraySizeMax,
1849 MaxUniformBufferRange,
1850 MaxVertexInputs,
1851 MaxVertexOutputs
1852 };
1853
1854 ~QRhi();
1855
1856 static QRhi *create(Implementation impl,
1857 QRhiInitParams *params,
1858 Flags flags = {},
1859 QRhiNativeHandles *importDevice = nullptr);
1860 static bool probe(Implementation impl, QRhiInitParams *params);
1861
1862 Implementation backend() const;
1863 const char *backendName() const;
1864 static const char *backendName(Implementation impl);
1865 QRhiDriverInfo driverInfo() const;
1866 QThread *thread() const;
1867
1868 using CleanupCallback = std::function<void(QRhi *)>;
1869 void addCleanupCallback(const CleanupCallback &callback);
1870 void runCleanup();
1871
1872 QRhiGraphicsPipeline *newGraphicsPipeline();
1873 QRhiComputePipeline *newComputePipeline();
1874 QRhiShaderResourceBindings *newShaderResourceBindings();
1875
1876 QRhiBuffer *newBuffer(QRhiBuffer::Type type,
1877 QRhiBuffer::UsageFlags usage,
1878 quint32 size);
1879
1880 QRhiRenderBuffer *newRenderBuffer(QRhiRenderBuffer::Type type,
1881 const QSize &pixelSize,
1882 int sampleCount = 1,
1883 QRhiRenderBuffer::Flags flags = {},
1884 QRhiTexture::Format backingFormatHint = QRhiTexture::UnknownFormat);
1885
1886 QRhiTexture *newTexture(QRhiTexture::Format format,
1887 const QSize &pixelSize,
1888 int sampleCount = 1,
1889 QRhiTexture::Flags flags = {});
1890
1891 QRhiTexture *newTexture(QRhiTexture::Format format,
1892 int width, int height, int depth,
1893 int sampleCount = 1,
1894 QRhiTexture::Flags flags = {});
1895
1896 QRhiTexture *newTextureArray(QRhiTexture::Format format,
1897 int arraySize,
1898 const QSize &pixelSize,
1899 int sampleCount = 1,
1900 QRhiTexture::Flags flags = {});
1901
1902 QRhiSampler *newSampler(QRhiSampler::Filter magFilter,
1903 QRhiSampler::Filter minFilter,
1904 QRhiSampler::Filter mipmapMode,
1905 QRhiSampler::AddressMode addressU,
1906 QRhiSampler::AddressMode addressV,
1907 QRhiSampler::AddressMode addressW = QRhiSampler::Repeat);
1908
1909 QRhiTextureRenderTarget *newTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc,
1910 QRhiTextureRenderTarget::Flags flags = {});
1911
1912 QRhiSwapChain *newSwapChain();
1913 FrameOpResult beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags flags = {});
1914 FrameOpResult endFrame(QRhiSwapChain *swapChain, EndFrameFlags flags = {});
1915 bool isRecordingFrame() const;
1916 int currentFrameSlot() const;
1917
1918 FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, BeginFrameFlags flags = {});
1919 FrameOpResult endOffscreenFrame(EndFrameFlags flags = {});
1920
1921 QRhi::FrameOpResult finish();
1922
1923 QRhiResourceUpdateBatch *nextResourceUpdateBatch();
1924
1925 QList<int> supportedSampleCounts() const;
1926
1927 int ubufAlignment() const;
1928 int ubufAligned(int v) const;
1929
1930 static int mipLevelsForSize(const QSize &size);
1931 static QSize sizeForMipLevel(int mipLevel, const QSize &baseLevelSize);
1932
1933 bool isYUpInFramebuffer() const;
1934 bool isYUpInNDC() const;
1935 bool isClipDepthZeroToOne() const;
1936
1937 QMatrix4x4 clipSpaceCorrMatrix() const;
1938
1939 bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags = {}) const;
1940 bool isFeatureSupported(QRhi::Feature feature) const;
1941 int resourceLimit(ResourceLimit limit) const;
1942
1943 const QRhiNativeHandles *nativeHandles();
1944 bool makeThreadLocalNativeContextCurrent();
1945
1946 static const int MAX_MIP_LEVELS = 16; // -> max width or height is 65536
1947
1948 void releaseCachedResources();
1949
1950 bool isDeviceLost() const;
1951
1952 QByteArray pipelineCacheData();
1953 void setPipelineCacheData(const QByteArray &data);
1954
1955 QRhiStats statistics() const;
1956
1957 static QRhiSwapChainProxyData updateSwapChainProxyData(Implementation impl, QWindow *window);
1958
1959protected:
1960 QRhi();
1961
1962private:
1963 Q_DISABLE_COPY(QRhi)
1964 QRhiImplementation *d = nullptr;
1965};
1966
1967Q_DECLARE_OPERATORS_FOR_FLAGS(QRhi::Flags)
1968Q_DECLARE_OPERATORS_FOR_FLAGS(QRhi::BeginFrameFlags)
1969Q_DECLARE_OPERATORS_FOR_FLAGS(QRhi::EndFrameFlags)
1970
1971QT_END_NAMESPACE
1972
1973#include <rhi/qrhi_platform.h>
1974
1975#endif
1976

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