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
qssgrenderskymaterialmanager_p.h
Go to the documentation of this file.
1// Copyright (C) 2026 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#ifndef QSSGRENDERSKYMATERIALMANAGER_H
6#define QSSGRENDERSKYMATERIALMANAGER_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtQuick3DRuntimeRender/private/qtquick3druntimerenderglobal_p.h>
20#include <QtQuick3DRuntimeRender/private/qssgrenderimagetexture_p.h>
21#include <QtQuick3DRuntimeRender/private/qssgrenderskymaterial_p.h>
22
23#include <QtCore/qhash.h>
24#include <QtCore/qlist.h>
25#include <QtCore/qmap.h>
26#include <QtCore/qsize.h>
27#include <QtCore/qvarlengtharray.h>
28
29#include <rhi/qrhi.h>
30
31#include <memory>
32
33QT_BEGIN_NAMESPACE
34
35class QSSGRenderContextInterface;
36class QSSGRhiShaderPipeline;
37
38using QSSGSkyIblCubeFaceRenderTargets = QVarLengthArray<QRhiTextureRenderTarget *, 6>;
39
45
53
54class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRenderSkyMaterialManager
55{
56 Q_DISABLE_COPY(QSSGRenderSkyMaterialManager)
57public:
58 explicit QSSGRenderSkyMaterialManager(const QSSGRenderContextInterface &inContext);
59 ~QSSGRenderSkyMaterialManager();
60
61 void releaseCachedResources();
62
63 QSSGRenderImageTexture resolve(QSSGRenderSkyMaterial *settings);
64
65private:
66 bool ensureEnvironmentMap(QSSGRenderSkyMaterial *settings);
67
68 struct FrameState;
69
70 bool computeFrameState(QSSGRenderSkyMaterial *inSky, FrameState &fs);
71 bool ensureTextures(FrameState &fs);
72 void deriveCycleState(QSSGRenderSkyMaterial *inSky, FrameState &fs);
73 void validateAndUpdateCacheKey(const FrameState &fs, QSSGRhiShaderPipeline *envShaderPipelineKey);
74 bool ensureSharedResources(FrameState &fs, QRhiCommandBuffer *cb);
75 bool renderEnvironmentCube(QSSGRenderSkyMaterial *inSky,
76 const FrameState &fs,
77 const QSSGRhiShaderPipelinePtr &shaderPipeline,
78 QRhiCommandBuffer *cb,
79 QRhiResourceUpdateBatch *rub);
80 void runEnvironmentMipChain(const FrameState &fs, QRhiCommandBuffer *cb);
81 bool runPrefilterCycle(QSSGRenderSkyMaterial *inSky, const FrameState &fs, QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *&rub);
82 void initializeTailMips(const FrameState &fs, QRhiCommandBuffer *cb);
83
84 const QSSGRenderContextInterface &m_context;
85
86 QSSGRenderImageTexture m_skyIblTexture;
87
88 // The procedural cubemap is shared between IBL modes;
89 // m_prefilteredCubeMap is only allocated when IBL is enabled.
90 QRhiTexture *m_envCubeMap = nullptr;
91 QRhiTexture *m_prefilteredCubeMap = nullptr;
92 QSize m_cubeMapSize;
93 int m_prefilteredMipCount = 0;
94
95 // One non-mipmapped GL_TEXTURE_2D_ARRAY per specular mip level.
96 // Storing them separately (rather than as one mipmapped array) works
97 // around an Android GLES driver bug where glFramebufferTextureLayer
98 // silently ignores level > 0, causing all slice writes to land on
99 // mip 0 and corrupting the prefiltered result. Each texture here has
100 // exactly one mip level and is always attached at level 0.
101 QList<QRhiTexture *> m_prefilterAccumulators;
102
103 int m_accumulatedSamples = 0;
104 int m_accumIblSampleCount = 0;
105 bool m_haveConvergedResult = false;
106 bool m_envTailMipsInitialized = false;
107 bool m_prefilteredTailMipsInitialized = false;
108
109 struct PrefilterResourceCache
110 {
111 // Invalidation keys
112 QSize environmentMapSize;
113 bool enableIBL = false;
114 int prefilterTotalMipCount = 0;
115 QRhiTexture *envCubeMap = nullptr;
116 QRhiTexture *prefilteredCubeMap = nullptr;
117 // One entry per specular mip level, mirroring m_prefilterAccumulators.
118 QList<QRhiTexture *> prefilterAccumulators;
119 QSSGRhiShaderPipeline *envShaderPipeline = nullptr;
120
121 // Cached resources.
122 QRhiBuffer *vertexBuffer = nullptr;
123 QRhiBuffer *uBuf = nullptr;
124 QRhiBuffer *uBufSlice = nullptr;
125 QRhiBuffer *uBufNormalize = nullptr;
126 QRhiBuffer *uBufIrradiance = nullptr;
127
128 QSSGSkyIblFaceTargets envFaceTargets;
129 QSSGSkyIblPrefilterTargets prefilterTargets;
130
131 // Per-mip face targets for the accumulator (one entry per specular mip level).
132 // Preserve variant: loads existing content so additive slices accumulate.
133 // Clear variant: clears before drawing, used on the first slice.
134 QList<QSSGSkyIblFaceTargets> accumPreserveFaceTargets;
135 QList<QSSGSkyIblFaceTargets> accumClearFaceTargets;
136
137 QRhiShaderResourceBindings *sliceSrb = nullptr;
138 // One SRB per specular mip level, each binding the corresponding
139 // per-mip accumulator texture so the normalize pass reads the right data.
140 QVarLengthArray<QRhiShaderResourceBindings *, 6> normalizeSrbs;
141 QRhiShaderResourceBindings *irradianceSrb = nullptr;
142
143 QRhiGraphicsPipeline *envMapPipeline = nullptr;
144 QRhiGraphicsPipeline *slicePipeline = nullptr;
145 QRhiGraphicsPipeline *normalizeCubePipeline = nullptr;
146 QRhiGraphicsPipeline *irradiancePipeline = nullptr;
147 };
148
149 PrefilterResourceCache m_cache;
150
151 void clearPrefilterCache();
152};
153
154using QSSGRenderSkyMaterialManagerPtr = std::shared_ptr<QSSGRenderSkyMaterialManager>;
155
156QT_END_NAMESPACE
157
158#endif
QSSGRenderImageTexture resolve(QSSGRenderSkyMaterial *settings)
friend class QSSGRenderContextInterface
QSSGSkyIblCubeFaceRenderTargets renderTargets
QRhiRenderPassDescriptor * renderPassDesc
QVarLengthArray< QSize, 6 > mipLevelSizes
QVarLengthArray< QSSGSkyIblCubeFaceRenderTargets, 6 > mipRenderTargetsMap
QRhiRenderPassDescriptor * renderPassDesc