diff options
author | Kaj Grönholm <[email protected]> | 2023-01-03 14:10:04 +0200 |
---|---|---|
committer | Laszlo Agocs <[email protected]> | 2023-01-07 18:24:47 +0100 |
commit | df00f9ea860d2d171d0132e2a49f6bdacc919100 (patch) | |
tree | 45e7aa88b27648f7ed7fb4da1274ac79d596ecfb | |
parent | 90751ff13dcc73b25ef392626c8ae15196250517 (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.cpp | 35 | ||||
-rw-r--r-- | src/gui/rhi/qshader_p.h | 8 | ||||
-rw-r--r-- | src/gui/rhi/qshader_p_p.h | 10 | ||||
-rw-r--r-- | src/gui/rhi/qshaderdescription.cpp | 62 | ||||
-rw-r--r-- | src/gui/rhi/qshaderdescription_p.h | 2 | ||||
-rw-r--r-- | src/gui/rhi/qshaderdescription_p_p.h | 2 | ||||
-rw-r--r-- | tests/auto/gui/rhi/qshader/tst_qshader.cpp | 4 |
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()); |