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:
parent
fed97b9264
commit
a99cee1c7b
@ -442,9 +442,8 @@ QShader QShader::fromSerialized(const QByteArray &data)
|
||||
if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITH_CBOR) {
|
||||
d->desc = QShaderDescription::deserialize(&ds, d->qsbVersion);
|
||||
} else if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITH_BINARY_JSON) {
|
||||
QByteArray descBin;
|
||||
ds >> descBin;
|
||||
d->desc = QShaderDescription::fromCbor(descBin);
|
||||
qWarning("Can no longer load QShaderDescription from CBOR.");
|
||||
d->desc = QShaderDescription();
|
||||
} else {
|
||||
qWarning("Can no longer load QShaderDescription from binary JSON.");
|
||||
d->desc = QShaderDescription();
|
||||
|
@ -40,9 +40,6 @@
|
||||
#include <QDataStream>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QCborValue>
|
||||
#include <QCborMap>
|
||||
#include <QCborArray>
|
||||
|
||||
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
|
||||
float \c opacity at offset 64.
|
||||
|
||||
All this is described by a QShaderDescription object. QShaderDescription
|
||||
can also be serialized to JSON and CBOR, and can be deserialized
|
||||
from CBOR. In practice this is rarely needed since QShader
|
||||
takes care of the associated QShaderDescription automatically, but if the
|
||||
QShaderDescription of the above shader would be written out as JSON, it
|
||||
would look like the following:
|
||||
All this is described by a QShaderDescription object. QShaderDescription can
|
||||
be serialized to JSON and to a binary format via QDataStream, and can be
|
||||
deserialized from this binary format. In practice this is rarely needed
|
||||
since QShader takes care of the associated QShaderDescription automatically,
|
||||
but if the QShaderDescription of the above shader would be written out as
|
||||
JSON (like it is done by the \c qsb tool's \c{-d} option), it would look
|
||||
like the following:
|
||||
|
||||
\badcode
|
||||
{
|
||||
@ -337,54 +335,34 @@ bool QShaderDescription::isValid() const
|
||||
|| !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.
|
||||
|
||||
\note There is no deserialization method provided for JSON text.
|
||||
|
||||
\sa toCbor()
|
||||
\sa serialize()
|
||||
*/
|
||||
QByteArray QShaderDescription::toJson() const
|
||||
{
|
||||
return d->makeDoc().toJson();
|
||||
}
|
||||
|
||||
/*!
|
||||
Serializes this QShaderDescription to \a stream.
|
||||
|
||||
\sa deserialize(), toJson()
|
||||
*/
|
||||
void QShaderDescription::serialize(QDataStream *stream) const
|
||||
{
|
||||
d->writeToStream(stream);
|
||||
}
|
||||
|
||||
/*!
|
||||
Deserializes the given CBOR \a data and returns a new QShaderDescription.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
\return a new QShaderDescription loaded from \a stream. \a version specifies
|
||||
the qsb version.
|
||||
|
||||
\sa serialize()
|
||||
*/
|
||||
QShaderDescription QShaderDescription::deserialize(QDataStream *stream, int version)
|
||||
{
|
||||
QShaderDescription desc;
|
||||
@ -656,15 +634,6 @@ static QString typeStr(const QShaderDescription::VariableType &t)
|
||||
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 {
|
||||
QString k;
|
||||
QShaderDescription::ImageFormat v;
|
||||
@ -720,15 +689,6 @@ static QString imageFormatStr(const QShaderDescription::ImageFormat &f)
|
||||
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
|
||||
QDebug operator<<(QDebug dbg, const QShaderDescription &sd)
|
||||
{
|
||||
@ -1106,29 +1066,6 @@ void QShaderDescriptionPrivate::writeToStream(QDataStream *stream)
|
||||
(*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)
|
||||
{
|
||||
(*stream) >> v->location;
|
||||
@ -1161,32 +1098,6 @@ static QShaderDescription::InOutVariable deserializeInOutVar(QDataStream *stream
|
||||
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)
|
||||
{
|
||||
QShaderDescription::BlockVariable var;
|
||||
@ -1213,110 +1124,6 @@ static QShaderDescription::BlockVariable deserializeBlockMemberVar(QDataStream *
|
||||
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)
|
||||
{
|
||||
Q_ASSERT(ref.loadRelaxed() == 1); // must be detached
|
||||
|
@ -69,13 +69,9 @@ public:
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
#if QT_CONFIG(cborstreamwriter)
|
||||
QByteArray toCbor() const;
|
||||
#endif
|
||||
void serialize(QDataStream *stream) const;
|
||||
QByteArray toJson() const;
|
||||
|
||||
static QShaderDescription fromCbor(const QByteArray &data);
|
||||
static QShaderDescription deserialize(QDataStream *stream, int version);
|
||||
|
||||
enum VariableType {
|
||||
|
@ -81,7 +81,6 @@ struct Q_GUI_EXPORT QShaderDescriptionPrivate
|
||||
|
||||
QJsonDocument makeDoc();
|
||||
void writeToStream(QDataStream *stream);
|
||||
void loadDoc(const QJsonDocument &doc);
|
||||
void loadFromStream(QDataStream *stream, int version);
|
||||
|
||||
QAtomicInt ref;
|
||||
|
Binary file not shown.
@ -42,7 +42,6 @@ private slots:
|
||||
void shaderDescImplicitSharing();
|
||||
void bakedShaderImplicitSharing();
|
||||
void mslResourceMapping();
|
||||
void loadV3();
|
||||
void serializeShaderDesc();
|
||||
void comparison();
|
||||
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
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
// default constructed QShaderDescription
|
||||
|
Loading…
Reference in New Issue
Block a user