43void QSSGShaderLibraryManager::setShaderSource(
const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type,
44 const QByteArray &inSource,
const QSSGCustomShaderMetaData &meta)
46 QWriteLocker locker(&m_lock);
48 const QByteArray perStageKey = stageKey(type) + inShaderPathKey;
50 auto it = m_expandedFiles.find(perStageKey);
51 if (it != m_expandedFiles.end())
52 it.value() = inSource;
54 m_expandedFiles.insert(perStageKey, inSource);
58 auto it = m_metadata.find(perStageKey);
59 if (it != m_metadata.end())
62 m_metadata.insert(perStageKey, meta);
66void QSSGShaderLibraryManager::resolveIncludeFiles(QByteArray &theReadBuffer,
const QByteArray &inMaterialInfoString)
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);
73 if (theEndQuote == -1) {
74 qCCritical(INVALID_OPERATION,
"Unterminated include in file: %s", inMaterialInfoString.constData());
75 theReadBuffer.clear();
78 const int theActualBegin = thePos + includeSearch().size();
79 const auto &theInclude = theReadBuffer.mid(theActualBegin, theEndQuote - theActualBegin);
81 auto contents = getIncludeContents(theInclude);
83 if (contents.startsWith(copyrightHeaderStart())) {
84 int clipPos = contents.indexOf(copyrightHeaderEnd()) ;
86 contents.remove(0, clipPos + copyrightHeaderEnd().size());
89 contents.prepend(QByteArrayLiteral(
"\n// begin \"") + theInclude + QByteArrayLiteral(
"\"\n"));
91 contents.append(QByteArrayLiteral(
"\n// end \"" ) + theInclude + QByteArrayLiteral(
"\"\n"));
93 theReadBuffer = theReadBuffer.replace(thePos, (theEndQuote + 1) - thePos, contents);
97QByteArray QSSGShaderLibraryManager::getIncludeContents(
const QByteArray &inShaderPathKey)
99 QWriteLocker locker(&m_lock);
101 auto theInsert = m_expandedFiles.constFind(inShaderPathKey);
102 const bool found = (theInsert != m_expandedFiles.cend());
104 QByteArray theReadBuffer;
106 const QString defaultDir = getShaderCodeLibraryDirectory();
107 const auto ver = QByteArrayLiteral(
"rhi");
110 QSharedPointer<QIODevice> theStream;
111 QTextStream stream(&fullPath);
112 stream << defaultDir << QLatin1Char(
'/') << ver << QLatin1Char(
'/') << QString::fromLocal8Bit(inShaderPathKey);
113 theStream = QSSGInputUtil::getStreamForFile(fullPath,
true);
114 if (theStream.isNull()) {
116 QTextStream stream(&fullPath);
117 stream << defaultDir << QLatin1Char(
'/') << QString::fromLocal8Bit(inShaderPathKey);
118 theStream = QSSGInputUtil::getStreamForFile(fullPath,
false);
120 if (!theStream.isNull()) {
122 qint64 amountRead = 0;
124 amountRead = theStream->read(readBuf, 1024);
126 theReadBuffer.append(readBuf,
int(amountRead));
127 }
while (amountRead);
129 qCCritical(INVALID_OPERATION,
"Failed to find include file %s", qPrintable(QString::fromLocal8Bit(inShaderPathKey)));
132 theInsert = m_expandedFiles.insert(inShaderPathKey, theReadBuffer);
134 theReadBuffer = theInsert.value();
138 resolveIncludeFiles(theReadBuffer, inShaderPathKey);
140 return theReadBuffer;
143QByteArray QSSGShaderLibraryManager::getShaderSource(
const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type)
145 QReadLocker locker(&m_lock);
147 const QByteArray perStageKey = stageKey(type) + inShaderPathKey;
148 auto it = m_expandedFiles.constFind(perStageKey);
149 if (it != m_expandedFiles.cend())
152 qWarning(
"No shader source stored for key %s", perStageKey.constData());
156QSSGCustomShaderMetaData QSSGShaderLibraryManager::getShaderMetaData(
const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type)
158 QReadLocker locker(&m_lock);
160 const QByteArray perStageKey = stageKey(type) + inShaderPathKey;
161 auto it = m_metadata.constFind(perStageKey);
162 if (it != m_metadata.cend())
165 qWarning(
"No shader metadata stored for key %s", perStageKey.constData());
169void QSSGShaderLibraryManager::loadPregeneratedShaderInfo()
171 const auto collectionFilePath = QString::fromLatin1(QSSGShaderCache::resourceFolder() + QSSGShaderCache::shaderCollectionFile());
172 QFile file(collectionFilePath);
174 QQsbIODeviceCollection qsbc(file);
175 if (qsbc.map(QQsbIODeviceCollection::Read))
176 m_preGeneratedShaderEntries = qsbc.availableEntries();
181bool QSSGShaderLibraryManager::compare(
const QSSGShaderDefaultMaterialKey &key1,
const QSSGShaderDefaultMaterialKey &key2)
183 QSSGShaderDefaultMaterialKeyProperties props;
184#define COMPARE_PROP(x)
185 if (props.x.getValue(key1) < props.x.getValue(key2)) return true;
205 for (
int i = 0; i < QSSGShaderDefaultMaterialKeyProperties::ImageMapCount; i++) {
208 for (
int i = 0; i < QSSGShaderDefaultMaterialKeyProperties::SingleChannelImageCount; i++) {