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