45void QSSGShaderLibraryManager::setShaderSource(
const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type,
46 const QByteArray &inSource,
const QSSGCustomShaderMetaData &meta)
48 QWriteLocker locker(&m_lock);
50 const QByteArray perStageKey = stageKey(type) + inShaderPathKey;
52 auto it = m_expandedFiles.find(perStageKey);
53 if (it != m_expandedFiles.end())
54 it.value() = inSource;
56 m_expandedFiles.insert(perStageKey, inSource);
60 auto it = m_metadata.find(perStageKey);
61 if (it != m_metadata.end())
64 m_metadata.insert(perStageKey, meta);
68void QSSGShaderLibraryManager::resolveIncludeFiles(QByteArray &theReadBuffer,
const QByteArray &inMaterialInfoString)
71 for (
int thePos = theReadBuffer.indexOf(includeSearch()); thePos != -1;
72 thePos = theReadBuffer.indexOf(includeSearch(), thePos + 1)) {
73 int theEndQuote = theReadBuffer.indexOf(
'\"', thePos + includeSearch().size() + 1);
75 if (theEndQuote == -1) {
76 qCCritical(INVALID_OPERATION,
"Unterminated include in file: %s", inMaterialInfoString.constData());
77 theReadBuffer.clear();
80 const int theActualBegin = thePos + includeSearch().size();
81 const auto &theInclude = theReadBuffer.mid(theActualBegin, theEndQuote - theActualBegin);
83 auto contents = getIncludeContents(theInclude);
85 if (contents.startsWith(copyrightHeaderStart())) {
86 int clipPos = contents.indexOf(copyrightHeaderEnd()) ;
88 contents.remove(0, clipPos + copyrightHeaderEnd().size());
91 contents.prepend(QByteArrayLiteral(
"\n// begin \"") + theInclude + QByteArrayLiteral(
"\"\n"));
93 contents.append(QByteArrayLiteral(
"\n// end \"" ) + theInclude + QByteArrayLiteral(
"\"\n"));
95 theReadBuffer = theReadBuffer.replace(thePos, (theEndQuote + 1) - thePos, contents);
99QByteArray QSSGShaderLibraryManager::getIncludeContents(
const QByteArray &inShaderPathKey)
101 QWriteLocker locker(&m_lock);
103 auto theInsert = m_expandedFiles.constFind(inShaderPathKey);
104 const bool found = (theInsert != m_expandedFiles.cend());
106 QByteArray theReadBuffer;
108 const QString defaultDir = getShaderCodeLibraryDirectory();
109 const auto ver = QByteArrayLiteral(
"rhi");
112 QSharedPointer<QIODevice> theStream;
113 QTextStream stream(&fullPath);
114 stream << defaultDir << QLatin1Char(
'/') << ver << QLatin1Char(
'/') << QString::fromLocal8Bit(inShaderPathKey);
115 theStream = QSSGInputUtil::getStreamForFile(fullPath,
true);
116 if (theStream.isNull()) {
118 QTextStream stream(&fullPath);
119 stream << defaultDir << QLatin1Char(
'/') << QString::fromLocal8Bit(inShaderPathKey);
120 theStream = QSSGInputUtil::getStreamForFile(fullPath,
false);
122 if (!theStream.isNull()) {
124 qint64 amountRead = 0;
126 amountRead = theStream->read(readBuf, 1024);
128 theReadBuffer.append(readBuf,
int(amountRead));
129 }
while (amountRead);
131 qCCritical(INVALID_OPERATION,
"Failed to find include file %s", qPrintable(QString::fromLocal8Bit(inShaderPathKey)));
134 theInsert = m_expandedFiles.insert(inShaderPathKey, theReadBuffer);
136 theReadBuffer = theInsert.value();
140 resolveIncludeFiles(theReadBuffer, inShaderPathKey);
142 return theReadBuffer;
145QByteArray QSSGShaderLibraryManager::getShaderSource(
const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type)
147 QReadLocker locker(&m_lock);
149 const QByteArray perStageKey = stageKey(type) + inShaderPathKey;
150 auto it = m_expandedFiles.constFind(perStageKey);
151 if (it != m_expandedFiles.cend())
154 qWarning(
"No shader source stored for key %s", perStageKey.constData());
158QSSGCustomShaderMetaData QSSGShaderLibraryManager::getShaderMetaData(
const QByteArray &inShaderPathKey, QSSGShaderCache::ShaderType type)
160 QReadLocker locker(&m_lock);
162 const QByteArray perStageKey = stageKey(type) + inShaderPathKey;
163 auto it = m_metadata.constFind(perStageKey);
164 if (it != m_metadata.cend())
167 qWarning(
"No shader metadata stored for key %s", perStageKey.constData());
171void QSSGShaderLibraryManager::loadPregeneratedShaderInfo()
173 const auto collectionFilePath = QString::fromLatin1(QSSGShaderCache::resourceFolder() + QSSGShaderCache::shaderCollectionFile());
174 QFile file(collectionFilePath);
176 QQsbIODeviceCollection qsbc(file);
177 if (qsbc.map(QQsbIODeviceCollection::Read))
178 m_preGeneratedShaderEntries = qsbc.availableEntries();
183QQsbCollection::EntryMap QSSGShaderLibraryManager::getParticleShaderEntries()
const
185 QQsbCollection::EntryMap map;
186 const auto collectionFilePath = QString::fromLatin1(QSSGShaderCache::resourceFolder() + QSSGShaderCache::particleShaderCollectionFile());
187 QFile file(collectionFilePath);
189 QQsbIODeviceCollection qsbc(file);
190 if (qsbc.map(QQsbIODeviceCollection::Read))
191 map = qsbc.availableEntries();
197bool QSSGShaderLibraryManager::compare(
const QSSGShaderDefaultMaterialKey &key1,
const QSSGShaderDefaultMaterialKey &key2)
199 QSSGShaderDefaultMaterialKeyProperties props;
200#define COMPARE_PROP(x)
201 if (props.x.getValue(key1) < props.x.getValue(key2)) return true;
221 for (
int i = 0; i < QSSGShaderDefaultMaterialKeyProperties::ImageMapCount; i++) {
224 for (
int i = 0; i < QSSGShaderDefaultMaterialKeyProperties::SingleChannelImageCount; i++) {