9#include <QtQuick3DUtils/private/qssgutils_p.h>
10#include <QtQuick3DUtils/private/qquick3dprofiler_p.h>
12#include <QtQuick3DRuntimeRender/private/qssgruntimerenderlogging_p.h>
13#include <qtquick3d_tracepoints_p.h>
15#include <QCoreApplication>
16#include <QStandardPaths>
21#include <QtGui/qsurfaceformat.h>
23# include <QtGui/qopenglcontext.h>
26#ifdef QT_QUICK3D_HAS_RUNTIME_SHADERS
27#include <rhi/qshaderbaker.h>
30#include <QtCore/qmutex.h>
58 const char *
name =
nullptr;
94#ifdef QT_QUICK3D_HAS_RUNTIME_SHADERS
117 bool isGLESModule =
false;
122 if (
format.majorVersion() >= 3)
154 baker->setGeneratedShaders(outputs);
183 baker->setBreakOnShaderTranslationError(
false);
185 baker->setGeneratedShaders(outputs);
219 static bool checked =
false;
220 static QString currentCacheDir;
221 static bool cacheWritable =
false;
224 return cacheWritable ? currentCacheDir :
QString();
231 currentCacheDir = cachePath +
subPath;
235 return cacheWritable ? currentCacheDir :
QString();
250 m_initBaker(initBakeFn)
255 if (!m_persistentShaderStorageFileName.
isEmpty()) {
259 qDebug(
"Attempting to seed material shader cache from %s",
qPrintable(m_persistentShaderStorageFileName));
260 if (m_persistentShaderBakingCache.
load(m_persistentShaderStorageFileName)) {
263 qDebug(
"Loaded %d shader pipelines into the material shader cache",
count);
285 if (!m_persistentShaderStorageFileName.
isEmpty())
286 m_persistentShaderBakingCache.
save(m_persistentShaderStorageFileName);
291 m_rhiShaders.
clear();
303 const auto theIter = m_rhiShaders.
constFind(cacheKey);
304 if (theIter != m_rhiShaders.
cend())
305 return theIter.value();
312 ShaderType shaderType,
317 m_insertStr +=
"#version 440\n";
320 m_insertStr +=
"//Shader name -";
321 m_insertStr += inKey;
325 m_insertStr +=
"#define texture2D texture\n";
333 m_insertStr.
append(
"#define ");
334 m_insertStr.
append(def.name);
336 m_insertStr.
append(inFeatures.
isSet(def.feature) ?
"1" :
"0");
341 insertPos += int(m_insertStr.
size());
344 if (fragOutputEnabled)
345 m_insertStr +=
"layout(location = 0) out vec4 fragOutput;\n";
363#ifdef QT_QUICK3D_HAS_RUNTIME_SHADERS
387 m_initBaker(&baker, m_rhiContext.
rhi());
396 qDebug(
"VERTEX SHADER:\n*****\n");
399 qDebug(
"FRAGMENT SHADER:\n*****\n");
402 qDebug(
"SHADER:\n*****\n");
405 const auto lines = code.
split(
'\n');
406 for (
int i = 0;
i < lines.size();
i++)
407 qDebug(
"%3d %s",
i + 1, lines.at(
i).constData());
419 QShader vertexShader = baker.bake();
420 const auto vertShaderValid = vertexShader.
isValid();
421 if (!vertShaderValid) {
422 vertErr = baker.errorMessage();
424 qWarning(
"Failed to compile vertex shader:\n");
426 qWarning() << inKey <<
'\n' << vertErr;
432 if (!vertShaderValid)
437 QShader fragmentShader = baker.bake();
438 const bool fragShaderValid = fragmentShader.
isValid();
439 if (!fragShaderValid) {
440 fragErr = baker.errorMessage();
442 qWarning(
"Failed to compile fragment shader \n");
444 qWarning() << inKey <<
'\n' << fragErr;
450 if (!fragShaderValid)
454 if (vertShaderValid && fragShaderValid) {
455 shaders = std::make_shared<QSSGRhiShaderPipeline>(m_rhiContext);
459 qDebug(
"Compilation for vertex and fragment stages succeeded");
464 const auto vertStatus = vertShaderValid ? Status::Success : Status::Error;
465 const auto fragStatus = fragShaderValid ? Status::Success : Status::Error;
476 result->vertexStage()->shader(),
477 result->fragmentStage()->shader()
489 qWarning(
"Cannot compile and condition shaders at runtime because this build of Qt Quick 3D is not linking to Qt Shader Tools. "
490 "Only pre-processed materials are supported.");
499 QSSGRhiShaderPipeline::StageFlags stageFlags)
510 qDebug(
"Loading pregenerated rhi shader(s)");
531 qDebug(
"Loading of vertex and fragment stages succeeded");
540 const auto inserted = m_rhiShaders.
insert(cacheKey,
shaders);
542 return inserted.value();
548 QSSGRhiShaderPipeline::StageFlags stageFlags)
608 f.setFileName(vertexFileName);
616 f.setFileName(fragmentFileName);
629 qDebug(
"Loading of vertex and fragment stages succeeded");
638 const auto inserted = m_rhiShaders.
insert(cacheKey,
shaders);
639 return inserted.value();
656 return ::isAutoDiskCacheEnabled();
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
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...
bool isNull() const noexcept
Returns true if this byte array is null; otherwise returns false.
static QDir root()
Returns the root directory.
bool mkpath(const QString &dirPath) const
Creates the directory path dirPath.
\inmodule QtCore \reentrant
bool isWritable() const
Returns true if the user can write to the file; otherwise returns false.
bool exists() const
Returns true if the file exists; otherwise returns false.
const_iterator constFind(const Key &key) const noexcept
const_iterator cend() const noexcept
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
void reserve(qsizetype size)
void append(parameter_type t)
static OpenGLModuleType openGLModuleType()
Returns the underlying OpenGL implementation type.
static FeatureSet toFeatureSet(const T &ssgFeatureSet)
bool extractEntry(Entry entry, EntryDesc &entryDesc) override
Entry addEntry(const QByteArray &key, const EntryDesc &entryDesc) override
bool load(const QString &filename)
bool save(const QString &filename)
EntryMap availableEntries() const override
bool extractEntry(Entry entry, EntryDesc &entryDesc) override
\variable QRhiGles2InitParams::format
Implementation backend() const
const QRhiNativeHandles * nativeHandles()
static bool shaderDebuggingEnabled()
QSSGRhiShaderPipelinePtr tryGetRhiShaderPipeline(const QByteArray &inKey, const QSSGShaderFeatures &inFeatures)
QSSGShaderCache(QSSGRhiContext &ctx, const InitBakerFunc initBakeFn=nullptr)
static QByteArray shaderCollectionFile()
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)
void releaseCachedResources()
QSSGRhiShaderPipelinePtr loadBuiltinForRhi(const QByteArray &inKey)
QSSGRhiShaderPipelinePtr tryNewPipelineFromPersistentCache(const QByteArray &qsbcKey, const QByteArray &inKey, const QSSGShaderFeatures &inFeatures, QSSGRhiShaderPipeline::StageFlags stageFlags={})
void(*)(QShaderBaker *baker, QRhi *rhi) InitBakerFunc
static QShader fromSerialized(const QByteArray &data)
Creates a new QShader instance from the given data.
Stage
Describes the stage of the graphics pipeline the shader is suitable for.
static QString writableLocation(StandardLocation type)
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the string into substrings wherever sep occurs, and returns the list of those strings.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
QString & insert(qsizetype i, QChar c)
static QString buildAbi()
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()
@ AA_DisableShaderDiskCache
#define QByteArrayLiteral(str)
static const QPainterPath::ElementType * subPath(const QPainterPath::ElementType *t, const QPainterPath::ElementType *end, const qreal *points, bool *closed)
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLsizei GLsizei GLenum format
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLsizei GLuint * shaders
constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
#define Q_QUICK3D_PROFILE_START(Type)
#define Q_QUICK3D_PROFILE_END_WITH_ID(Type, Payload, POID)
#define Q_QUICK3D_PROFILE_END_WITH_STRING(Type, Payload, Str)
static QString persistentQsbcFileName()
static bool isAutoDiskCacheEnabled()
size_t qHash(QSSGShaderFeatures features) noexcept
static bool ensureWritableDir(const QString &name)
static constexpr DefineEntry DefineTable[]
static bool s_autoDiskCacheEnabled
static QString dumpFilename(QShader::Stage stage)
static void initBakerForPersistentUse(QShaderBaker *, QRhi *)
static QT_BEGIN_NAMESPACE QtQuick3DEditorHelpers::ShaderBaker::StatusCallback s_statusCallback
static QString persistentQsbcDir()
static void initBakerForNonPersistentUse(QShaderBaker *, QRhi *)
std::shared_ptr< QSSGRhiShaderPipeline > QSSGRhiShaderPipelinePtr
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define qPrintable(string)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
#define Q_TRACE_SCOPE(x,...)
#define Q_TRACE_POINT(provider, tracepoint,...)
QSSGShaderFeatures::Feature feature
\inmodule QtCore \reentrant
QByteArray generateSha() const
QSSGShaderFeatures m_features
constexpr bool isSet(Feature feature) const
static constexpr FlagType IndexMask
void set(Feature feature, bool val)
static constexpr quint32 Count
static const char * asDefineString(QSSGShaderFeatures::Feature feature)
static Feature fromIndex(quint32 idx)