From 7e2cef0f15b133c07bd11aa5e5065b0b9959fb0d Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Sun, 12 Jan 2020 17:33:31 +0100 Subject: 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 --- .../gui/rhi/qshader/data/texture_all_v4.frag.qsb | Bin 0 -> 1272 bytes tests/auto/gui/rhi/qshader/tst_qshader.cpp | 132 +++++++++++++++++++-- 2 files changed, 123 insertions(+), 9 deletions(-) create mode 100644 tests/auto/gui/rhi/qshader/data/texture_all_v4.frag.qsb (limited to 'tests') diff --git a/tests/auto/gui/rhi/qshader/data/texture_all_v4.frag.qsb b/tests/auto/gui/rhi/qshader/data/texture_all_v4.frag.qsb new file mode 100644 index 0000000000..4292d67b7c Binary files /dev/null and b/tests/auto/gui/rhi/qshader/data/texture_all_v4.frag.qsb differ diff --git a/tests/auto/gui/rhi/qshader/tst_qshader.cpp b/tests/auto/gui/rhi/qshader/tst_qshader.cpp index a0082f1e3b..b90ac8dc53 100644 --- a/tests/auto/gui/rhi/qshader/tst_qshader.cpp +++ b/tests/auto/gui/rhi/qshader/tst_qshader.cpp @@ -43,6 +43,8 @@ private slots: void mslResourceMapping(); void loadV3(); void serializeShaderDesc(); + void comparison(); + void loadV4(); }; static QShader getShader(const QString &name) @@ -353,21 +355,38 @@ void tst_QShader::serializeShaderDesc() QShaderDescription desc; QVERIFY(!desc.isValid()); - const QByteArray data = desc.toCbor(); + QByteArray data; + { + QBuffer buf(&data); + QDataStream ds(&buf); + QVERIFY(buf.open(QIODevice::WriteOnly)); + desc.serialize(&ds); + } QVERIFY(!data.isEmpty()); - QShaderDescription desc2 = QShaderDescription::fromCbor(data); - QVERIFY(!desc2.isValid()); + { + QBuffer buf(&data); + QDataStream ds(&buf); + QVERIFY(buf.open(QIODevice::ReadOnly)); + QShaderDescription desc2 = QShaderDescription::deserialize(&ds); + QVERIFY(!desc2.isValid()); + } } // a QShaderDescription with inputs, outputs, uniform block and combined image sampler { - QShader s = getShader(QLatin1String(":/data/texture_all_v3.frag.qsb")); + QShader s = getShader(QLatin1String(":/data/texture_all_v4.frag.qsb")); QVERIFY(s.isValid()); const QShaderDescription desc = s.description(); QVERIFY(desc.isValid()); - const QByteArray data = desc.toCbor(); + QByteArray data; + { + QBuffer buf(&data); + QDataStream ds(&buf); + QVERIFY(buf.open(QIODevice::WriteOnly)); + desc.serialize(&ds); + } QVERIFY(!data.isEmpty()); QShaderDescription desc2; @@ -375,14 +394,22 @@ void tst_QShader::serializeShaderDesc() QVERIFY(!(desc == desc2)); QVERIFY(desc != desc2); - desc2 = QShaderDescription::fromCbor(data); - QVERIFY(desc2.isValid()); - QCOMPARE(desc, desc2); + { + QBuffer buf(&data); + QDataStream ds(&buf); + QVERIFY(buf.open(QIODevice::ReadOnly)); + QShaderDescription desc2 = QShaderDescription::deserialize(&ds); + QVERIFY(desc2.isValid()); + QCOMPARE(desc, desc2); + } } +} +void tst_QShader::comparison() +{ // exercise QShader and QShaderDescription comparisons { - QShader s1 = getShader(QLatin1String(":/data/texture_all_v3.frag.qsb")); + QShader s1 = getShader(QLatin1String(":/data/texture_all_v4.frag.qsb")); QVERIFY(s1.isValid()); QShader s2 = getShader(QLatin1String(":/data/color_all_v1.vert.qsb")); QVERIFY(s2.isValid()); @@ -393,6 +420,93 @@ void tst_QShader::serializeShaderDesc() QVERIFY(s1 != s2); QVERIFY(s1.description() != s2.description()); } + + { + QShader s1 = getShader(QLatin1String(":/data/texture_all_v4.frag.qsb")); + QVERIFY(s1.isValid()); + QShader s2 = getShader(QLatin1String(":/data/texture_all_v4.frag.qsb")); + QVERIFY(s2.isValid()); + + QVERIFY(s1.description().isValid()); + QVERIFY(s2.description().isValid()); + + QVERIFY(s1 == s2); + QVERIFY(s1.description() == s2.description()); + } +} + +void tst_QShader::loadV4() +{ + // qsb version 4: QShaderDescription is serialized via QDataStream. Ensure the deserialized data is as expected. + QShader s = getShader(QLatin1String(":/data/texture_all_v4.frag.qsb")); + QVERIFY(s.isValid()); + QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 4); + + const QVector 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, QLatin1String("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, QLatin1String("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, QLatin1String("buf")); + QCOMPARE(blk.structName, QLatin1String("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, QLatin1String("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, QLatin1String("opacity")); + QCOMPARE(v.type, QShaderDescription::Float); + break; + default: + QVERIFY(false); + break; + } + } } #include -- cgit v1.2.3