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
qssgrhicontext_p.h
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5
6#ifndef QSSGRHICONTEXT_P_H
7#define QSSGRHICONTEXT_P_H
8
9//
10// W A R N I N G
11// -------------
12//
13// This file is not part of the Qt API. It exists purely as an
14// implementation detail. This header file may change from version to
15// version without notice, or even be removed.
16//
17// We mean it.
18//
19
20#include <QtGui/rhi/qrhi.h>
21
22#include <QtQuick3DRuntimeRender/qtquick3druntimerenderexports.h>
23#include <QtQuick3DUtils/private/qssgrenderbasetypes_p.h>
24#include <QtQuick3DUtils/private/qssgutils_p.h>
25#include <ssg/qssgrhicontext.h>
26
28
29struct QSSGRenderLayer;
30struct QSSGRenderSkyMaterial;
31struct QSSGRenderInstanceTable;
32struct QSSGRenderModel;
33struct QSSGRenderMesh;
34class QSSGRenderGraphObject;
35class QSSGBufferManager;
36class QSSGUserRenderPassManager;
37
39{
41 static const InputAssemblerState &get(const QSSGRhiGraphicsPipelineState &ps) { return ps.ia; }
42 static InputAssemblerState &get(QSSGRhiGraphicsPipelineState &ps) { return ps.ia; }
43};
44
45using QSSGRhiInputAssemblerState = QSSGRhiInputAssemblerStatePrivate::InputAssemblerState;
46
48{
49 static void setShaderPipeline(QSSGRhiGraphicsPipelineState &ps, const QSSGRhiShaderPipeline *pipeline)
50 {
51 ps.shaderPipeline = pipeline;
52 }
53
54 static constexpr const QSSGRhiShaderPipeline *getShaderPipeline(const QSSGRhiGraphicsPipelineState &ps)
55 {
56 return ps.shaderPipeline;
57 }
58};
59
60namespace QSSGRhiHelpers
61{
62
63inline QRhiSampler::Filter toRhi(QSSGRenderTextureFilterOp op)
64{
65 switch (op) {
66 case QSSGRenderTextureFilterOp::Nearest:
67 return QRhiSampler::Nearest;
68 case QSSGRenderTextureFilterOp::Linear:
69 return QRhiSampler::Linear;
70 case QSSGRenderTextureFilterOp::None:
71 return QRhiSampler::Linear;
72 }
73
74 Q_UNREACHABLE_RETURN(QRhiSampler::Linear);
75}
76
77inline QRhiSampler::AddressMode toRhi(QSSGRenderTextureCoordOp tiling)
78{
79 switch (tiling) {
80 case QSSGRenderTextureCoordOp::Repeat:
81 return QRhiSampler::Repeat;
82 case QSSGRenderTextureCoordOp::MirroredRepeat:
83 return QRhiSampler::Mirror;
84 case QSSGRenderTextureCoordOp::ClampToEdge:
85 return QRhiSampler::ClampToEdge;
86 case QSSGRenderTextureCoordOp::Unknown:
87 return QRhiSampler::ClampToEdge;
88 }
89
90 Q_UNREACHABLE_RETURN(QRhiSampler::ClampToEdge);
91}
92
93inline QRhiGraphicsPipeline::CullMode toCullMode(QSSGCullFaceMode cullFaceMode)
94{
95 switch (cullFaceMode) {
96 case QSSGCullFaceMode::Back:
97 return QRhiGraphicsPipeline::Back;
98 case QSSGCullFaceMode::Front:
99 return QRhiGraphicsPipeline::Front;
100 case QSSGCullFaceMode::Disabled:
101 return QRhiGraphicsPipeline::None;
102 case QSSGCullFaceMode::FrontAndBack:
103 qWarning("FrontAndBack cull mode not supported");
104 return QRhiGraphicsPipeline::None;
105 case QSSGCullFaceMode::Unknown:
106 return QRhiGraphicsPipeline::None;
107 }
108
109 Q_UNREACHABLE_RETURN(QRhiGraphicsPipeline::None);
110}
111
112QRhiVertexInputAttribute::Format toVertexInputFormat(QSSGRenderComponentType compType, quint32 numComps);
113QRhiGraphicsPipeline::Topology toTopology(QSSGRenderDrawMode drawMode);
114// Fills out inputLayout.attributes[].location based on
115// inputLayoutInputNames and the provided shader reflection info.
116void bakeVertexInputLocations(QSSGRhiInputAssemblerState *ia, const QSSGRhiShaderPipeline &shaders, int instanceBufferBinding = 0);
117
118} // namespace QSSGRhiHelpers
119
120inline bool operator==(const QSSGRhiGraphicsPipelineState &a, const QSSGRhiGraphicsPipelineState &b) Q_DECL_NOTHROW
121{
122 const auto &ia_a = QSSGRhiInputAssemblerStatePrivate::get(a);
123 const auto &ia_b = QSSGRhiInputAssemblerStatePrivate::get(b);
124 const auto compareTargetBlend = [](const std::array<QRhiGraphicsPipeline::TargetBlend, 8> &a,
125 const std::array<QRhiGraphicsPipeline::TargetBlend, 8> &b,
126 const int count) -> bool {
127 for (int i = 0; i < count; i++) {
128 if (a[i].colorWrite != b[i].colorWrite
129 || a[i].srcColor != b[i].srcColor
130 || a[i].dstColor != b[i].dstColor
131 || a[i].opColor != b[i].opColor
132 || a[i].srcAlpha != b[i].srcAlpha
133 || a[i].dstAlpha != b[i].dstAlpha
134 || a[i].opAlpha != b[i].opAlpha) {
135 return false;
136 }
137 }
138 return true;
139 };
140 // The viewport and scissor rects are intentionally not compared: they are
141 // dynamic state, never baked into a QRhiGraphicsPipeline, and comparing
142 // them made the pipeline cache key size-dependent, growing the cache with
143 // a new set of pipelines for every window size!
144 return QSSGRhiGraphicsPipelineStatePrivate::getShaderPipeline(a) == QSSGRhiGraphicsPipelineStatePrivate::getShaderPipeline(b)
145 && a.samples == b.samples
146 && a.flags == b.flags
147 && a.stencilRef == b.stencilRef
148 && (std::memcmp(&a.stencilOpFrontState, &b.stencilOpFrontState, sizeof(QRhiGraphicsPipeline::StencilOpState)) == 0)
149 && a.stencilWriteMask == b.stencilWriteMask
150 && a.depthFunc == b.depthFunc
151 && a.cullMode == b.cullMode
152 && a.depthBias == b.depthBias
153 && a.slopeScaledDepthBias == b.slopeScaledDepthBias
154 && ia_a.topology == ia_b.topology
155 && ia_a.inputLayout == ia_b.inputLayout
156 && a.colorAttachmentCount == b.colorAttachmentCount
157 && compareTargetBlend(a.targetBlend, b.targetBlend, a.colorAttachmentCount)
158 && a.lineWidth == b.lineWidth
159 && a.polygonMode == b.polygonMode
160 && a.viewCount == b.viewCount;
161}
162
163inline bool operator!=(const QSSGRhiGraphicsPipelineState &a, const QSSGRhiGraphicsPipelineState &b) Q_DECL_NOTHROW
164{
165 return !(a == b);
166}
167
168inline size_t qHash(const QSSGRhiGraphicsPipelineState &s, size_t seed) Q_DECL_NOTHROW
169{
170 // do not bother with all fields
171 return qHash(QSSGRhiGraphicsPipelineStatePrivate::getShaderPipeline(s), seed)
172 ^ qHash(s.samples)
173 ^ qHash(s.viewCount)
174 ^ qHash(s.targetBlend[0].dstColor)
175 ^ qHash(s.depthFunc)
176 ^ qHash(s.cullMode)
177 ^ qHash(s.colorAttachmentCount)
178 ^ qHash(s.lineWidth)
179 ^ qHash(s.polygonMode)
180 ^ qHashBits(&s.stencilOpFrontState, sizeof(QRhiGraphicsPipeline::StencilOpState))
181 ^ (s.flags)
182 ^ (s.stencilRef << 6)
183 ^ (s.stencilWriteMask << 7);
184}
185
186// The lookup keys can be somewhat complicated due to having to handle cases
187// like "render a model in a shared scene between multiple View3Ds" (here both
188// the View3D ('layer/cid') and the model ('model') act as the lookup key since
189// while the model is the same, we still want different uniform buffers per
190// View3D). 'resource' is the resource the model is drawn with, typically a
191// material; many resources can map to one model. When 'resource' refers to a
192// material it must be the material pointer and nothing else, since
193// cleanupDrawCallDataForResource() finds the entries to release for a
194// to-be-destroyed material by matching on 'resource'. 'mapEntry' is the
195// per-light shadow map entry or per-probe reflection map entry being rendered
196// into, when the draw is part of a shadow or reflection pass, otherwise null.
197// 'resourceIdx' disambiguates multiple entries for the same resource and map
198// entry, e.g. the cube map face and the subset offset.
199//
200struct QSSGRhiDrawCallDataKey
201{
202 const void *cid = nullptr; // Usually the sub-pass (see usage of QSSGPassKey)
203 const void *model = nullptr;
204 const void *resource = nullptr;
205 const void *mapEntry = nullptr;
206 quintptr resourceIdx = 0;
207};
208
209class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRhiBuffer
210{
211 Q_DISABLE_COPY(QSSGRhiBuffer)
212public:
213 QSSGRhiBuffer(QSSGRhiContext &context,
214 QRhiBuffer::Type type,
215 QRhiBuffer::UsageFlags usageMask,
216 quint32 stride,
217 qsizetype size,
218 QRhiCommandBuffer::IndexFormat indexFormat = QRhiCommandBuffer::IndexUInt16);
219
220 virtual ~QSSGRhiBuffer();
221
222 QRhiBuffer *buffer() const { return m_buffer; }
223 quint32 stride() const { return m_stride; }
225 const quint32 sz = quint32(m_buffer->size());
226 Q_ASSERT((sz % m_stride) == 0);
227 return sz / m_stride;
228 }
229 QRhiCommandBuffer::IndexFormat indexFormat() const { return m_indexFormat; }
230
231private:
232 QSSGRhiContext &m_context;
233 QRhiBuffer *m_buffer = nullptr;
234 quint32 m_stride;
235 QRhiCommandBuffer::IndexFormat m_indexFormat;
236};
237
239{
240 char name[64];
242
243private:
244 size_t offset = SIZE_MAX;
245 bool maybeExists = true;
246 friend class QSSGRhiShaderPipeline;
247};
248
250{
251 char name[64];
254
255private:
256 size_t offset = SIZE_MAX;
257 size_t size = 0;
258 bool maybeExists = true;
259 friend class QSSGRhiShaderPipeline;
260};
261
262using QSSGRhiBufferPtr = std::shared_ptr<QSSGRhiBuffer>;
263
264inline bool operator==(const QSSGRhiSamplerDescription &a, const QSSGRhiSamplerDescription &b) Q_DECL_NOTHROW
265{
266 return a.hTiling == b.hTiling && a.vTiling == b.vTiling && a.zTiling == b.zTiling
267 && a.minFilter == b.minFilter && a.magFilter == b.magFilter
268 && a.mipmap == b.mipmap;
269}
270
271inline bool operator!=(const QSSGRhiSamplerDescription &a, const QSSGRhiSamplerDescription &b) Q_DECL_NOTHROW
272{
273 return !(a == b);
274}
275
276struct QSSGRhiTexture
277{
278 QByteArray name;
279 QRhiTexture *texture = nullptr;
280 QSSGRhiSamplerDescription samplerDesc;
281};
282
298
299// these are our current shader limits
300#define QSSG_MAX_NUM_LIGHTS 16
301#define QSSG_MAX_NUM_DIRECTIONAL_LIGHTS 4
302#define QSSG_REDUCED_MAX_NUM_LIGHTS 4
303#define QSSG_REDUCED_MAX_NUM_DIRECTIONAL_LIGHTS 1
304
338
364
368
372
373class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRhiShaderPipeline
374{
375 Q_DISABLE_COPY(QSSGRhiShaderPipeline)
376public:
377 explicit QSSGRhiShaderPipeline(QSSGRhiContext &context) : m_context(context) { }
378
379 QSSGRhiContext &context() const { return m_context; }
380 bool isNull() const { return m_stages.isEmpty(); }
381
382 enum StageFlag {
383 // Indicates that this shaderpipeline object is not going to be used with
384 // a QSSGRhiInputAssemblerState, i.e. bakeVertexInputLocations() will
385 // not be called.
386 UsedWithoutIa = 0x01
387 };
389
390 void addStage(const QRhiShaderStage &stage, StageFlags flags = {});
391 const QRhiShaderStage *cbeginStages() const { return m_stages.cbegin(); }
392 const QRhiShaderStage *cendStages() const { return m_stages.cend(); }
393
395 for (const QRhiShaderStage &s : m_stages) {
396 if (s.type() == QRhiShaderStage::Vertex)
397 return &s;
398 }
399 return nullptr;
400 }
402 for (const QRhiShaderStage &s : m_stages) {
403 if (s.type() == QRhiShaderStage::Fragment)
404 return &s;
405 }
406 return nullptr;
407 }
408
409 int ub0Size() const { return m_ub0Size; }
410 int ub0LightDataOffset() const { return m_ub0NextUBufOffset; }
412
414
415 // This struct is used purely for performance. It is used to quickly store
416 // and index common uniform names using the storeIndex argument in the
417 // setUniform method.
419 {
455 int pointSizeIdx = -1;
462 int fogColorIdx = -1;
470 int viewSize = -1;
471 int samples = -1;
472
479 } commonUniformIndices;
480
482 int transform0 = -1;
483 int transform1 = -1;
484 int transform2 = -1;
485 int color = -1;
486 int data = -1;
487 } instanceLocations;
488
489 enum class UniformFlag {
490 Mat3 = 0x01
491 };
492 Q_DECLARE_FLAGS(UniformFlags, UniformFlag)
493
494 void setUniformValue(char *ubufData, const char *name, const QVariant &value, QSSGRenderShaderValue::Type type);
495 void setUniform(char *ubufData, const char *name, const void *data, size_t size, int *storeIndex = nullptr, UniformFlags flags = {});
496 void setUniformArray(char *ubufData, const char *name, const void *data, size_t itemCount, QSSGRenderShaderValue::Type type, int *storeIndex = nullptr);
497 int bindingForTexture(const char *name, int hint = -1);
498 int bindingForImage(const char *name);
499
500 void setShaderResources(char *ubufData,
501 QSSGBufferManager &theBufferManager,
502 const QByteArray &inPropertyName,
503 const QVariant &propertyValue,
504 QSSGRenderShaderValue::Type inPropertyType);
505
506 void setLightsEnabled(bool enable) { m_lightsEnabled = enable; }
507 bool isLightingEnabled() const { return m_lightsEnabled; }
508
509 void ensureCombinedUniformBuffer(QRhiBuffer **ubuf);
510 void ensureUniformBuffer(QRhiBuffer **ubuf);
511
512 void setLightProbeTexture(QRhiTexture *texture,
513 QSSGRenderTextureCoordOp hTile = QSSGRenderTextureCoordOp::ClampToEdge,
514 QSSGRenderTextureCoordOp vTile = QSSGRenderTextureCoordOp::ClampToEdge)
515 {
516 m_lightProbeTexture = texture; m_lightProbeHorzTile = hTile; m_lightProbeVertTile = vTile;
517 }
518 QRhiTexture *lightProbeTexture() const { return m_lightProbeTexture; }
520 {
521 return {m_lightProbeHorzTile, m_lightProbeVertTile};
522 }
523
524 void setScreenTexture(QRhiTexture *texture) { m_screenTexture = texture; }
525 QRhiTexture *screenTexture() const { return m_screenTexture; }
526
527 void setDepthTexture(QRhiTexture *texture) { m_depthTexture = texture; }
528 QRhiTexture *depthTexture() const { return m_depthTexture; }
529
530 void setNormalTexture(QRhiTexture *texture) { m_normalTexture = texture; }
531 QRhiTexture *normalTexture() const { return m_normalTexture; }
532
533 void setSsaoTexture(QRhiTexture *texture) { m_ssaoTexture = texture; }
534 QRhiTexture *ssaoTexture() const { return m_ssaoTexture; }
535
536 void setLightmapTexture(QRhiTexture *texture) { m_lightmapTexture = texture; }
537 QRhiTexture *lightmapTexture() const { return m_lightmapTexture; }
538
539 void setMotionVectorTexture(QRhiTexture *texture) { m_motionVectorTexture = texture; }
540 QRhiTexture *MotionVectorTexture() const { return m_motionVectorTexture; }
541 void setShadowMapAtlasTexture(QRhiTexture *texture) { m_shadowMapAtlasTexture = texture; }
542 QRhiTexture *shadowMapAtlasTexture() const { return m_shadowMapAtlasTexture; }
543
544 void setShadowMapBlueNoiseTexture(QRhiTexture *texture) { m_shadowMapBlueNoiseTexture = texture; }
545 QRhiTexture *shadowMapBlueNoiseTexture() const { return m_shadowMapBlueNoiseTexture; }
546
547 void setOITImages(QRhiTexture *accumulator, QRhiTexture *auxiliary, QRhiTexture *counter)
548 {
549 m_oitImages[0] = accumulator;
550 m_oitImages[1] = auxiliary;
551 m_oitImages[2] = counter;
552 }
553 QRhiTexture **oitImages() { return m_oitImages; }
554
555 void resetExtraTextures() { m_extraTextures.clear(); }
556 void addExtraTexture(const QSSGRhiTexture &t) { m_extraTextures.append(t); }
557 int extraTextureCount() const { return m_extraTextures.size(); }
558 const QSSGRhiTexture &extraTextureAt(int index) const { return m_extraTextures[index]; }
559 QSSGRhiTexture &extraTextureAt(int index) { return m_extraTextures[index]; }
560
561 QSSGShaderLightsUniformData &lightsUniformData() { return m_lightsUniformData; }
562 QSSGShaderDirectionalLightsUniformData &directionalLightsUniformData() { return m_directionalLightsUniformData; }
563 InstanceLocations instanceBufferLocations() const { return instanceLocations; }
564
565 int offsetOfUniform(const QByteArray &name);
566
567private:
568 QSSGRhiContext &m_context;
569 QVarLengthArray<QRhiShaderStage, 2> m_stages;
570 int m_ub0Size = 0;
571 int m_ub0NextUBufOffset = 0;
572 QHash<QByteArray, QShaderDescription::BlockVariable> m_ub0;
573 QHash<QSSGRhiInputAssemblerState::InputSemantic, QShaderDescription::InOutVariable> m_vertexInputs;
574 QHash<QByteArray, QShaderDescription::InOutVariable> m_combinedImageSamplers;
575 QHash<QByteArray, QShaderDescription::InOutVariable> m_storageImages;
576 int m_materialImageSamplerBindings[size_t(QSSGRhiSamplerBindingHints::BindingMapSize)];
577
578 QVarLengthArray<QSSGRhiShaderUniform, 32> m_uniforms; // members of the main (binding 0) uniform buffer
579 QVarLengthArray<QSSGRhiShaderUniformArray, 8> m_uniformArrays;
580 QHash<QByteArray, size_t> m_uniformIndex; // Maps uniform name to index in m_uniforms and m_uniformArrays
581
582 // transient (per-object) data; pointers are all non-owning
583 bool m_lightsEnabled = false;
584 QSSGShaderLightsUniformData m_lightsUniformData;
585 QSSGShaderDirectionalLightsUniformData m_directionalLightsUniformData;
586 QRhiTexture *m_shadowMapAtlasTexture = nullptr;
587 QRhiTexture *m_shadowMapBlueNoiseTexture = nullptr;
588 QRhiTexture *m_lightProbeTexture = nullptr;
589 QSSGRenderTextureCoordOp m_lightProbeHorzTile = QSSGRenderTextureCoordOp::ClampToEdge;
590 QSSGRenderTextureCoordOp m_lightProbeVertTile = QSSGRenderTextureCoordOp::ClampToEdge;
591 QRhiTexture *m_screenTexture = nullptr;
592 QRhiTexture *m_depthTexture = nullptr;
593 QRhiTexture *m_normalTexture = nullptr;
594 QRhiTexture *m_ssaoTexture = nullptr;
595 QRhiTexture *m_lightmapTexture = nullptr;
596 QRhiTexture *m_oitImages[3] = {nullptr};
597 QRhiTexture *m_motionVectorTexture = nullptr;
598 QVarLengthArray<QSSGRhiTexture, 8> m_extraTextures;
599};
600
601Q_DECLARE_OPERATORS_FOR_FLAGS(QSSGRhiShaderPipeline::StageFlags)
602Q_DECLARE_OPERATORS_FOR_FLAGS(QSSGRhiShaderPipeline::UniformFlags)
603
604using QSSGRhiShaderPipelinePtr = std::shared_ptr<QSSGRhiShaderPipeline>;
605
606class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRhiShaderResourceBindingList
607{
608public:
609 static const int MAX_SIZE = 32;
610
611 int p = 0;
612 size_t h = 0;
613 QRhiShaderResourceBinding v[MAX_SIZE];
614
615 void clear() { p = 0; h = 0; }
616
617 QSSGRhiShaderResourceBindingList() { }
618
619 QSSGRhiShaderResourceBindingList(const QSSGRhiShaderResourceBindingList &other)
620 : p(other.p),
621 h(other.h)
622 {
623 for (int i = 0; i < p; ++i)
624 v[i] = other.v[i];
625 }
626
627 QSSGRhiShaderResourceBindingList &operator=(const QSSGRhiShaderResourceBindingList &other) Q_DECL_NOTHROW
628 {
629 if (this != &other) {
630 p = other.p;
631 h = other.h;
632 for (int i = 0; i < p; ++i)
633 v[i] = other.v[i];
634 }
635 return *this;
636 }
637
638 void addUniformBuffer(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiBuffer *buf, int offset = 0 , int size = 0, bool hasDynamicOffset = false);
639 void addTexture(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler);
640 void addImageLoad(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiTexture *tex, int level);
641 void addImageStore(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiTexture *tex, int level);
642 void addImageLoadStore(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiTexture *tex, int level);
643 void addStorageBufferLoad(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiBuffer *buf, int offset = 0 , int size = 0);
644 void addStorageBufferStore(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiBuffer *buf, int offset = 0 , int size = 0);
645 void addStorageBufferLoadStore(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiBuffer *buf, int offset = 0 , int size = 0);
646private:
647 void fillImage(QRhiShaderResourceBinding::Data *d, QRhiShaderResourceBinding::Type t, int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiTexture *tex, int level);
648 void fillStorageBuffer(QRhiShaderResourceBinding::Data *d, QRhiShaderResourceBinding::Type t, int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiBuffer *buf, int offset, int size);
649 QRhiShaderResourceBinding::Data *newBinding();
650};
651
652inline bool operator==(const QSSGRhiShaderResourceBindingList &a, const QSSGRhiShaderResourceBindingList &b) Q_DECL_NOTHROW
653{
654 if (a.h != b.h)
655 return false;
656 if (a.p != b.p)
657 return false;
658 for (int i = 0; i < a.p; ++i) {
659 if (a.v[i] != b.v[i])
660 return false;
661 }
662 return true;
663}
664
665inline bool operator!=(const QSSGRhiShaderResourceBindingList &a, const QSSGRhiShaderResourceBindingList &b) Q_DECL_NOTHROW
666{
667 return !(a == b);
668}
669
670inline size_t qHash(const QSSGRhiShaderResourceBindingList &bl, size_t seed) Q_DECL_NOTHROW
671{
672 return bl.h ^ seed;
673}
674
675struct QSSGRhiDrawCallData
676{
677 QRhiBuffer *ubuf = nullptr; // owned
678 QRhiShaderResourceBindings *srb = nullptr; // not owned
679 QSSGRhiShaderResourceBindingList bindings;
680 QRhiGraphicsPipeline *pipeline = nullptr; // not owned
681 size_t renderTargetDescriptionHash = 0;
682 QVector<quint32> renderTargetDescription;
683 QSSGRhiGraphicsPipelineState ps;
684
685 void reset()
686 {
687 delete ubuf;
688 ubuf = nullptr;
689 srb = nullptr;
690 pipeline = nullptr;
691 }
692};
693
694class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGManagedRhiTexture
695{
696 enum class Private { Initialize };
697 Q_DISABLE_COPY(QSSGManagedRhiTexture)
698public:
699 using Ptr = std::unique_ptr<QSSGManagedRhiTexture>;
700
701 const std::unique_ptr<QRhiTexture> &texture() const { return m_texture; }
702
703 [[nodiscard]] bool isValid() const { return m_texture != nullptr; }
704
705 QSSGManagedRhiTexture() = default;
706 QSSGManagedRhiTexture(const std::shared_ptr<QSSGUserRenderPassManager> &manager, QRhiTexture *texture, Private);
707 QSSGManagedRhiTexture(const std::shared_ptr<QSSGUserRenderPassManager> &manager, std::unique_ptr<QRhiTexture> texture);
708 ~QSSGManagedRhiTexture();
709
710 [[nodiscard]] static Ptr make_copy(const Ptr &other)
711 {
712 return std::make_unique<QSSGManagedRhiTexture>(other->m_manager, other->m_texture.get(), Private::Initialize);
713 }
714
715private:
716 friend class QSSGRhiRenderableTextureV2;
717 friend class QSSGUserRenderPassManager;
718
719 void invalidate();
720
721 std::shared_ptr<QSSGUserRenderPassManager> m_manager;
722 std::unique_ptr<QRhiTexture> m_texture;
723};
724
725using QSSGManagedRhiTexturePtr = QSSGManagedRhiTexture::Ptr;
726
728{
729 enum class Private { Initialize };
730public:
731 QSSGRhiRenderableTextureV2(const std::shared_ptr<QSSGUserRenderPassManager> &manager, Private)
732 : m_manager(manager)
733 {
734 }
736
737 void setDescription(QRhi *rhi, QRhiTextureRenderTargetDescription rtDesc, QRhiTextureRenderTarget::Flags = {});
738
739 void setName(const QByteArray &name) { rtName = name; }
740 const QByteArray &getName() const { return rtName; }
741
742 const QSSGManagedRhiTexturePtr &getDepthTexture() const { return depthTexture; }
743 const std::unique_ptr<QRhiRenderBuffer> &getDepthStencil() const { return depthStencil; }
746
747 size_t colorAttachmentCount() const { return textures.size(); }
748 const QSSGManagedRhiTexturePtr &getColorTexture(int index) const { return textures[index]; }
749
750 bool isValid() const { return (textures.size() > 0) && rt && rpDesc; }
751
752 void finialize(QRhi *rhi);
753
754 void resetRenderTarget();
755 void reset();
756
757private:
758 friend class QSSGUserRenderPassManager;
759
760 enum Dirty : quint32
761 {
762 ColorTextureDirty = 0x1,
763 DepthStencilDirty = 0x2,
764 DepthTextureDirty = 0x4,
765 };
766
767 void invalidate();
768
770
771 std::shared_ptr<QSSGUserRenderPassManager> m_manager;
772
773 QVarLengthArray<QSSGManagedRhiTexturePtr, 4> textures {};
774 std::unique_ptr<QRhiRenderBuffer> depthStencil;
775 QSSGManagedRhiTexturePtr depthTexture; // either depthStencil or depthTexture are valid, never both
776
777 std::unique_ptr<QRhiRenderPassDescriptor> rpDesc;
778 std::unique_ptr<QRhiTextureRenderTarget> rt;
779 QByteArray rtName;
780 DirtyT dirty = 0;
781};
782
783using QSSGRhiRenderableTextureV2Ptr = std::shared_ptr<QSSGRhiRenderableTextureV2>;
784
786{
789 QRhiTexture *depthTexture = nullptr; // either depthStencil or depthTexture are valid, never both
792 bool isValid() const { return texture && rpDesc && rt; }
794 delete rt;
795 rt = nullptr;
796 delete rpDesc;
797 rpDesc = nullptr;
798 }
799 void reset() {
801 delete texture;
802 delete depthStencil;
803 delete depthTexture;
804 *this = QSSGRhiRenderableTexture();
805 }
806};
807
809{
810 float d = 0.0f;
812};
813
826
837
839{
840public:
843 struct {
845 } extra;
846 static QSSGComputePipelineStateKey create(const QShader &shader,
847 const QRhiShaderResourceBindings *srb)
848 {
849 const QVector<quint32> srbDesc = srb->serializedLayoutDescription();
850 return { shader, srbDesc, { qHash(srbDesc) } };
851 }
852};
853
854inline bool operator==(const QSSGComputePipelineStateKey &a, const QSSGComputePipelineStateKey &b) Q_DECL_NOTHROW
855{
856 return a.shader == b.shader && a.srbLayoutDescription == b.srbLayoutDescription;
857}
858
859inline bool operator!=(const QSSGComputePipelineStateKey &a, const QSSGComputePipelineStateKey &b) Q_DECL_NOTHROW
860{
861 return !(a == b);
862}
863
864inline size_t qHash(const QSSGComputePipelineStateKey &k, size_t seed = 0) Q_DECL_NOTHROW
865{
866 return qHash(k.shader, seed) ^ k.extra.srbLayoutDescriptionHash;
867}
868
869struct QSSGRhiDummyTextureKey
870{
871 QRhiTexture::Flags flags;
872 QSize size;
873 QColor color;
874 int arraySize;
875};
876
877inline size_t qHash(const QSSGRhiDummyTextureKey &k, size_t seed) Q_DECL_NOTHROW
878{
879 return qHash(k.flags, seed)
880 ^ qHash(k.size.width() ^ k.size.height() ^ k.color.red() ^ k.color.green()
881 ^ k.color.blue() ^ k.color.alpha() ^ k.arraySize);
882}
883
884inline bool operator==(const QSSGRhiDummyTextureKey &a, const QSSGRhiDummyTextureKey &b) Q_DECL_NOTHROW
885{
886 return a.flags == b.flags && a.size == b.size && a.color == b.color && a.arraySize == b.arraySize;
887}
888
889inline bool operator!=(const QSSGRhiDummyTextureKey &a, const QSSGRhiDummyTextureKey &b) Q_DECL_NOTHROW
890{
891 return !(a == b);
892}
893
894class QSSGGraphicsPipelineStateKey
895{
896public:
897 QSSGRhiGraphicsPipelineState state;
898 QVector<quint32> renderTargetDescription;
899 QVector<quint32> srbLayoutDescription;
900 struct {
901 size_t renderTargetDescriptionHash;
902 size_t srbLayoutDescriptionHash;
903 } extra;
904 static QSSGGraphicsPipelineStateKey create(const QSSGRhiGraphicsPipelineState &state,
905 const QRhiRenderPassDescriptor *rpDesc,
906 const QRhiShaderResourceBindings *srb)
907 {
908 const QVector<quint32> rtDesc = rpDesc->serializedFormat();
909 const QVector<quint32> srbDesc = srb->serializedLayoutDescription();
910 return { state, rtDesc, srbDesc, { qHash(rtDesc), qHash(srbDesc) } };
911 }
912};
913
914inline bool operator==(const QSSGGraphicsPipelineStateKey &a, const QSSGGraphicsPipelineStateKey &b) Q_DECL_NOTHROW
915{
916 return a.state == b.state
917 && a.renderTargetDescription == b.renderTargetDescription
918 && a.srbLayoutDescription == b.srbLayoutDescription;
919}
920
921inline bool operator!=(const QSSGGraphicsPipelineStateKey &a, const QSSGGraphicsPipelineStateKey &b) Q_DECL_NOTHROW
922{
923 return !(a == b);
924}
925
926inline size_t qHash(const QSSGGraphicsPipelineStateKey &k, size_t seed) Q_DECL_NOTHROW
927{
928 return qHash(k.state, seed)
929 ^ k.extra.renderTargetDescriptionHash
930 ^ k.extra.srbLayoutDescriptionHash;
931}
932
933#define QSSGRHICTX_STAT(ctx, f)
934 for (bool qssgrhictxlog_enabled = QSSGRhiContextStats::get(*ctx).isEnabled(); qssgrhictxlog_enabled; qssgrhictxlog_enabled = false)
935 QSSGRhiContextStats::get(*ctx).f
936
937class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRhiContextStats
938{
939public:
940 [[nodiscard]] static QSSGRhiContextStats &get(QSSGRhiContext &rhiCtx);
941 [[nodiscard]] static const QSSGRhiContextStats &get(const QSSGRhiContext &rhiCtx);
942
943 struct DrawInfo {
944 quint64 callCount = 0;
945 quint64 vertexOrIndexCount = 0;
946 };
947 struct InstancedDrawInfo {
948 quint64 callCount = 0;
949 quint64 vertexOrIndexCount = 0;
950 quint64 instanceCount = 0;
951 };
952 struct RenderPassInfo {
953 QByteArray rtName;
954 QSize pixelSize;
955 DrawInfo indexedDraws;
956 DrawInfo draws;
957 InstancedDrawInfo instancedIndexedDraws;
958 InstancedDrawInfo instancedDraws;
959 };
960 struct PerLayerInfo {
961 PerLayerInfo()
962 {
963 externalRenderPass.rtName = QByteArrayLiteral("Qt Quick");
964 }
965
966 // The main render pass if renderMode==Offscreen, plus render passes
967 // for shadow maps, postprocessing effects, etc.
968 QVector<RenderPassInfo> renderPasses;
969
970 // An Underlay/Overlay/Inline renderMode will make the View3D add stuff
971 // to a render pass managed by Qt Quick. (external == not under the
972 // control of Qt Quick 3D)
973 RenderPassInfo externalRenderPass;
974
975 int currentRenderPassIndex = -1;
976 };
977 struct GlobalInfo { // global as in per QSSGRhiContext which is per-QQuickWindow
978 quint64 meshDataSize = 0;
979 quint64 imageDataSize = 0;
980 qint64 materialGenerationTime = 0;
981 qint64 effectGenerationTime = 0;
982 };
983
984 QHash<QSSGRenderLayer *, PerLayerInfo> perLayerInfo;
985 GlobalInfo globalInfo;
986
987 QSSGRhiContextStats(QSSGRhiContext &context)
988 : rhiCtx(&context)
989 {
990 }
991
992 // The data collected have four consumers:
993 //
994 // - Printed on debug output when QSG_RENDERER_DEBUG has the relevant key.
995 // (this way the debug output from the 2D scenegraph renderer and these 3D
996 // statistics appear nicely intermixed)
997 // - Passed on to the QML profiler when profiling is enabled.
998 // - DebugView via QQuick3DRenderStats.
999 // - When tracing is enabled
1000 //
1001 // The first two are enabled globally, but DebugView needs a dynamic
1002 // enable/disable since we want to collect data when a DebugView item
1003 // becomes visible, but not otherwise.
1004
1005 static bool profilingEnabled();
1006 static bool rendererDebugEnabled();
1007
1008 bool isEnabled() const;
1009 void drawIndexed(quint32 indexCount, quint32 instanceCount);
1010 void draw(quint32 vertexCount, quint32 instanceCount);
1011
1012 void meshDataSizeChanges(quint64 newSize) // can be called outside start-stop
1013 {
1014 globalInfo.meshDataSize = newSize;
1015 }
1016
1017 void imageDataSizeChanges(quint64 newSize) // can be called outside start-stop
1018 {
1019 globalInfo.imageDataSize = newSize;
1020 }
1021
1022 void registerMaterialShaderGenerationTime(qint64 ms)
1023 {
1024 globalInfo.materialGenerationTime += ms;
1025 }
1026
1027 void registerEffectShaderGenerationTime(qint64 ms)
1028 {
1029 globalInfo.effectGenerationTime += ms;
1030 }
1031
1032 static quint64 totalDrawCallCountForPass(const QSSGRhiContextStats::RenderPassInfo &pass)
1033 {
1034 return pass.draws.callCount
1035 + pass.indexedDraws.callCount
1036 + pass.instancedDraws.callCount
1037 + pass.instancedIndexedDraws.callCount;
1038 }
1039
1040 static quint64 totalVertexCountForPass(const QSSGRhiContextStats::RenderPassInfo &pass)
1041 {
1042 return pass.draws.vertexOrIndexCount
1043 + pass.indexedDraws.vertexOrIndexCount
1044 + pass.instancedDraws.vertexOrIndexCount
1045 + pass.instancedIndexedDraws.vertexOrIndexCount;
1046 }
1047
1048 void start(QSSGRenderLayer *layer);
1049 void stop(QSSGRenderLayer *layer);
1050 void beginRenderPass(QRhiTextureRenderTarget *rt);
1051 void endRenderPass();
1052 void printRenderPass(const RenderPassInfo &rp);
1053 void cleanupLayerInfo(QSSGRenderLayer *layer);
1054
1055 QSSGRhiContext *rhiCtx;
1056 QSSGRenderLayer *layerKey = nullptr;
1057 QSet<QSSGRenderLayer *> dynamicDataSources;
1058};
1059
1060class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRhiContextPrivate
1061{
1062 Q_DECLARE_PUBLIC(QSSGRhiContext)
1063
1064 explicit QSSGRhiContextPrivate(QSSGRhiContext &rhiCtx, QRhi *rhi_)
1065 : q_ptr(&rhiCtx)
1066 , m_rhi(rhi_)
1067 , m_stats(rhiCtx)
1068 {}
1069
1070public:
1071 using Textures = QSet<QRhiTexture *>;
1072 using Meshes = QSet<QSSGRenderMesh *>;
1073
1074 [[nodiscard]] static QSSGRhiContextPrivate *get(QSSGRhiContext *q) { return q->d_ptr.get(); }
1075 [[nodiscard]] static const QSSGRhiContextPrivate *get(const QSSGRhiContext *q) { return q->d_ptr.get(); }
1076
1077 [[nodiscard]] static bool shaderDebuggingEnabled();
1078 [[nodiscard]] static bool editorMode();
1079
1080 void setMainRenderPassDescriptor(QRhiRenderPassDescriptor *rpDesc);
1081 void setCommandBuffer(QRhiCommandBuffer *cb);
1082 void setRenderTarget(QRhiRenderTarget *rt);
1083 void setMainPassSampleCount(int samples);
1084 void setMainPassViewCount(int viewCount);
1085
1086 void releaseCachedResources();
1087
1088 void registerTexture(QRhiTexture *texture);
1089 void releaseTexture(QRhiTexture *texture);
1090
1091 void registerMesh(QSSGRenderMesh *mesh);
1092 void releaseMesh(QSSGRenderMesh *mesh);
1093
1094 QRhiShaderResourceBindings *srb(const QSSGRhiShaderResourceBindingList &bindings);
1095 void releaseCachedSrb(QSSGRhiShaderResourceBindingList &bindings);
1096
1097 QRhiGraphicsPipeline *pipeline(const QSSGRhiGraphicsPipelineState &ps,
1098 QRhiRenderPassDescriptor *rpDesc,
1099 QRhiShaderResourceBindings *srb);
1100
1101 QRhiGraphicsPipeline *pipeline(const QSSGGraphicsPipelineStateKey &key,
1102 QRhiRenderPassDescriptor *rpDesc,
1103 QRhiShaderResourceBindings *srb);
1104
1105 QRhiComputePipeline *computePipeline(const QShader &shader,
1106 QRhiShaderResourceBindings *srb);
1107
1109 QRhiShaderResourceBindings *srb);
1110
1111 QSSGRhiDrawCallData &drawCallData(const QSSGRhiDrawCallDataKey &key);
1112 void releaseDrawCallData(QSSGRhiDrawCallData &dcd);
1113 void cleanupDrawCallData(const QSSGRenderModel *model);
1114 void cleanupDrawCallDataForResource(const void *resource);
1115 void cleanupDrawCallDataForCid(const void *cid);
1116 void cleanupDrawCallDataForSkyMaterial(QSSGRenderSkyMaterial *skyMaterial);
1117
1118 QSSGRhiInstanceBufferData &instanceBufferData(QSSGRenderInstanceTable *instanceTable);
1119 void releaseInstanceBuffer(QSSGRenderInstanceTable *instanceTable);
1120
1121 QSSGRhiInstanceBufferData &instanceBufferData(const QSSGRenderModel *model);
1122
1123 QSSGRhiParticleData &particleData(const QSSGRenderGraphObject *particlesOrModel);
1124
1125 QSSGRhiContext *q_ptr = nullptr;
1126 QRhi *m_rhi = nullptr;
1127
1135
1137
1147};
1148
1149inline bool operator==(const QSSGRhiDrawCallDataKey &a, const QSSGRhiDrawCallDataKey &b) noexcept
1150{
1151 return a.cid == b.cid && a.model == b.model && a.resource == b.resource && a.mapEntry == b.mapEntry
1152 && a.resourceIdx == b.resourceIdx;
1153}
1154
1155inline bool operator!=(const QSSGRhiDrawCallDataKey &a, const QSSGRhiDrawCallDataKey &b) noexcept
1156{
1157 return !(a == b);
1158}
1159
1160inline size_t qHash(const QSSGRhiDrawCallDataKey &k, size_t seed = 0) noexcept
1161{
1162 return qHashMulti(seed, k.cid, k.model, k.resource, k.mapEntry, k.resourceIdx);
1163}
1164
1165QT_END_NAMESPACE
1166
1167#endif // QSSGRHICONTEXT_P_H
friend bool operator==(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
Returns true if lhs and rhs are equal, otherwise returns false.
Definition qbytearray.h:842
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
QObject * q_ptr
Definition qobject.h:73
Q_DECLARE_FLAGS(InitFlags, InitFlag)
static QSSGComputePipelineStateKey create(const QShader &shader, const QRhiShaderResourceBindings *srb)
QVector< quint32 > srbLayoutDescription
QRhiBuffer * buffer() const
QRhiCommandBuffer::IndexFormat indexFormat() const
quint32 stride() const
quint32 numVertices() const
void setMainRenderPassDescriptor(QRhiRenderPassDescriptor *rpDesc)
void releaseInstanceBuffer(QSSGRenderInstanceTable *instanceTable)
QSSGRhiInstanceBufferData & instanceBufferData(const QSSGRenderModel *model)
void releaseDrawCallData(QSSGRhiDrawCallData &dcd)
QRhiRenderPassDescriptor * m_mainRpDesc
QRhiShaderResourceBindings * srb(const QSSGRhiShaderResourceBindingList &bindings)
QSSGRhiDrawCallData & drawCallData(const QSSGRhiDrawCallDataKey &key)
QRhiGraphicsPipeline * pipeline(const QSSGRhiGraphicsPipelineState &ps, QRhiRenderPassDescriptor *rpDesc, QRhiShaderResourceBindings *srb)
void cleanupDrawCallDataForCid(const void *cid)
void releaseCachedSrb(QSSGRhiShaderResourceBindingList &bindings)
void releaseMesh(QSSGRenderMesh *mesh)
QRhiComputePipeline * computePipeline(const QSSGComputePipelineStateKey &key, QRhiShaderResourceBindings *srb)
QHash< QSSGRenderInstanceTable *, QSSGRhiInstanceBufferData > m_instanceBuffers
void setCommandBuffer(QRhiCommandBuffer *cb)
QVector< QPair< QSSGRhiSamplerDescription, QRhiSampler * > > m_samplers
void setMainPassSampleCount(int samples)
QRhiRenderTarget * m_rt
void cleanupDrawCallData(const QSSGRenderModel *model)
QHash< const QSSGRenderGraphObject *, QSSGRhiParticleData > m_particleData
QSSGRhiContextStats m_stats
void cleanupDrawCallDataForResource(const void *resource)
QHash< const QSSGRenderModel *, QSSGRhiInstanceBufferData > m_instanceBuffersLod
QHash< QSSGRhiDummyTextureKey, QRhiTexture * > m_dummyTextures
void registerMesh(QSSGRenderMesh *mesh)
static bool shaderDebuggingEnabled()
QSSGRhiParticleData & particleData(const QSSGRenderGraphObject *particlesOrModel)
void setRenderTarget(QRhiRenderTarget *rt)
QHash< QSSGRhiShaderResourceBindingList, QRhiShaderResourceBindings * > m_srbCache
QHash< QSSGRhiDrawCallDataKey, QSSGRhiDrawCallData > m_drawCallData
void setMainPassViewCount(int viewCount)
QRhiCommandBuffer * m_cb
QRhiComputePipeline * computePipeline(const QShader &shader, QRhiShaderResourceBindings *srb)
QHash< QSSGComputePipelineStateKey, QRhiComputePipeline * > m_computePipelines
QHash< QSSGGraphicsPipelineStateKey, QRhiGraphicsPipeline * > m_pipelines
void cleanupDrawCallDataForSkyMaterial(QSSGRenderSkyMaterial *skyMaterial)
QSSGRhiInstanceBufferData & instanceBufferData(QSSGRenderInstanceTable *instanceTable)
const QSSGManagedRhiTexturePtr & getColorTexture(int index) const
const std::unique_ptr< QRhiRenderPassDescriptor > & getRenderPassDescriptor() const
void setName(const QByteArray &name)
const std::unique_ptr< QRhiTextureRenderTarget > & getRenderTarget() const
const std::unique_ptr< QRhiRenderBuffer > & getDepthStencil() const
const QByteArray & getName() const
const QSSGManagedRhiTexturePtr & getDepthTexture() const
void setUniformValue(char *ubufData, const char *name, const QVariant &value, QSSGRenderShaderValue::Type type)
const QRhiShaderStage * cendStages() const
QRhiTexture * ssaoTexture() const
const QHash< QSSGRhiInputAssemblerState::InputSemantic, QShaderDescription::InOutVariable > & vertexInputs() const
QRhiTexture * lightProbeTexture() const
QRhiTexture * shadowMapAtlasTexture() const
int bindingForImage(const char *name)
QPair< QSSGRenderTextureCoordOp, QSSGRenderTextureCoordOp > lightProbeTiling() const
InstanceLocations instanceBufferLocations() const
void addStage(const QRhiShaderStage &stage, StageFlags flags={})
QRhiTexture * screenTexture() const
void ensureUniformBuffer(QRhiBuffer **ubuf)
QRhiTexture * MotionVectorTexture() const
QRhiTexture * shadowMapBlueNoiseTexture() const
const QRhiShaderStage * cbeginStages() const
const QRhiShaderStage * fragmentStage() const
QRhiTexture * depthTexture() const
void addExtraTexture(const QSSGRhiTexture &t)
void setLightsEnabled(bool enable)
QSSGShaderDirectionalLightsUniformData & directionalLightsUniformData()
int offsetOfUniform(const QByteArray &name)
int bindingForTexture(const char *name, int hint=-1)
void ensureCombinedUniformBuffer(QRhiBuffer **ubuf)
void setShaderResources(char *ubufData, QSSGBufferManager &theBufferManager, const QByteArray &inPropertyName, const QVariant &propertyValue, QSSGRenderShaderValue::Type inPropertyType)
QRhiTexture ** oitImages()
void setUniformArray(char *ubufData, const char *name, const void *data, size_t itemCount, QSSGRenderShaderValue::Type type, int *storeIndex=nullptr)
QRhiTexture * normalTexture() const
int ub0DirectionalLightDataOffset() const
const QRhiShaderStage * vertexStage() const
QSSGShaderLightsUniformData & lightsUniformData()
void setUniform(char *ubufData, const char *name, const void *data, size_t size, int *storeIndex=nullptr, UniformFlags flags={})
QRhiTexture * lightmapTexture() const
const QSSGRhiTexture & extraTextureAt(int index) const
QRhiVertexInputAttribute::Format toVertexInputFormat(QSSGRenderComponentType compType, quint32 numComps)
QRhiGraphicsPipeline::CullMode toCullMode(QSSGCullFaceMode cullFaceMode)
QRhiGraphicsPipeline::Topology toTopology(QSSGRenderDrawMode drawMode)
QRhiSampler::Filter toRhi(QSSGRenderTextureFilterOp op)
Combined button and popup list for selecting options.
static bool skyIblCreatePrefilterTargets(QRhi *rhi, QRhiTexture *texture, const QSize &environmentMapSize, const QByteArray &namePrefix, QSSGSkyIblPrefilterTargets *outTargets, bool preserveColorContents=false)
static constexpr QRhiTexture::Format cTextureFormat
static bool ensureSrb(QRhi *rhi, QRhiShaderResourceBindings *&dst, std::initializer_list< QRhiShaderResourceBinding > bindings, const char *errorMessage)
static bool skyIblCreateFaceTargets(QRhi *rhi, QRhiTexture *texture, const QByteArray &namePrefix, QSSGSkyIblFaceTargets *outTargets, bool preserveColorContents=false)
static QRhiGraphicsPipeline * createPrefilterPipeline(QRhi *rhi, const QRhiVertexInputLayout &inputLayout, const PrefilterPipelineConfig &cfg, const char *errorMessage)
static void drawCubeFace(QRhiCommandBuffer *cb, QSSGRhiContext *ctx, QRhiTextureRenderTarget *rt, QSize viewport, QRhiGraphicsPipeline *pipeline, QRhiShaderResourceBindings *srb, const QRhiCommandBuffer::VertexInput &vbufBinding, const QVector< QPair< int, quint32 > > &dynamicOffsets, const QByteArray &profilerLabel, const QByteArray &passDebugLabel, const QColor &clearColor=QColor(0, 0, 0, 1))
static void skyIblInitializeUnrenderedMips(QRhi *rhi, QRhiCommandBuffer *cb, QSSGRhiContext *context, QRhiTexture *texture, int firstMip, int mipCountExclusive, const QByteArray &debugObjectName)
static bool ensureDynamicUBuf(QRhi *rhi, QRhiBuffer *&dst, int size, const char *errorMessage)
static QVarLengthArray< QMatrix4x4, 6 > skyIblEnvironmentMapViews(QRhi *rhi)
constexpr size_t qHash(const QSize &s, size_t seed=0) noexcept
Definition qsize.h:192
#define QSSGRHICTX_STAT(ctx, f)
#define QSSG_MAX_NUM_LIGHTS
#define QSSG_MAX_NUM_DIRECTIONAL_LIGHTS
QSSGRhiSamplerBindingHints
static constexpr const QSSGRhiShaderPipeline * getShaderPipeline(const QSSGRhiGraphicsPipelineState &ps)
static const InputAssemblerState & get(const QSSGRhiGraphicsPipelineState &ps)
static InputAssemblerState & get(QSSGRhiGraphicsPipelineState &ps)
QList< QSSGRhiSortData > sortData
QList< QSSGRhiSortData > sortData
QRhiTextureRenderTarget * rt
QRhiRenderPassDescriptor * rpDesc
QRhiRenderBuffer * depthStencil
QVarLengthArray< ImageIndices, 16 > imageIndices
QSSGShaderDirectionalLightData directionalLightData[QSSG_MAX_NUM_DIRECTIONAL_LIGHTS]
QSSGShaderLightData lightData[QSSG_MAX_NUM_LIGHTS]