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
qssgrendershadercache_p.h
Go to the documentation of this file.
1// Copyright (C) 2008-2012 NVIDIA Corporation.
2// Copyright (C) 2019 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
6
7#ifndef QSSG_RENDER_SHADER_CACHE_H
8#define QSSG_RENDER_SHADER_CACHE_H
9
10//
11// W A R N I N G
12// -------------
13//
14// This file is not part of the Qt API. It exists purely as an
15// implementation detail. This header file may change from version to
16// version without notice, or even be removed.
17//
18// We mean it.
19//
20
21#include <QtQuick3DRuntimeRender/private/qtquick3druntimerenderglobal_p.h>
22#include <QtQuick3DUtils/private/qssgdataref_p.h>
23#include <QtQuick3DUtils/private/qqsbcollection_p.h>
24
25#include <QtQuick3DRuntimeRender/private/qssgrhicontext_p.h>
26#include <QtQuick3DRuntimeRender/private/qssgrendererimplshaders_p.h>
27
28#include <QtCore/QString>
29#include <QtCore/qcryptographichash.h>
30#include <QtCore/QSharedPointer>
31#include <QtCore/QVector>
32
33QT_BEGIN_NAMESPACE
34
35class QSSGRenderContextInterface;
36class QSSGRhiShaderPipeline;
37class QShaderBaker;
38class QRhi;
39class QSurfaceFormat;
40
41using QSSGUserShaderFragmentOutputs = QVector<QByteArrayView>;
42
48
49using QSSGShaderDefineList = QList<QSSGShaderDefine>;
50
52{
53public:
57
58 enum class FeatureFlags : quint32
59 {
60 None = 0,
61 BaseColor = (1 << 0),
62 Roughness = (1 << 1),
63 Metalness = (1 << 2),
64 DiffuseLight = (1 << 3),
65 SpecularLight = (1 << 4),
66 EmissiveLight = (1 << 5),
67 WorldNormal = (1 << 6),
68 WorldTangent = (1 << 7),
69 WorldBinormal = (1 << 8),
70 F0 = (1 << 9),
71 F90 = (1 << 10)
72 };
73
76
77 void setFeatureFlag(FeatureFlags flag, bool enabled = true)
78 {
79 if (enabled)
80 featureFlags |= static_cast<FeatureFlagsType>(flag);
81 else
82 featureFlags &= ~static_cast<FeatureFlagsType>(flag);
83 }
84
86 {
87 return (featureFlags & static_cast<FeatureFlagsType>(flag)) != 0;
88 }
89
91
93
96
98
100 {
101 return (body.size() > 0);
102 }
103
105 {
106 return propertyUniforms.size() > 0;
107 }
108
109};
110
111
112
113struct Q_QUICK3DRUNTIMERENDER_EXPORT QSSGShaderFeatures
114{
115
116// There are a number of macros used to turn on or off various features.
117// This allows those features to be propagated into the shader cache's caching mechanism.
118// They will be translated into #define name value where value is 1 or zero depending on
119// if the feature is enabled or not.
120//
121// In snippets that use this feature the code would look something like this:
122
123/*
124#ifndef QSSG_ENABLE_<FEATURE>
125#define QSSG_ENABLE_<FEATURE> 0
126#endif
127
128void func()
129{
130 ...
131#if QSSG_ENABLE_<FEATURE>
132 ...
133#endif
134 ...
135}
136*/
137
138// NOTE: The order of these will affect generated keys, so re-ordering these
139// will break already baked shaders (e.g. shadergen).
140using FlagType = quint32;
141enum class Feature : FlagType
142{
143 LightProbe = (1 << 8),
144 IblOrientation = (1 << 9) + 1,
145 Ssm = (1 << 10) + 2,
146 Ssao = (1 << 11) + 3,
147 DepthPass = (1 << 12) + 4,
148 OrthoShadowPass = (1 << 13) + 5,
149 PerspectiveShadowPass = (1 << 14) + 6,
150 LinearTonemapping = (1 << 15) + 7,
151 AcesTonemapping = (1 << 16) + 8,
152 HejlDawsonTonemapping = (1 << 17) + 9,
153 FilmicTonemapping = (1 << 18) + 10,
154 RGBELightProbe = (1 << 19) + 11,
155 OpaqueDepthPrePass = (1 << 20) + 12,
156 ReflectionProbe = (1 << 21) + 13,
157 ReduceMaxNumLights = (1 << 22) + 14,
158 Lightmap = (1 << 23) + 15,
159 DisableMultiView = (1 << 24) + 16,
160 ForceIblExposure = (1 << 25) + 17,
161 NormalPass = (1 << 26) + 18,
162 UserRenderPass = (1 << 27) + 19,
163 MotionVector = (1 << 28) + 20,
164 LastFeature
165};
166
167static constexpr FlagType IndexMask = 0xff;
168static constexpr quint32 Count = (static_cast<FlagType>(Feature::LastFeature) & IndexMask);
169
170static const char *asDefineString(QSSGShaderFeatures::Feature feature);
171static Feature fromIndex(quint32 idx);
172
173constexpr bool isNull() const { return flags == 0; }
174constexpr bool isSet(Feature feature) const { return (static_cast<FlagType>(feature) & flags); }
175void set(Feature feature, bool val);
176
177FlagType flags = 0;
178
179inline friend bool operator==(QSSGShaderFeatures a, QSSGShaderFeatures b) { return a.flags == b.flags; }
180
181void disableTonemapping()
182{
183 set(Feature::LinearTonemapping, false);
184 set(Feature::AcesTonemapping, false);
185 set(Feature::FilmicTonemapping, false);
186 set(Feature::HejlDawsonTonemapping, false);
187 set(Feature::ForceIblExposure, false);
188}
189
190inline friend QDebug operator<<(QDebug stream, const QSSGShaderFeatures &features)
191{
192 QVarLengthArray<const char *, Count> enabledFeatureStrings;
193 for (quint32 idx = 0; idx < Count; ++idx) {
194 const Feature feature = fromIndex(idx);
195 if (features.isSet(feature))
196 enabledFeatureStrings.append(asDefineString(feature));
197 }
198 stream.nospace() << "QSSGShaderFeatures(";
199 for (int i = 0; i < enabledFeatureStrings.size(); ++i)
200 stream.nospace() << (i > 0 ? ", " : "") << enabledFeatureStrings[i];
201 stream.nospace() << ")";
202 return stream;
203}
204
205};
206
207Q_QUICK3DRUNTIMERENDER_EXPORT size_t qHash(QSSGShaderFeatures features) noexcept;
208
210{
214
215 explicit QSSGShaderCacheKey(const QByteArray &key = QByteArray()) : m_key(key), m_hashCode(0) {}
216
217 QSSGShaderCacheKey(const QSSGShaderCacheKey &other) = default;
219
220 static inline size_t generateHashCode(const QByteArray &key, QSSGShaderFeatures features)
221 {
222 return qHash(key) ^ qHash(features);
223 }
224
226 {
227 m_hashCode = generateHashCode(m_key, m_features);
228 }
229
230 bool operator==(const QSSGShaderCacheKey &inOther) const
231 {
232 return m_key == inOther.m_key && m_features == inOther.m_features;
233 }
234};
235
237{
238 return key.m_hashCode;
239}
240
241class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGShaderCache
242{
243 Q_DISABLE_COPY(QSSGShaderCache)
244public:
245 enum class ShaderType
246 {
247 Vertex = 0,
248 Fragment = 1
249 };
250
251 using InitBakerFunc = void (*)(QShaderBaker *baker, QRhi *rhi);
252private:
253 friend class QSSGBuiltInRhiShaderCache;
254
255 typedef QHash<QSSGShaderCacheKey, QSSGRhiShaderPipelinePtr> TRhiShaderMap;
256 QSSGRhiContext &m_rhiContext; // Not own, the RCI owns us and the QSSGRhiContext.
257 TRhiShaderMap m_rhiShaders;
258 QByteArray m_insertStr; // member to potentially reuse the allocation after clear
259 QByteArray m_cacheKeyStr; // same here
260 InitBakerFunc m_initBaker;
261 QQsbInMemoryCollection m_persistentShaderBakingCache;
262 QString m_persistentShaderStorageFileName;
263 QSSGBuiltInRhiShaderCache m_builtInShaders;
264
265 QSSGRhiShaderPipelinePtr loadBuiltinUncached(const QByteArray &inKey, int viewCount,
266 QSSGRhiShaderPipeline::StageFlags vertexStageFlags);
267
268 void addShaderPreprocessor(QByteArray &str,
269 const QByteArray &inKey,
270 ShaderType shaderType,
271 const QSSGShaderFeatures &inFeatures,
272 const QSSGUserShaderAugmentation &shaderAugmentation,
273 int viewCount);
274
275public:
276 QSSGShaderCache(QSSGRhiContext &ctx,
277 const InitBakerFunc initBakeFn = nullptr);
278 ~QSSGShaderCache();
279
280 QSSGRhiContext &rhiContext() { return m_rhiContext; }
281
282 void releaseCachedResources();
283
284 QQsbInMemoryCollection &persistentShaderBakingCache() { return m_persistentShaderBakingCache; }
285
287 const QSSGShaderFeatures &inFeatures);
288
290 const QByteArray &inKey,
291 const QSSGShaderFeatures &inFeatures,
292 QSSGRhiShaderPipeline::StageFlags stageFlags = {});
293
295 const QSSGShaderFeatures &inFeatures,
296 QQsbCollection::Entry entry,
297 const QSSGRenderGraphObject &obj,
298 QSSGRhiShaderPipeline::StageFlags stageFlags = {});
299
301 const QByteArray &inVert,
302 const QByteArray &inFrag,
303 const QSSGShaderFeatures &inFeatures,
304 QSSGRhiShaderPipeline::StageFlags stageFlags,
305 const QSSGUserShaderAugmentation &shaderAugmentation,
306 int viewCount,
307 bool perTargetCompilation,
308 const QByteArray &inCacheKey = {});
309
310 QSSGRhiShaderPipelinePtr compileComputePipeline(const QByteArray &inKey,
311 const QByteArray &inComp,
312 int viewCount,
313 bool perTargetCompilation,
314 const QByteArray &inCacheKey = {});
315
316 QSSGBuiltInRhiShaderCache &getBuiltInRhiShaders() { return m_builtInShaders; }
317
318 static QByteArray resourceFolder();
321 static void initBakerForPersistentUse(QShaderBaker *baker, QRhi *rhi);
322 static QList<QShaderVersion> glslTargetsForContext(const QSurfaceFormat &format, bool isGLESModule);
323};
324
325namespace QtQuick3DEditorHelpers {
326namespace ShaderBaker
327{
328 enum class Status : quint8
329 {
332 };
333 using StatusCallback = void(*)(const QByteArray &descKey, Status status, const QString &err, QShader::Stage stage);
334 Q_QUICK3DRUNTIMERENDER_EXPORT void setStatusCallback(StatusCallback cb);
335}
336
337namespace ShaderCache
338{
339 // Used by DS and the QML puppet!
340 // Note: Needs to be called before any QSSGShaderCache instance is created.
341 Q_QUICK3DRUNTIMERENDER_EXPORT void setAutomaticDiskCache(bool enable);
342 Q_QUICK3DRUNTIMERENDER_EXPORT bool isAutomaticDiskCacheEnabled();
343}
344
345}
346
347QT_END_NAMESPACE
348
349#endif
const std::unique_ptr< QSSGRhiContext > & rhiContext() const
QSSGBuiltInRhiShaderCache & getBuiltInRhiShaders()
QSSGRhiShaderPipelinePtr tryGetRhiShaderPipeline(const QByteArray &inKey, const QSSGShaderFeatures &inFeatures)
static void initBakerForPersistentUse(QShaderBaker *baker, QRhi *rhi)
static QByteArray shaderCollectionFile()
QSSGRhiShaderPipelinePtr compileGraphicsPipeline(const QByteArray &inKey, const QByteArray &inVert, const QByteArray &inFrag, const QSSGShaderFeatures &inFeatures, QSSGRhiShaderPipeline::StageFlags stageFlags, const QSSGUserShaderAugmentation &shaderAugmentation, int viewCount, bool perTargetCompilation, const QByteArray &inCacheKey={})
static QList< QShaderVersion > glslTargetsForContext(const QSurfaceFormat &format, bool isGLESModule)
QQsbInMemoryCollection & persistentShaderBakingCache()
static QByteArray resourceFolder()
QSSGRhiShaderPipelinePtr newPipelineFromPregenerated(const QByteArray &inKey, const QSSGShaderFeatures &inFeatures, QQsbCollection::Entry entry, const QSSGRenderGraphObject &obj, QSSGRhiShaderPipeline::StageFlags stageFlags={})
static QByteArray particleShaderCollectionFile()
QSSGRhiShaderPipelinePtr tryNewPipelineFromPersistentCache(const QByteArray &qsbcKey, const QByteArray &inKey, const QSSGShaderFeatures &inFeatures, QSSGRhiShaderPipeline::StageFlags stageFlags={})
QSSGRhiShaderPipelinePtr compileComputePipeline(const QByteArray &inKey, const QByteArray &inComp, int viewCount, bool perTargetCompilation, const QByteArray &inCacheKey={})
void(*)(QShaderBaker *baker, QRhi *rhi) InitBakerFunc
PropertyUniformsList propertyUniforms
void setFeatureFlag(FeatureFlags flag, bool enabled=true)
bool isFeatureFlagSet(FeatureFlags flag) const
QSSGUserShaderFragmentOutputs outputs
constexpr QSSGCameraId getCameraId(const QSSGRenderGraphObject &o)
constexpr QSSGResourceId getResourceId(const QSSGRenderGraphObject &o)
T * getExtension(QSSGExtensionId extensionId)
static constexpr bool isSceneRoot(QSSGRenderGraphObject::Type type) noexcept
T * getResource(QSSGResourceId resId)
static constexpr bool isUserRenderPass(QSSGRenderGraphObject::Type type) noexcept
constexpr QSSGExtensionId getExtensionId(const QSSGRenderGraphObject &o)
static constexpr bool hasInternalFlag(const QSSGRenderGraphObject &obj, InternalFlags flag)
constexpr bool isNull(QSSGTypeId id)
static constexpr bool hasInternalFlags(const QSSGRenderGraphObject &obj)
T * getCamera(QSSGCameraId cameraId)
static constexpr bool isTextureProvider(QSSGRenderGraphObject::Type type) noexcept
constexpr QSSGNodeId getNodeId(const QSSGRenderGraphObject &o)
static constexpr QSSGRenderGraphObject::BaseType getBaseType(QSSGRenderGraphObject::Type type) noexcept
Combined button and popup list for selecting options.
Q_QUICK3DRUNTIMERENDER_EXPORT void setStatusCallback(StatusCallback cb)
void(*)(const QByteArray &descKey, Status status, const QString &err, QShader::Stage stage) StatusCallback
Q_QUICK3DRUNTIMERENDER_EXPORT void setAutomaticDiskCache(bool enable)
Q_QUICK3DRUNTIMERENDER_EXPORT bool isAutomaticDiskCacheEnabled()
Q_GLOBAL_STATIC(QReadWriteLock, g_updateMutex)
static QString persistentQsbcFileName()
static bool isAutoDiskCacheEnabled()
size_t qHash(QSSGShaderFeatures features) noexcept
static bool ensureWritableDir(const QString &name)
static bool s_autoDiskCacheEnabled
static QString persistentQsbcDir()
static void initBakerForNonPersistentUse(QShaderBaker *, QRhi *)
static constexpr DefineEntry DefineTable[]
size_t qHash(const QSSGShaderCacheKey &key)
static size_t generateHashCode(const QByteArray &key, QSSGShaderFeatures features)
QSSGShaderCacheKey & operator=(const QSSGShaderCacheKey &other)=default
bool operator==(const QSSGShaderCacheKey &inOther) const
QSSGShaderCacheKey(const QSSGShaderCacheKey &other)=default
QSSGShaderCacheKey(const QByteArray &key=QByteArray())
QSSGShaderFeatures m_features