summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaj Grönholm <[email protected]>2023-01-03 14:10:04 +0200
committerLaszlo Agocs <[email protected]>2023-01-07 18:24:47 +0100
commitdf00f9ea860d2d171d0132e2a49f6bdacc919100 (patch)
tree45e7aa88b27648f7ed7fb4da1274ac79d596ecfb
parent90751ff13dcc73b25ef392626c8ae15196250517 (diff)
Support serializing the QShader for qsb version
Support serializing shaders with specific qsb version. The default behavior remains the same, using the latest version. Task-number: QTBUG-101062 Pick-to: 6.5 Change-Id: I090a88c1ccb3be4ac5eee1da4058afaa8bf3111c Reviewed-by: Laszlo Agocs <[email protected]>
-rw-r--r--src/gui/rhi/qshader.cpp35
-rw-r--r--src/gui/rhi/qshader_p.h8
-rw-r--r--src/gui/rhi/qshader_p_p.h10
-rw-r--r--src/gui/rhi/qshaderdescription.cpp62
-rw-r--r--src/gui/rhi/qshaderdescription_p.h2
-rw-r--r--src/gui/rhi/qshaderdescription_p_p.h2
-rw-r--r--tests/auto/gui/rhi/qshader/tst_qshader.cpp4
7 files changed, 76 insertions, 47 deletions
diff --git a/src/gui/rhi/qshader.cpp b/src/gui/rhi/qshader.cpp
index 440e7fedc8e..c35445f7b89 100644
--- a/src/gui/rhi/qshader.cpp
+++ b/src/gui/rhi/qshader.cpp
@@ -365,9 +365,12 @@ static void writeShaderKey(QDataStream *ds, const QShaderKey &k)
\return a serialized binary version of all the data held by the
QShader, suitable for writing to files or other I/O devices.
+ By default the latest serialization format is used. Use \a version
+ parameter to serialize for a compatibility Qt version.
+
\sa fromSerialized()
*/
-QByteArray QShader::serialized() const
+QByteArray QShader::serialized(SerializedFormatVersion version) const
{
static QShaderPrivate sd;
QShaderPrivate *dd = d ? d : &sd;
@@ -378,9 +381,11 @@ QByteArray QShader::serialized() const
if (!buf.open(QIODevice::WriteOnly))
return QByteArray();
- ds << QShaderPrivate::QSB_VERSION;
+ const int qsbVersion = QShaderPrivate::qtQsbVersion(version);
+ ds << qsbVersion;
+
ds << int(dd->stage);
- dd->desc.serialize(&ds);
+ dd->desc.serialize(&ds, qsbVersion);
ds << int(dd->shaders.size());
for (auto it = dd->shaders.cbegin(), itEnd = dd->shaders.cend(); it != itEnd; ++it) {
const QShaderKey &k(it.key());
@@ -413,17 +418,19 @@ QByteArray QShader::serialized() const
ds << listIt->samplerBinding;
}
}
- ds << int(dd->nativeShaderInfoMap.size());
- for (auto it = dd->nativeShaderInfoMap.cbegin(), itEnd = dd->nativeShaderInfoMap.cend(); it != itEnd; ++it) {
- const QShaderKey &k(it.key());
- writeShaderKey(&ds, k);
- ds << it->flags;
- ds << int(it->extraBufferBindings.size());
- for (auto mapIt = it->extraBufferBindings.cbegin(), mapItEnd = it->extraBufferBindings.cend();
- mapIt != mapItEnd; ++mapIt)
- {
- ds << mapIt.key();
- ds << mapIt.value();
+ if (qsbVersion > QShaderPrivate::QSB_VERSION_WITHOUT_NATIVE_SHADER_INFO) {
+ ds << int(dd->nativeShaderInfoMap.size());
+ for (auto it = dd->nativeShaderInfoMap.cbegin(), itEnd = dd->nativeShaderInfoMap.cend(); it != itEnd; ++it) {
+ const QShaderKey &k(it.key());
+ writeShaderKey(&ds, k);
+ ds << it->flags;
+ ds << int(it->extraBufferBindings.size());
+ for (auto mapIt = it->extraBufferBindings.cbegin(), mapItEnd = it->extraBufferBindings.cend();
+ mapIt != mapItEnd; ++mapIt)
+ {
+ ds << mapIt.key();
+ ds << mapIt.value();
+ }
}
}
diff --git a/src/gui/rhi/qshader_p.h b/src/gui/rhi/qshader_p.h
index 33c026f7796..f85b075a83b 100644
--- a/src/gui/rhi/qshader_p.h
+++ b/src/gui/rhi/qshader_p.h
@@ -110,6 +110,12 @@ public:
NonIndexedVertexAsComputeShader
};
+ enum class SerializedFormatVersion {
+ Latest = 0,
+ Qt_6_5,
+ Qt_6_4
+ };
+
QShader();
QShader(const QShader &other);
QShader &operator=(const QShader &other);
@@ -129,7 +135,7 @@ public:
void setShader(const QShaderKey &key, const QShaderCode &shader);
void removeShader(const QShaderKey &key);
- QByteArray serialized() const;
+ QByteArray serialized(SerializedFormatVersion version = SerializedFormatVersion::Latest) const;
static QShader fromSerialized(const QByteArray &data);
using NativeResourceBindingMap = QMap<int, QPair<int, int> >; // binding -> native_binding[, native_binding]
diff --git a/src/gui/rhi/qshader_p_p.h b/src/gui/rhi/qshader_p_p.h
index b0ba04ef513..58fb2072c92 100644
--- a/src/gui/rhi/qshader_p_p.h
+++ b/src/gui/rhi/qshader_p_p.h
@@ -61,6 +61,16 @@ struct Q_GUI_EXPORT QShaderPrivate
static QShaderPrivate *get(QShader *s) { return s->d; }
static const QShaderPrivate *get(const QShader *s) { return s->d; }
+ static int qtQsbVersion(QShader::SerializedFormatVersion qtVersion) {
+ switch (qtVersion) {
+ case QShader::SerializedFormatVersion::Qt_6_4:
+ return (QShaderPrivate::QSB_VERSION_WITHOUT_SEPARATE_IMAGES_AND_SAMPLERS + 1);
+ case QShader::SerializedFormatVersion::Qt_6_5:
+ return (QShaderPrivate::QSB_VERSION_WITHOUT_EXTENDED_STORAGE_BUFFER_INFO + 1);
+ default:
+ return QShaderPrivate::QSB_VERSION;
+ }
+ }
QAtomicInt ref;
int qsbVersion = QSB_VERSION;
diff --git a/src/gui/rhi/qshaderdescription.cpp b/src/gui/rhi/qshaderdescription.cpp
index 443900240a2..ca697d8edb0 100644
--- a/src/gui/rhi/qshaderdescription.cpp
+++ b/src/gui/rhi/qshaderdescription.cpp
@@ -319,13 +319,14 @@ QByteArray QShaderDescription::toJson() const
}
/*!
- Serializes this QShaderDescription to \a stream.
+ Serializes this QShaderDescription to \a stream. \a version specifies
+ the qsb version.
\sa deserialize(), toJson()
*/
-void QShaderDescription::serialize(QDataStream *stream) const
+void QShaderDescription::serialize(QDataStream *stream, int version) const
{
- d->writeToStream(stream);
+ d->writeToStream(stream, version);
}
/*!
@@ -1067,7 +1068,7 @@ static void addDeco(QJsonObject *obj, const QShaderDescription::InOutVariable &v
}
}
-static void serializeDecorations(QDataStream *stream, const QShaderDescription::InOutVariable &v)
+static void serializeDecorations(QDataStream *stream, const QShaderDescription::InOutVariable &v, int version)
{
(*stream) << v.location;
(*stream) << v.binding;
@@ -1077,7 +1078,8 @@ static void serializeDecorations(QDataStream *stream, const QShaderDescription::
(*stream) << int(v.arrayDims.size());
for (int dim : v.arrayDims)
(*stream) << dim;
- (*stream) << quint8(v.perPatch);
+ if (version > QShaderPrivate::QSB_VERSION_WITHOUT_NATIVE_SHADER_INFO)
+ (*stream) << quint8(v.perPatch);
}
static QJsonObject inOutObject(const QShaderDescription::InOutVariable &v)
@@ -1089,11 +1091,11 @@ static QJsonObject inOutObject(const QShaderDescription::InOutVariable &v)
return obj;
}
-static void serializeInOutVar(QDataStream *stream, const QShaderDescription::InOutVariable &v)
+static void serializeInOutVar(QDataStream *stream, const QShaderDescription::InOutVariable &v, int version)
{
(*stream) << QString::fromUtf8(v.name);
(*stream) << int(v.type);
- serializeDecorations(stream, v);
+ serializeDecorations(stream, v, version);
}
static QJsonObject blockMemberObject(const QShaderDescription::BlockVariable &v)
@@ -1297,15 +1299,15 @@ QJsonDocument QShaderDescriptionPrivate::makeDoc()
return QJsonDocument(root);
}
-void QShaderDescriptionPrivate::writeToStream(QDataStream *stream)
+void QShaderDescriptionPrivate::writeToStream(QDataStream *stream, int version)
{
(*stream) << int(inVars.size());
for (const QShaderDescription::InOutVariable &v : std::as_const(inVars))
- serializeInOutVar(stream, v);
+ serializeInOutVar(stream, v, version);
(*stream) << int(outVars.size());
for (const QShaderDescription::InOutVariable &v : std::as_const(outVars))
- serializeInOutVar(stream, v);
+ serializeInOutVar(stream, v, version);
(*stream) << int(uniformBlocks.size());
for (const QShaderDescription::UniformBlock &b : uniformBlocks) {
@@ -1338,22 +1340,24 @@ void QShaderDescriptionPrivate::writeToStream(QDataStream *stream)
(*stream) << int(b.members.size());
for (const QShaderDescription::BlockVariable &v : b.members)
serializeBlockMemberVar(stream, v);
- (*stream) << b.runtimeArrayStride;
- (*stream) << b.qualifierFlags;
+ if (version > QShaderPrivate::QSB_VERSION_WITHOUT_EXTENDED_STORAGE_BUFFER_INFO) {
+ (*stream) << b.runtimeArrayStride;
+ (*stream) << b.qualifierFlags;
+ }
}
(*stream) << int(combinedImageSamplers.size());
for (const QShaderDescription::InOutVariable &v : std::as_const(combinedImageSamplers)) {
(*stream) << QString::fromUtf8(v.name);
(*stream) << int(v.type);
- serializeDecorations(stream, v);
+ serializeDecorations(stream, v, version);
}
(*stream) << int(storageImages.size());
for (const QShaderDescription::InOutVariable &v : std::as_const(storageImages)) {
(*stream) << QString::fromUtf8(v.name);
(*stream) << int(v.type);
- serializeDecorations(stream, v);
+ serializeDecorations(stream, v, version);
}
for (size_t i = 0; i < 3; ++i)
@@ -1363,28 +1367,30 @@ void QShaderDescriptionPrivate::writeToStream(QDataStream *stream)
for (const QShaderDescription::InOutVariable &v : std::as_const(separateImages)) {
(*stream) << QString::fromUtf8(v.name);
(*stream) << int(v.type);
- serializeDecorations(stream, v);
+ serializeDecorations(stream, v, version);
}
(*stream) << int(separateSamplers.size());
for (const QShaderDescription::InOutVariable &v : std::as_const(separateSamplers)) {
(*stream) << QString::fromUtf8(v.name);
(*stream) << int(v.type);
- serializeDecorations(stream, v);
+ serializeDecorations(stream, v, version);
}
- (*stream) << quint32(tessOutVertCount);
- (*stream) << quint32(tessMode);
- (*stream) << quint32(tessWind);
- (*stream) << quint32(tessPart);
-
- (*stream) << int(inBuiltins.size());
- for (const QShaderDescription::BuiltinVariable &v : std::as_const(inBuiltins))
- (*stream) << int(v.type);
-
- (*stream) << int(outBuiltins.size());
- for (const QShaderDescription::BuiltinVariable &v : std::as_const(outBuiltins))
- (*stream) << int(v.type);
+ if (version > QShaderPrivate::QSB_VERSION_WITHOUT_NATIVE_SHADER_INFO) {
+ (*stream) << quint32(tessOutVertCount);
+ (*stream) << quint32(tessMode);
+ (*stream) << quint32(tessWind);
+ (*stream) << quint32(tessPart);
+
+ (*stream) << int(inBuiltins.size());
+ for (const QShaderDescription::BuiltinVariable &v : std::as_const(inBuiltins))
+ (*stream) << int(v.type);
+
+ (*stream) << int(outBuiltins.size());
+ for (const QShaderDescription::BuiltinVariable &v : std::as_const(outBuiltins))
+ (*stream) << int(v.type);
+ }
}
static void deserializeDecorations(QDataStream *stream, int version, QShaderDescription::InOutVariable *v)
diff --git a/src/gui/rhi/qshaderdescription_p.h b/src/gui/rhi/qshaderdescription_p.h
index 7e5412a784e..13e72ad134d 100644
--- a/src/gui/rhi/qshaderdescription_p.h
+++ b/src/gui/rhi/qshaderdescription_p.h
@@ -37,7 +37,7 @@ public:
bool isValid() const;
- void serialize(QDataStream *stream) const;
+ void serialize(QDataStream *stream, int version) const;
QByteArray toJson() const;
static QShaderDescription deserialize(QDataStream *stream, int version);
diff --git a/src/gui/rhi/qshaderdescription_p_p.h b/src/gui/rhi/qshaderdescription_p_p.h
index 1ccb7a14ed4..c22ddda8ada 100644
--- a/src/gui/rhi/qshaderdescription_p_p.h
+++ b/src/gui/rhi/qshaderdescription_p_p.h
@@ -54,7 +54,7 @@ struct Q_GUI_EXPORT QShaderDescriptionPrivate
static const QShaderDescriptionPrivate *get(const QShaderDescription *desc) { return desc->d; }
QJsonDocument makeDoc();
- void writeToStream(QDataStream *stream);
+ void writeToStream(QDataStream *stream, int version);
void loadFromStream(QDataStream *stream, int version);
QAtomicInt ref;
diff --git a/tests/auto/gui/rhi/qshader/tst_qshader.cpp b/tests/auto/gui/rhi/qshader/tst_qshader.cpp
index 52de60ce550..425b5951d01 100644
--- a/tests/auto/gui/rhi/qshader/tst_qshader.cpp
+++ b/tests/auto/gui/rhi/qshader/tst_qshader.cpp
@@ -294,7 +294,7 @@ void tst_QShader::serializeShaderDesc()
QBuffer buf(&data);
QDataStream ds(&buf);
QVERIFY(buf.open(QIODevice::WriteOnly));
- desc.serialize(&ds);
+ desc.serialize(&ds, QShaderPrivate::QSB_VERSION);
}
QVERIFY(!data.isEmpty());
@@ -319,7 +319,7 @@ void tst_QShader::serializeShaderDesc()
QBuffer buf(&data);
QDataStream ds(&buf);
QVERIFY(buf.open(QIODevice::WriteOnly));
- desc.serialize(&ds);
+ desc.serialize(&ds, QShaderPrivate::QSB_VERSION);
}
QVERIFY(!data.isEmpty());