Remove old CBOR-based format from QShader

We only support version 4 and 5 in Qt 6.0. 1 and 2 are already gone
(due to being based on binary JSON), now we remove 3 as well.

Task-number: QTBUG-81346
Change-Id: I3627dcc0587f1e36f11e93edf7172889e911d64e
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
This commit is contained in:
Laszlo Agocs 2020-08-10 16:12:02 +02:00
parent fed97b9264
commit a99cee1c7b
6 changed files with 19 additions and 293 deletions

View File

@ -442,9 +442,8 @@ QShader QShader::fromSerialized(const QByteArray &data)
if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITH_CBOR) { if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITH_CBOR) {
d->desc = QShaderDescription::deserialize(&ds, d->qsbVersion); d->desc = QShaderDescription::deserialize(&ds, d->qsbVersion);
} else if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITH_BINARY_JSON) { } else if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITH_BINARY_JSON) {
QByteArray descBin; qWarning("Can no longer load QShaderDescription from CBOR.");
ds >> descBin; d->desc = QShaderDescription();
d->desc = QShaderDescription::fromCbor(descBin);
} else { } else {
qWarning("Can no longer load QShaderDescription from binary JSON."); qWarning("Can no longer load QShaderDescription from binary JSON.");
d->desc = QShaderDescription(); d->desc = QShaderDescription();

View File

@ -40,9 +40,6 @@
#include <QDataStream> #include <QDataStream>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonArray> #include <QJsonArray>
#include <QCborValue>
#include <QCborMap>
#include <QCborArray>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -103,12 +100,13 @@ QT_BEGIN_NAMESPACE
of 68 bytes and two members, a 4x4 matrix named \c mvp at offset 0, and a of 68 bytes and two members, a 4x4 matrix named \c mvp at offset 0, and a
float \c opacity at offset 64. float \c opacity at offset 64.
All this is described by a QShaderDescription object. QShaderDescription All this is described by a QShaderDescription object. QShaderDescription can
can also be serialized to JSON and CBOR, and can be deserialized be serialized to JSON and to a binary format via QDataStream, and can be
from CBOR. In practice this is rarely needed since QShader deserialized from this binary format. In practice this is rarely needed
takes care of the associated QShaderDescription automatically, but if the since QShader takes care of the associated QShaderDescription automatically,
QShaderDescription of the above shader would be written out as JSON, it but if the QShaderDescription of the above shader would be written out as
would look like the following: JSON (like it is done by the \c qsb tool's \c{-d} option), it would look
like the following:
\badcode \badcode
{ {
@ -337,54 +335,34 @@ bool QShaderDescription::isValid() const
|| !d->combinedImageSamplers.isEmpty() || !d->storageImages.isEmpty(); || !d->combinedImageSamplers.isEmpty() || !d->storageImages.isEmpty();
} }
#if QT_CONFIG(cborstreamwriter)
/*!
\return a serialized binary version of the data in CBOR (Concise Binary
Object Representation) format.
\sa QCborValue, toJson()
*/
QByteArray QShaderDescription::toCbor() const
{
return QCborValue::fromJsonValue(d->makeDoc().object()).toCbor();
}
#endif
/*! /*!
\return a serialized JSON text version of the data. \return a serialized JSON text version of the data.
\note There is no deserialization method provided for JSON text. \note There is no deserialization method provided for JSON text.
\sa toCbor() \sa serialize()
*/ */
QByteArray QShaderDescription::toJson() const QByteArray QShaderDescription::toJson() const
{ {
return d->makeDoc().toJson(); return d->makeDoc().toJson();
} }
/*!
Serializes this QShaderDescription to \a stream.
\sa deserialize(), toJson()
*/
void QShaderDescription::serialize(QDataStream *stream) const void QShaderDescription::serialize(QDataStream *stream) const
{ {
d->writeToStream(stream); d->writeToStream(stream);
} }
/*! /*!
Deserializes the given CBOR \a data and returns a new QShaderDescription. \return a new QShaderDescription loaded from \a stream. \a version specifies
*/ the qsb version.
QShaderDescription QShaderDescription::fromCbor(const QByteArray &data)
{
QShaderDescription desc;
const QCborValue cbor = QCborValue::fromCbor(data);
if (cbor.isMap()) {
const QJsonDocument doc(cbor.toMap().toJsonObject());
QShaderDescriptionPrivate::get(&desc)->loadDoc(doc);
}
if (cbor.isArray()) {
const QJsonDocument doc(cbor.toArray().toJsonArray());
QShaderDescriptionPrivate::get(&desc)->loadDoc(doc);
}
return desc;
}
\sa serialize()
*/
QShaderDescription QShaderDescription::deserialize(QDataStream *stream, int version) QShaderDescription QShaderDescription::deserialize(QDataStream *stream, int version)
{ {
QShaderDescription desc; QShaderDescription desc;
@ -656,15 +634,6 @@ static QString typeStr(const QShaderDescription::VariableType &t)
return QString(); return QString();
} }
static QShaderDescription::VariableType mapType(const QString &t)
{
for (size_t i = 0; i < sizeof(typeTab) / sizeof(TypeTab); ++i) {
if (typeTab[i].k == t)
return typeTab[i].v;
}
return QShaderDescription::Unknown;
}
static struct ImageFormatTab { static struct ImageFormatTab {
QString k; QString k;
QShaderDescription::ImageFormat v; QShaderDescription::ImageFormat v;
@ -720,15 +689,6 @@ static QString imageFormatStr(const QShaderDescription::ImageFormat &f)
return QString(); return QString();
} }
static QShaderDescription::ImageFormat mapImageFormat(const QString &f)
{
for (size_t i = 0; i < sizeof(imageFormatTab) / sizeof(ImageFormatTab); ++i) {
if (imageFormatTab[i].k == f)
return imageFormatTab[i].v;
}
return QShaderDescription::ImageFormatUnknown;
}
#ifndef QT_NO_DEBUG_STREAM #ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const QShaderDescription &sd) QDebug operator<<(QDebug dbg, const QShaderDescription &sd)
{ {
@ -1106,29 +1066,6 @@ void QShaderDescriptionPrivate::writeToStream(QDataStream *stream)
(*stream) << localSize[i]; (*stream) << localSize[i];
} }
static QShaderDescription::InOutVariable inOutVar(const QJsonObject &obj)
{
QShaderDescription::InOutVariable var;
var.name = obj[nameKey].toString().toUtf8();
var.type = mapType(obj[typeKey].toString());
if (obj.contains(locationKey))
var.location = obj[locationKey].toInt();
if (obj.contains(bindingKey))
var.binding = obj[bindingKey].toInt();
if (obj.contains(setKey))
var.descriptorSet = obj[setKey].toInt();
if (obj.contains(imageFormatKey))
var.imageFormat = mapImageFormat(obj[imageFormatKey].toString());
if (obj.contains(imageFlagsKey))
var.imageFlags = QShaderDescription::ImageFlags(obj[imageFlagsKey].toInt());
if (obj.contains(arrayDimsKey)) {
QJsonArray dimArr = obj[arrayDimsKey].toArray();
for (int i = 0; i < dimArr.count(); ++i)
var.arrayDims.append(dimArr.at(i).toInt());
}
return var;
}
static void deserializeDecorations(QDataStream *stream, int version, QShaderDescription::InOutVariable *v) static void deserializeDecorations(QDataStream *stream, int version, QShaderDescription::InOutVariable *v)
{ {
(*stream) >> v->location; (*stream) >> v->location;
@ -1161,32 +1098,6 @@ static QShaderDescription::InOutVariable deserializeInOutVar(QDataStream *stream
return var; return var;
} }
static QShaderDescription::BlockVariable blockVar(const QJsonObject &obj)
{
QShaderDescription::BlockVariable var;
var.name = obj[nameKey].toString().toUtf8();
var.type = mapType(obj[typeKey].toString());
var.offset = obj[offsetKey].toInt();
var.size = obj[sizeKey].toInt();
if (obj.contains(arrayDimsKey)) {
QJsonArray dimArr = obj[arrayDimsKey].toArray();
for (int i = 0; i < dimArr.count(); ++i)
var.arrayDims.append(dimArr.at(i).toInt());
}
if (obj.contains(arrayStrideKey))
var.arrayStride = obj[arrayStrideKey].toInt();
if (obj.contains(matrixStrideKey))
var.matrixStride = obj[matrixStrideKey].toInt();
if (obj.contains(matrixRowMajorKey))
var.matrixIsRowMajor = obj[matrixRowMajorKey].toBool();
if (obj.contains(structMembersKey)) {
QJsonArray arr = obj[structMembersKey].toArray();
for (int i = 0; i < arr.count(); ++i)
var.structMembers.append(blockVar(arr.at(i).toObject()));
}
return var;
}
static QShaderDescription::BlockVariable deserializeBlockMemberVar(QDataStream *stream, int version) static QShaderDescription::BlockVariable deserializeBlockMemberVar(QDataStream *stream, int version)
{ {
QShaderDescription::BlockVariable var; QShaderDescription::BlockVariable var;
@ -1213,110 +1124,6 @@ static QShaderDescription::BlockVariable deserializeBlockMemberVar(QDataStream *
return var; return var;
} }
void QShaderDescriptionPrivate::loadDoc(const QJsonDocument &doc)
{
if (doc.isNull()) {
qWarning("QShaderDescription: JSON document is empty");
return;
}
Q_ASSERT(ref.loadRelaxed() == 1); // must be detached
inVars.clear();
outVars.clear();
uniformBlocks.clear();
pushConstantBlocks.clear();
storageBlocks.clear();
combinedImageSamplers.clear();
storageImages.clear();
QJsonObject root = doc.object();
if (root.contains(inputsKey)) {
QJsonArray inputs = root[inputsKey].toArray();
for (int i = 0; i < inputs.count(); ++i)
inVars.append(inOutVar(inputs[i].toObject()));
}
if (root.contains(outputsKey)) {
QJsonArray outputs = root[outputsKey].toArray();
for (int i = 0; i < outputs.count(); ++i)
outVars.append(inOutVar(outputs[i].toObject()));
}
if (root.contains(uniformBlocksKey)) {
QJsonArray ubs = root[uniformBlocksKey].toArray();
for (int i = 0; i < ubs.count(); ++i) {
QJsonObject ubObj = ubs[i].toObject();
QShaderDescription::UniformBlock ub;
ub.blockName = ubObj[blockNameKey].toString().toUtf8();
ub.structName = ubObj[structNameKey].toString().toUtf8();
ub.size = ubObj[sizeKey].toInt();
if (ubObj.contains(bindingKey))
ub.binding = ubObj[bindingKey].toInt();
if (ubObj.contains(setKey))
ub.descriptorSet = ubObj[setKey].toInt();
QJsonArray members = ubObj[membersKey].toArray();
for (const QJsonValue &member : members)
ub.members.append(blockVar(member.toObject()));
uniformBlocks.append(ub);
}
}
if (root.contains(pushConstantBlocksKey)) {
QJsonArray pcs = root[pushConstantBlocksKey].toArray();
for (int i = 0; i < pcs.count(); ++i) {
QJsonObject pcObj = pcs[i].toObject();
QShaderDescription::PushConstantBlock pc;
pc.name = pcObj[nameKey].toString().toUtf8();
pc.size = pcObj[sizeKey].toInt();
QJsonArray members = pcObj[membersKey].toArray();
for (const QJsonValue &member : members)
pc.members.append(blockVar(member.toObject()));
pushConstantBlocks.append(pc);
}
}
if (root.contains(storageBlocksKey)) {
QJsonArray ubs = root[storageBlocksKey].toArray();
for (int i = 0; i < ubs.count(); ++i) {
QJsonObject sbObj = ubs[i].toObject();
QShaderDescription::StorageBlock sb;
sb.blockName = sbObj[blockNameKey].toString().toUtf8();
sb.instanceName = sbObj[instanceNameKey].toString().toUtf8();
sb.knownSize = sbObj[knownSizeKey].toInt();
if (sbObj.contains(bindingKey))
sb.binding = sbObj[bindingKey].toInt();
if (sbObj.contains(setKey))
sb.descriptorSet = sbObj[setKey].toInt();
QJsonArray members = sbObj[membersKey].toArray();
for (const QJsonValue &member : members)
sb.members.append(blockVar(member.toObject()));
storageBlocks.append(sb);
}
}
if (root.contains(combinedImageSamplersKey)) {
QJsonArray samplers = root[combinedImageSamplersKey].toArray();
for (int i = 0; i < samplers.count(); ++i)
combinedImageSamplers.append(inOutVar(samplers[i].toObject()));
}
if (root.contains(storageImagesKey)) {
QJsonArray images = root[storageImagesKey].toArray();
for (int i = 0; i < images.count(); ++i)
storageImages.append(inOutVar(images[i].toObject()));
}
if (root.contains(localSizeKey)) {
QJsonArray localSizeArr = root[localSizeKey].toArray();
if (localSizeArr.count() == 3) {
for (int i = 0; i < 3; ++i)
localSize[i] = localSizeArr[i].toInt();
}
}
}
void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream, int version) void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream, int version)
{ {
Q_ASSERT(ref.loadRelaxed() == 1); // must be detached Q_ASSERT(ref.loadRelaxed() == 1); // must be detached

View File

@ -69,13 +69,9 @@ public:
bool isValid() const; bool isValid() const;
#if QT_CONFIG(cborstreamwriter)
QByteArray toCbor() const;
#endif
void serialize(QDataStream *stream) const; void serialize(QDataStream *stream) const;
QByteArray toJson() const; QByteArray toJson() const;
static QShaderDescription fromCbor(const QByteArray &data);
static QShaderDescription deserialize(QDataStream *stream, int version); static QShaderDescription deserialize(QDataStream *stream, int version);
enum VariableType { enum VariableType {

View File

@ -81,7 +81,6 @@ struct Q_GUI_EXPORT QShaderDescriptionPrivate
QJsonDocument makeDoc(); QJsonDocument makeDoc();
void writeToStream(QDataStream *stream); void writeToStream(QDataStream *stream);
void loadDoc(const QJsonDocument &doc);
void loadFromStream(QDataStream *stream, int version); void loadFromStream(QDataStream *stream, int version);
QAtomicInt ref; QAtomicInt ref;

View File

@ -42,7 +42,6 @@ private slots:
void shaderDescImplicitSharing(); void shaderDescImplicitSharing();
void bakedShaderImplicitSharing(); void bakedShaderImplicitSharing();
void mslResourceMapping(); void mslResourceMapping();
void loadV3();
void serializeShaderDesc(); void serializeShaderDesc();
void comparison(); void comparison();
void loadV4(); void loadV4();
@ -291,80 +290,6 @@ void tst_QShader::mslResourceMapping()
QCOMPARE(resMap->value(1), qMakePair(0, 0)); // mapped to native texture index 0 and sampler index 0 QCOMPARE(resMap->value(1), qMakePair(0, 0)); // mapped to native texture index 0 and sampler index 0
} }
void tst_QShader::loadV3()
{
// qsb version 3: QShaderDescription is serialized as CBOR. Ensure the deserialized data is as expected.
QShader s = getShader(QLatin1String(":/data/texture_all_v3.frag.qsb"));
QVERIFY(s.isValid());
QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 3);
const QList<QShaderKey> availableShaders = s.availableShaders();
QCOMPARE(availableShaders.count(), 7);
QVERIFY(availableShaders.contains(QShaderKey(QShader::SpirvShader, QShaderVersion(100))));
QVERIFY(availableShaders.contains(QShaderKey(QShader::MslShader, QShaderVersion(12))));
QVERIFY(availableShaders.contains(QShaderKey(QShader::HlslShader, QShaderVersion(50))));
QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(100, QShaderVersion::GlslEs))));
QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(120))));
QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(150))));
QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(330))));
const QShaderDescription desc = s.description();
QVERIFY(desc.isValid());
QCOMPARE(desc.inputVariables().count(), 1);
for (const QShaderDescription::InOutVariable &v : desc.inputVariables()) {
switch (v.location) {
case 0:
QCOMPARE(v.name, QByteArrayLiteral("qt_TexCoord"));
QCOMPARE(v.type, QShaderDescription::Vec2);
break;
default:
QVERIFY(false);
break;
}
}
QCOMPARE(desc.outputVariables().count(), 1);
for (const QShaderDescription::InOutVariable &v : desc.outputVariables()) {
switch (v.location) {
case 0:
QCOMPARE(v.name, QByteArrayLiteral("fragColor"));
QCOMPARE(v.type, QShaderDescription::Vec4);
break;
default:
QVERIFY(false);
break;
}
}
QCOMPARE(desc.uniformBlocks().count(), 1);
const QShaderDescription::UniformBlock blk = desc.uniformBlocks().first();
QCOMPARE(blk.blockName, QByteArrayLiteral("buf"));
QCOMPARE(blk.structName, QByteArrayLiteral("ubuf"));
QCOMPARE(blk.size, 68);
QCOMPARE(blk.binding, 0);
QCOMPARE(blk.descriptorSet, 0);
QCOMPARE(blk.members.count(), 2);
for (int i = 0; i < blk.members.count(); ++i) {
const QShaderDescription::BlockVariable v = blk.members[i];
switch (i) {
case 0:
QCOMPARE(v.offset, 0);
QCOMPARE(v.size, 64);
QCOMPARE(v.name, QByteArrayLiteral("qt_Matrix"));
QCOMPARE(v.type, QShaderDescription::Mat4);
QCOMPARE(v.matrixStride, 16);
break;
case 1:
QCOMPARE(v.offset, 64);
QCOMPARE(v.size, 4);
QCOMPARE(v.name, QByteArrayLiteral("opacity"));
QCOMPARE(v.type, QShaderDescription::Float);
break;
default:
QVERIFY(false);
break;
}
}
}
void tst_QShader::serializeShaderDesc() void tst_QShader::serializeShaderDesc()
{ {
// default constructed QShaderDescription // default constructed QShaderDescription