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
5#ifndef QSSG_RENDER_SHADER_CACHE_H
6#define QSSG_RENDER_SHADER_CACHE_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 <QtQuick3DUtils/private/qssgdataref_p.h>
21#include <QtQuick3DUtils/private/qqsbcollection_p.h>
22
23#include <QtQuick3DRuntimeRender/private/qssgrhicontext_p.h>
24#include <QtQuick3DRuntimeRender/private/qssgrendererimplshaders_p.h>
25
26#include <QtCore/QString>
27#include <QtCore/qcryptographichash.h>
28#include <QtCore/QSharedPointer>
29#include <QtCore/QVector>
30
31QT_BEGIN_NAMESPACE
32
33class QSSGRenderContextInterface;
34class QSSGRhiShaderPipeline;
35class QShaderBaker;
36class QRhi;
37
38struct Q_QUICK3DRUNTIMERENDER_EXPORT QSSGShaderFeatures
39{
40
41// There are a number of macros used to turn on or off various features.
42// This allows those features to be propagated into the shader cache's caching mechanism.
43// They will be translated into #define name value where value is 1 or zero depending on
44// if the feature is enabled or not.
45//
46// In snippets that use this feature the code would look something like this:
47
48/*
49#ifndef QSSG_ENABLE_<FEATURE>
50#define QSSG_ENABLE_<FEATURE> 0
51#endif
52
53void func()
54{
55 ...
56#if QSSG_ENABLE_<FEATURE>
57 ...
58#endif
59 ...
60}
61*/
62
63// NOTE: The order of these will affect generated keys, so re-ordering these
64// will break already baked shaders (e.g. shadergen).
65using FlagType = quint32;
66enum class Feature : FlagType
67{
68 LightProbe = (1 << 8),
69 IblOrientation = (1 << 9) + 1,
70 Ssm = (1 << 10) + 2,
71 Ssao = (1 << 11) + 3,
72 DepthPass = (1 << 12) + 4,
73 OrthoShadowPass = (1 << 13) + 5,
74 PerspectiveShadowPass = (1 << 14) + 6,
75 LinearTonemapping = (1 << 15) + 7,
76 AcesTonemapping = (1 << 16) + 8,
77 HejlDawsonTonemapping = (1 << 17) + 9,
78 FilmicTonemapping = (1 << 18) + 10,
79 RGBELightProbe = (1 << 19) + 11,
80 OpaqueDepthPrePass = (1 << 20) + 12,
81 ReflectionProbe = (1 << 21) + 13,
82 ReduceMaxNumLights = (1 << 22) + 14,
83 Lightmap = (1 << 23) + 15,
84 DisableMultiView = (1 << 24) + 16,
85 ForceIblExposure = (1 << 25) + 17,
86 NormalPass = (1 << 26) + 18,
87
88 LastFeature
89};
90
91static constexpr FlagType IndexMask = 0xff;
92static constexpr quint32 Count = (static_cast<FlagType>(Feature::LastFeature) & IndexMask);
93
94static const char *asDefineString(QSSGShaderFeatures::Feature feature);
95static Feature fromIndex(quint32 idx);
96
97constexpr bool isNull() const { return flags == 0; }
98constexpr bool isSet(Feature feature) const { return (static_cast<FlagType>(feature) & flags); }
99void set(Feature feature, bool val);
100
101FlagType flags = 0;
102
103inline friend bool operator==(QSSGShaderFeatures a, QSSGShaderFeatures b) { return a.flags == b.flags; }
104
105void disableTonemapping()
106{
107 set(Feature::LinearTonemapping, false);
108 set(Feature::AcesTonemapping, false);
109 set(Feature::FilmicTonemapping, false);
110 set(Feature::HejlDawsonTonemapping, false);
111 set(Feature::ForceIblExposure, false);
112}
113
114inline friend QDebug operator<<(QDebug stream, const QSSGShaderFeatures &features)
115{
116 QVarLengthArray<const char *, Count> enabledFeatureStrings;
117 for (quint32 idx = 0; idx < Count; ++idx) {
118 const Feature feature = fromIndex(idx);
119 if (features.isSet(feature))
120 enabledFeatureStrings.append(asDefineString(feature));
121 }
122 stream.nospace() << "QSSGShaderFeatures(";
123 for (int i = 0; i < enabledFeatureStrings.size(); ++i)
124 stream.nospace() << (i > 0 ? ", " : "") << enabledFeatureStrings[i];
125 stream.nospace() << ")";
126 return stream;
127}
128
129};
130
131Q_QUICK3DRUNTIMERENDER_EXPORT size_t qHash(QSSGShaderFeatures features) noexcept;
132
134{
138
139 explicit QSSGShaderCacheKey(const QByteArray &key = QByteArray()) : m_key(key), m_hashCode(0) {}
140
141 QSSGShaderCacheKey(const QSSGShaderCacheKey &other) = default;
143
144 static inline size_t generateHashCode(const QByteArray &key, QSSGShaderFeatures features)
145 {
146 return qHash(key) ^ qHash(features);
147 }
148
150 {
151 m_hashCode = generateHashCode(m_key, m_features);
152 }
153
154 bool operator==(const QSSGShaderCacheKey &inOther) const
155 {
156 return m_key == inOther.m_key && m_features == inOther.m_features;
157 }
158};
159
161{
162 return key.m_hashCode;
163}
164
165class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGShaderCache
166{
167 Q_DISABLE_COPY(QSSGShaderCache)
168public:
169 enum class ShaderType
170 {
171 Vertex = 0,
172 Fragment = 1
173 };
174
175 using InitBakerFunc = void (*)(QShaderBaker *baker, QRhi *rhi);
176private:
177 friend class QSSGBuiltInRhiShaderCache;
178
179 typedef QHash<QSSGShaderCacheKey, QSSGRhiShaderPipelinePtr> TRhiShaderMap;
180 QSSGRhiContext &m_rhiContext; // Not own, the RCI owns us and the QSSGRhiContext.
181 TRhiShaderMap m_rhiShaders;
182 QByteArray m_insertStr; // member to potentially reuse the allocation after clear
183 QByteArray m_cacheKeyStr; // same here
184 InitBakerFunc m_initBaker;
185 QQsbInMemoryCollection m_persistentShaderBakingCache;
186 QString m_persistentShaderStorageFileName;
187 QSSGBuiltInRhiShaderCache m_builtInShaders;
188
189 QSSGRhiShaderPipelinePtr loadBuiltinUncached(const QByteArray &inKey, int viewCount);
190
191 void addShaderPreprocessor(QByteArray &str,
192 const QByteArray &inKey,
193 ShaderType shaderType,
194 const QSSGShaderFeatures &inFeatures,
195 int viewCount);
196
197public:
198 QSSGShaderCache(QSSGRhiContext &ctx,
199 const InitBakerFunc initBakeFn = nullptr);
200 ~QSSGShaderCache();
201
202 void releaseCachedResources();
203
204 QQsbInMemoryCollection &persistentShaderBakingCache() { return m_persistentShaderBakingCache; }
205
207 const QSSGShaderFeatures &inFeatures);
208
210 const QByteArray &inKey,
211 const QSSGShaderFeatures &inFeatures,
212 QSSGRhiShaderPipeline::StageFlags stageFlags = {});
213
215 const QSSGShaderFeatures &inFeatures,
216 QQsbCollection::Entry entry,
217 const QSSGRenderGraphObject &obj,
218 QSSGRhiShaderPipeline::StageFlags stageFlags = {});
219
220 QSSGRhiShaderPipelinePtr compileForRhi(const QByteArray &inKey,
221 const QByteArray &inVert,
222 const QByteArray &inFrag,
223 const QSSGShaderFeatures &inFeatures,
224 QSSGRhiShaderPipeline::StageFlags stageFlags,
225 int viewCount,
226 bool perTargetCompilation);
227
228 QSSGBuiltInRhiShaderCache &getBuiltInRhiShaders() { return m_builtInShaders; }
229
230 static QByteArray resourceFolder();
232};
233
234namespace QtQuick3DEditorHelpers {
235namespace ShaderBaker
236{
237 enum class Status : quint8
238 {
241 };
242 using StatusCallback = void(*)(const QByteArray &descKey, Status status, const QString &err, QShader::Stage stage);
243 Q_QUICK3DRUNTIMERENDER_EXPORT void setStatusCallback(StatusCallback cb);
244}
245
246namespace ShaderCache
247{
248 // Used by DS and the QML puppet!
249 // Note: Needs to be called before any QSSGShaderCache instance is created.
250 Q_QUICK3DRUNTIMERENDER_EXPORT void setAutomaticDiskCache(bool enable);
251 Q_QUICK3DRUNTIMERENDER_EXPORT bool isAutomaticDiskCacheEnabled();
252}
253
254}
255
256QT_END_NAMESPACE
257
258#endif
QSSGBuiltInRhiShaderCache & getBuiltInRhiShaders()
QSSGRhiShaderPipelinePtr tryGetRhiShaderPipeline(const QByteArray &inKey, const QSSGShaderFeatures &inFeatures)
static QByteArray shaderCollectionFile()
QQsbInMemoryCollection & persistentShaderBakingCache()
static QByteArray resourceFolder()
QSSGRhiShaderPipelinePtr newPipelineFromPregenerated(const QByteArray &inKey, const QSSGShaderFeatures &inFeatures, QQsbCollection::Entry entry, const QSSGRenderGraphObject &obj, QSSGRhiShaderPipeline::StageFlags stageFlags={})
QSSGRhiShaderPipelinePtr compileForRhi(const QByteArray &inKey, const QByteArray &inVert, const QByteArray &inFrag, const QSSGShaderFeatures &inFeatures, QSSGRhiShaderPipeline::StageFlags stageFlags, int viewCount, bool perTargetCompilation)
QSSGRhiShaderPipelinePtr tryNewPipelineFromPersistentCache(const QByteArray &qsbcKey, const QByteArray &inKey, const QSSGShaderFeatures &inFeatures, QSSGRhiShaderPipeline::StageFlags stageFlags={})
void(*)(QShaderBaker *baker, QRhi *rhi) InitBakerFunc
constexpr QSSGCameraId getCameraId(const QSSGRenderGraphObject &o)
constexpr QSSGResourceId getResourceId(const QSSGRenderGraphObject &o)
T * getExtension(QSSGExtensionId extensionId)
T * getResource(QSSGResourceId resId)
constexpr QSSGExtensionId getExtensionId(const QSSGRenderGraphObject &o)
constexpr bool isNull(QSSGTypeId id)
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
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 dumpFilename(QShader::Stage stage)
static void initBakerForPersistentUse(QShaderBaker *, QRhi *)
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