diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-01-12 17:33:31 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-01-13 16:21:26 +0100 |
commit | 7e2cef0f15b133c07bd11aa5e5065b0b9959fb0d (patch) | |
tree | 50378e10ac4affce1768d40d3fabdf960d9497dc /src/gui/rhi/qshaderdescription.cpp | |
parent | 9a0ab41f28042c7f27208337e419435d16f00006 (diff) |
Move away from CBOR in QShaderDescription serialization
...but keep support for deserializing for all older versions in order to play
nice with existing .qsb files.
The usage of binary JSON and then CBOR is a historical artifact: relying
on the QJsonDocument (which we generate for purposes unrelated to binary
serialization) was a convenient shortcut. However, writing to and
reading from a QDataStream instead (which QShader already does) is trivial.
In order not to be limited by potential CBOR requirements in the future,
take it all into our own hands.
Extend the qshader autotest accordingly.
Task-number: QTBUG-81298
Change-Id: If0047b659bd6601ca47b5bbbce1b719630cde01e
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/gui/rhi/qshaderdescription.cpp')
-rw-r--r-- | src/gui/rhi/qshaderdescription.cpp | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/src/gui/rhi/qshaderdescription.cpp b/src/gui/rhi/qshaderdescription.cpp index 76c5d0ebef..96c8d082fc 100644 --- a/src/gui/rhi/qshaderdescription.cpp +++ b/src/gui/rhi/qshaderdescription.cpp @@ -36,6 +36,7 @@ #include "qshaderdescription_p_p.h" #include <QDebug> +#include <QDataStream> #include <QJsonObject> #include <QJsonArray> #include <QCborValue> @@ -358,6 +359,11 @@ QByteArray QShaderDescription::toJson() const return d->makeDoc().toJson(); } +void QShaderDescription::serialize(QDataStream *stream) const +{ + d->writeToStream(stream); +} + #if QT_CONFIG(binaryjson) && QT_DEPRECATED_SINCE(5, 15) /*! \deprecated @@ -396,6 +402,13 @@ QShaderDescription QShaderDescription::fromCbor(const QByteArray &data) return desc; } +QShaderDescription QShaderDescription::deserialize(QDataStream *stream) +{ + QShaderDescription desc; + QShaderDescriptionPrivate::get(&desc)->loadFromStream(stream); + return desc; +} + /*! \return the list of input variables. This includes vertex inputs (sometimes called attributes) for the vertex stage, and inputs for other stages @@ -867,6 +880,15 @@ static void addDeco(QJsonObject *obj, const QShaderDescription::InOutVariable &v (*obj)[imageFlagsKey] = int(v.imageFlags); } +static void serializeDecorations(QDataStream *stream, const QShaderDescription::InOutVariable &v) +{ + (*stream) << v.location; + (*stream) << v.binding; + (*stream) << v.descriptorSet; + (*stream) << int(v.imageFormat); + (*stream) << int(v.imageFlags); +} + static QJsonObject inOutObject(const QShaderDescription::InOutVariable &v) { QJsonObject obj; @@ -876,6 +898,13 @@ static QJsonObject inOutObject(const QShaderDescription::InOutVariable &v) return obj; } +static void serializeInOutVar(QDataStream *stream, const QShaderDescription::InOutVariable &v) +{ + (*stream) << v.name; + (*stream) << int(v.type); + serializeDecorations(stream, v); +} + static QJsonObject blockMemberObject(const QShaderDescription::BlockVariable &v) { QJsonObject obj; @@ -904,6 +933,23 @@ static QJsonObject blockMemberObject(const QShaderDescription::BlockVariable &v) return obj; } +static void serializeBlockMemberVar(QDataStream *stream, const QShaderDescription::BlockVariable &v) +{ + (*stream) << v.name; + (*stream) << int(v.type); + (*stream) << v.offset; + (*stream) << v.size; + (*stream) << v.arrayDims.count(); + for (int dim : v.arrayDims) + (*stream) << dim; + (*stream) << v.arrayStride; + (*stream) << v.matrixStride; + (*stream) << v.matrixIsRowMajor; + (*stream) << v.structMembers.count(); + for (const QShaderDescription::BlockVariable &sv : v.structMembers) + serializeBlockMemberVar(stream, sv); +} + QJsonDocument QShaderDescriptionPrivate::makeDoc() { QJsonObject root; @@ -1002,6 +1048,67 @@ QJsonDocument QShaderDescriptionPrivate::makeDoc() return QJsonDocument(root); } +void QShaderDescriptionPrivate::writeToStream(QDataStream *stream) +{ + (*stream) << inVars.count(); + for (const QShaderDescription::InOutVariable &v : qAsConst(inVars)) + serializeInOutVar(stream, v); + + (*stream) << outVars.count(); + for (const QShaderDescription::InOutVariable &v : qAsConst(outVars)) + serializeInOutVar(stream, v); + + (*stream) << uniformBlocks.count(); + for (const QShaderDescription::UniformBlock &b : uniformBlocks) { + (*stream) << b.blockName; + (*stream) << b.structName; + (*stream) << b.size; + (*stream) << b.binding; + (*stream) << b.descriptorSet; + (*stream) << b.members.count(); + for (const QShaderDescription::BlockVariable &v : b.members) + serializeBlockMemberVar(stream, v); + } + + (*stream) << pushConstantBlocks.count(); + for (const QShaderDescription::PushConstantBlock &b : pushConstantBlocks) { + (*stream) << b.name; + (*stream) << b.size; + (*stream) << b.members.count(); + for (const QShaderDescription::BlockVariable &v : b.members) + serializeBlockMemberVar(stream, v); + } + + (*stream) << storageBlocks.count(); + for (const QShaderDescription::StorageBlock &b : storageBlocks) { + (*stream) << b.blockName; + (*stream) << b.instanceName; + (*stream) << b.knownSize; + (*stream) << b.binding; + (*stream) << b.descriptorSet; + (*stream) << b.members.count(); + for (const QShaderDescription::BlockVariable &v : b.members) + serializeBlockMemberVar(stream, v); + } + + (*stream) << combinedImageSamplers.count(); + for (const QShaderDescription::InOutVariable &v : qAsConst(combinedImageSamplers)) { + (*stream) << v.name; + (*stream) << int(v.type); + serializeDecorations(stream, v); + } + + (*stream) << storageImages.count(); + for (const QShaderDescription::InOutVariable &v : qAsConst(storageImages)) { + (*stream) << v.name; + (*stream) << int(v.type); + serializeDecorations(stream, v); + } + + for (size_t i = 0; i < 3; ++i) + (*stream) << localSize[i]; +} + static QShaderDescription::InOutVariable inOutVar(const QJsonObject &obj) { QShaderDescription::InOutVariable var; @@ -1020,6 +1127,29 @@ static QShaderDescription::InOutVariable inOutVar(const QJsonObject &obj) return var; } +static void deserializeDecorations(QDataStream *stream, QShaderDescription::InOutVariable *v) +{ + (*stream) >> v->location; + (*stream) >> v->binding; + (*stream) >> v->descriptorSet; + int f; + (*stream) >> f; + v->imageFormat = QShaderDescription::ImageFormat(f); + (*stream) >> f; + v->imageFlags = QShaderDescription::ImageFlags(f); +} + +static QShaderDescription::InOutVariable deserializeInOutVar(QDataStream *stream) +{ + QShaderDescription::InOutVariable var; + (*stream) >> var.name; + int t; + (*stream) >> t; + var.type = QShaderDescription::VariableType(t); + deserializeDecorations(stream, &var); + return var; +} + static QShaderDescription::BlockVariable blockVar(const QJsonObject &obj) { QShaderDescription::BlockVariable var; @@ -1046,6 +1176,30 @@ static QShaderDescription::BlockVariable blockVar(const QJsonObject &obj) return var; } +static QShaderDescription::BlockVariable deserializeBlockMemberVar(QDataStream *stream) +{ + QShaderDescription::BlockVariable var; + (*stream) >> var.name; + int t; + (*stream) >> t; + var.type = QShaderDescription::VariableType(t); + (*stream) >> var.offset; + (*stream) >> var.size; + int count; + (*stream) >> count; + var.arrayDims.resize(count); + for (int i = 0; i < count; ++i) + (*stream) >> var.arrayDims[i]; + (*stream) >> var.arrayStride; + (*stream) >> var.matrixStride; + (*stream) >> var.matrixIsRowMajor; + (*stream) >> count; + var.structMembers.resize(count); + for (int i = 0; i < count; ++i) + var.structMembers[i] = deserializeBlockMemberVar(stream); + return var; +} + void QShaderDescriptionPrivate::loadDoc(const QJsonDocument &doc) { if (doc.isNull()) { @@ -1150,6 +1304,87 @@ void QShaderDescriptionPrivate::loadDoc(const QJsonDocument &doc) } } +void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream) +{ + Q_ASSERT(ref.loadRelaxed() == 1); // must be detached + + int count; + (*stream) >> count; + inVars.resize(count); + for (int i = 0; i < count; ++i) + inVars[i] = deserializeInOutVar(stream); + + (*stream) >> count; + outVars.resize(count); + for (int i = 0; i < count; ++i) + outVars[i] = deserializeInOutVar(stream); + + (*stream) >> count; + uniformBlocks.resize(count); + for (int i = 0; i < count; ++i) { + (*stream) >> uniformBlocks[i].blockName; + (*stream) >> uniformBlocks[i].structName; + (*stream) >> uniformBlocks[i].size; + (*stream) >> uniformBlocks[i].binding; + (*stream) >> uniformBlocks[i].descriptorSet; + int memberCount; + (*stream) >> memberCount; + uniformBlocks[i].members.resize(memberCount); + for (int memberIdx = 0; memberIdx < memberCount; ++memberIdx) + uniformBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream); + } + + (*stream) >> count; + pushConstantBlocks.resize(count); + for (int i = 0; i < count; ++i) { + (*stream) >> pushConstantBlocks[i].name; + (*stream) >> pushConstantBlocks[i].size; + int memberCount; + (*stream) >> memberCount; + pushConstantBlocks[i].members.resize(memberCount); + for (int memberIdx = 0; memberIdx < memberCount; ++memberIdx) + pushConstantBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream); + } + + (*stream) >> count; + storageBlocks.resize(count); + for (int i = 0; i < count; ++i) { + (*stream) >> storageBlocks[i].blockName; + (*stream) >> storageBlocks[i].instanceName; + (*stream) >> storageBlocks[i].knownSize; + (*stream) >> storageBlocks[i].binding; + (*stream) >> storageBlocks[i].descriptorSet; + int memberCount; + (*stream) >> memberCount; + storageBlocks[i].members.resize(memberCount); + for (int memberIdx = 0; memberIdx < memberCount; ++memberIdx) + storageBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream); + } + + (*stream) >> count; + combinedImageSamplers.resize(count); + for (int i = 0; i < count; ++i) { + (*stream) >> combinedImageSamplers[i].name; + int t; + (*stream) >> t; + combinedImageSamplers[i].type = QShaderDescription::VariableType(t); + deserializeDecorations(stream, &combinedImageSamplers[i]); + } + + (*stream) >> count; + storageImages.resize(count); + for (int i = 0; i < count; ++i) { + (*stream) >> storageImages[i].name; + int t; + (*stream) >> t; + storageImages[i].type = QShaderDescription::VariableType(t); + deserializeDecorations(stream, &storageImages[i]); + } + + for (size_t i = 0; i < 3; ++i) + (*stream) >> localSize[i]; +} + /*! Returns \c true if the two QShaderDescription objects \a lhs and \a rhs are equal. |