Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qssgrendershaderlibrarymanager.cpp
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
6
7#include <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.h>
8#include <QtQuick3DRuntimeRender/private/qssgrenderloadedtexture_p.h>
9
10#include <QXmlStreamReader>
11#include <QFileInfo>
12#include <QCryptographicHash>
13
14#include <QtQuick3DRuntimeRender/private/qssgruntimerenderlogging_p.h>
15
17
19{
20 return QStringLiteral("res/effectlib");
21}
22static QByteArray includeSearch() { return QByteArrayLiteral("#include \""); };
23static QByteArray copyrightHeaderStart() { return QByteArrayLiteral("/****************************************************************************"); }
24static QByteArray copyrightHeaderEnd() { return QByteArrayLiteral("****************************************************************************/"); }
25
27
29
31{
32 switch (type) {
34 return 'V';
36 return 'F';
37 default:
38 break;
39 }
40 return '?';
41}
42
44 const QByteArray &inSource, const QSSGCustomShaderMetaData &meta)
45{
46 QWriteLocker locker(&m_lock);
47
48 const QByteArray perStageKey = stageKey(type) + inShaderPathKey;
49 {
50 auto it = m_expandedFiles.find(perStageKey);
51 if (it != m_expandedFiles.end())
52 it.value() = inSource;
53 else
54 m_expandedFiles.insert(perStageKey, inSource);
55 }
56
57 {
58 auto it = m_metadata.find(perStageKey);
59 if (it != m_metadata.end())
60 it.value() = meta;
61 else
62 m_metadata.insert(perStageKey, meta);
63 }
64}
65
66void QSSGShaderLibraryManager::resolveIncludeFiles(QByteArray &theReadBuffer, const QByteArray &inMaterialInfoString)
67{
68 // Now do search and replace for the headers
69 for (int thePos = theReadBuffer.indexOf(includeSearch()); thePos != -1;
70 thePos = theReadBuffer.indexOf(includeSearch(), thePos + 1)) {
71 int theEndQuote = theReadBuffer.indexOf('\"', thePos + includeSearch().size() + 1);
72 // Indicates an unterminated include file.
73 if (theEndQuote == -1) {
74 qCCritical(INVALID_OPERATION, "Unterminated include in file: %s", inMaterialInfoString.constData());
75 theReadBuffer.clear();
76 break;
77 }
78 const int theActualBegin = thePos + includeSearch().size();
79 const auto &theInclude = theReadBuffer.mid(theActualBegin, theEndQuote - theActualBegin);
80 // If we haven't included the file yet this round
81 auto contents = getIncludeContents(theInclude);
82 // Strip copywrite headers from include if present
83 if (contents.startsWith(copyrightHeaderStart())) {
84 int clipPos = contents.indexOf(copyrightHeaderEnd()) ;
85 if (clipPos >= 0)
86 contents.remove(0, clipPos + copyrightHeaderEnd().size());
87 }
88 // Write insert comment for begin source
89 contents.prepend(QByteArrayLiteral("\n// begin \"") + theInclude + QByteArrayLiteral("\"\n"));
90 // Write insert comment for end source
91 contents.append(QByteArrayLiteral("\n// end \"" ) + theInclude + QByteArrayLiteral("\"\n"));
92
93 theReadBuffer = theReadBuffer.replace(thePos, (theEndQuote + 1) - thePos, contents);
94 }
95}
96
98{
99 QWriteLocker locker(&m_lock);
100
101 auto theInsert = m_expandedFiles.constFind(inShaderPathKey);
102 const bool found = (theInsert != m_expandedFiles.cend());
103
104 QByteArray theReadBuffer;
105 if (!found) {
106 const QString defaultDir = getShaderCodeLibraryDirectory();
107 const auto ver = QByteArrayLiteral("rhi");
108
109 QString fullPath;
111 QTextStream stream(&fullPath);
112 stream << defaultDir << QLatin1Char('/') << ver << QLatin1Char('/') << QString::fromLocal8Bit(inShaderPathKey);
113 theStream = QSSGInputUtil::getStreamForFile(fullPath, true);
114 if (theStream.isNull()) {
115 fullPath.clear();
116 QTextStream stream(&fullPath);
117 stream << defaultDir << QLatin1Char('/') << QString::fromLocal8Bit(inShaderPathKey);
118 theStream = QSSGInputUtil::getStreamForFile(fullPath, false);
119 }
120 if (!theStream.isNull()) {
121 char readBuf[1024];
122 qint64 amountRead = 0;
123 do {
124 amountRead = theStream->read(readBuf, 1024);
125 if (amountRead)
126 theReadBuffer.append(readBuf, int(amountRead));
127 } while (amountRead);
128 } else {
129 qCCritical(INVALID_OPERATION, "Failed to find include file %s", qPrintable(QString::fromLocal8Bit(inShaderPathKey)));
130 Q_ASSERT(false);
131 }
132 theInsert = m_expandedFiles.insert(inShaderPathKey, theReadBuffer);
133 } else {
134 theReadBuffer = theInsert.value();
135 }
136
137 locker.unlock();
138 resolveIncludeFiles(theReadBuffer, inShaderPathKey);
139
140 return theReadBuffer;
141}
142
144{
145 QReadLocker locker(&m_lock);
146
147 const QByteArray perStageKey = stageKey(type) + inShaderPathKey;
148 auto it = m_expandedFiles.constFind(perStageKey);
149 if (it != m_expandedFiles.cend())
150 return it.value();
151
152 qWarning("No shader source stored for key %s", perStageKey.constData());
153 return QByteArray();
154}
155
157{
158 QReadLocker locker(&m_lock);
159
160 const QByteArray perStageKey = stageKey(type) + inShaderPathKey;
161 auto it = m_metadata.constFind(perStageKey);
162 if (it != m_metadata.cend())
163 return it.value();
164
165 qWarning("No shader metadata stored for key %s", perStageKey.constData());
166 return {};
167}
168
170{
172 QFile file(collectionFilePath);
173 if (file.exists()) {
177 qsbc.unmap();
178 }
179}
180
183 return prop.m_lightFlags[i].getValue(key) + prop.m_lightSpotFlags[i].getValue(key) * 2
184 + prop.m_lightAreaFlags[i].getValue(key) * 4 + prop.m_lightShadowFlags[i].getValue(key) * 8;
185};
186
188{
190#define COMPARE_PROP(x) \
191 if (props.x.getValue(key1) < props.x.getValue(key2)) return true;
192
193 COMPARE_PROP(m_hasLighting)
194 COMPARE_PROP(m_hasIbl)
195 COMPARE_PROP(m_specularEnabled)
196 COMPARE_PROP(m_fresnelEnabled)
197 COMPARE_PROP(m_vertexColorsEnabled)
198 COMPARE_PROP(m_specularModel)
199 COMPARE_PROP(m_vertexAttributes)
200 COMPARE_PROP(m_alphaMode)
201
203 COMPARE_PROP(m_imageMaps[i])
204 }
206 COMPARE_PROP(m_textureChannels[i])
207 }
208 COMPARE_PROP(m_lightCount)
210 int lp1 = calcLightPoint(key1, i);
211 int lp2 = calcLightPoint(key2, i);
212 if (lp1 < lp2)
213 return true;
214 }
215#undef COMPARE_PROP
216 return false;
217}
218
\inmodule QtCore
Definition qbytearray.h:57
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
Definition qbytearray.h:474
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
qsizetype indexOf(char c, qsizetype from=0) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void clear()
Clears the contents of the byte array and makes it null.
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray mid(qsizetype index, qsizetype len=-1) const
Returns a byte array containing len bytes from this byte array, starting at position pos.
QByteArray & replace(qsizetype index, qsizetype len, const char *s, qsizetype alen)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qbytearray.h:275
\inmodule QtCore
Definition qfile.h:93
bool exists() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qfile.cpp:351
const_iterator constFind(const Key &key) const noexcept
Definition qhash.h:1279
iterator find(const Key &key)
Returns an iterator pointing to the item with the key in the hash.
Definition qhash.h:1258
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
Definition qhash.h:1206
const_iterator cend() const noexcept
Definition qhash.h:1208
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1283
bool map(MapMode mode)
EntryMap availableEntries() const override
\inmodule QtCore
static QByteArray shaderCollectionFile()
static QByteArray resourceFolder()
QSSGCustomShaderMetaData getShaderMetaData(const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type)
void setShaderSource(const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type, const QByteArray &inSource, const QSSGCustomShaderMetaData &meta)
QByteArray getShaderSource(const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type)
static bool compare(const QSSGShaderDefaultMaterialKey &key1, const QSSGShaderDefaultMaterialKey &key2)
QHash< QByteArray, QSSGCustomShaderMetaData > m_metadata
QByteArray getIncludeContents(const QByteArray &inShaderPathKey)
void resolveIncludeFiles(QByteArray &theReadBuffer, const QByteArray &inMaterialInfoString)
QQsbCollection::EntryMap m_preGeneratedShaderEntries
\inmodule QtCore
bool isNull() const noexcept
Returns true if this object refers to \nullptr.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5710
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5788
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1107
\inmodule QtCore
\inmodule QtCore
QSet< QString >::iterator it
Combined button and popup list for selecting options.
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
EGLStreamKHR stream
#define qWarning
Definition qlogging.h:162
#define qCCritical(category,...)
GLuint64 key
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum type
GLenum GLuint GLsizei const GLenum * props
GLuint64EXT GLuint GLuint GLenum GLenum GLuint GLuint GLenum GLuint GLuint key1
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QByteArray copyrightHeaderStart()
#define COMPARE_PROP(x)
static int calcLightPoint(const QSSGShaderDefaultMaterialKey &key, int i)
static QByteArray includeSearch()
static QByteArray copyrightHeaderEnd()
static char stageKey(QSSGShaderCache::ShaderType type)
#define qPrintable(string)
Definition qstring.h:1391
#define QStringLiteral(str)
long long qint64
Definition qtypes.h:55
QFile file
[0]
\inmodule QtCore \reentrant
Definition qchar.h:17
static QSharedPointer< QIODevice > getStreamForFile(const QString &inPath, bool inQuiet=false, QString *outPath=nullptr)
QSSGShaderKeyBoolean m_lightSpotFlags[LightCount]
QSSGShaderKeyBoolean m_lightAreaFlags[LightCount]
QSSGShaderKeyBoolean m_lightFlags[LightCount]
QSSGShaderKeyBoolean m_lightShadowFlags[LightCount]
bool getValue(QSSGDataView< quint32 > inDataStore) const