diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-10-28 16:37:57 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-10-29 15:22:46 +0100 |
commit | 58a67e4e0a88e52d71eef5d08df1465f7ac610ae (patch) | |
tree | 3d2a0ab28a8ee031f54165302f52df2de8a08fd8 /tests/auto/gui/rhi/qshader/tst_qshader.cpp | |
parent | c87e2c37de439996895fc2e2e4c79376b6ec1f09 (diff) |
rhi: Move to CBOR in QShader and expand the autotest
Binary JSON is said to become deprecated. Therefore, add support
for CBOR. Binary JSON is still supported for deserialization, so
all existing .qsb files will continue to work, as long as the
binaryjson feature is enabled in the Qt build.
Also makes QShaderDescription comparable. This is important for
tests in particular.
A nice side effect of using CBOR is that .qsb files become smaller.
For a typical Qt Quick material shader this can mean a reduction of
300 bytes or more.
Task-number: QTBUG-79576
Change-Id: I5547c0266e3e8128c9653e954e47487352267f71
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'tests/auto/gui/rhi/qshader/tst_qshader.cpp')
-rw-r--r-- | tests/auto/gui/rhi/qshader/tst_qshader.cpp | 174 |
1 files changed, 170 insertions, 4 deletions
diff --git a/tests/auto/gui/rhi/qshader/tst_qshader.cpp b/tests/auto/gui/rhi/qshader/tst_qshader.cpp index 21f0cc7895..a0082f1e3b 100644 --- a/tests/auto/gui/rhi/qshader/tst_qshader.cpp +++ b/tests/auto/gui/rhi/qshader/tst_qshader.cpp @@ -40,6 +40,9 @@ private slots: void genVariants(); void shaderDescImplicitSharing(); void bakedShaderImplicitSharing(); + void mslResourceMapping(); + void loadV3(); + void serializeShaderDesc(); }; static QShader getShader(const QString &name) @@ -53,8 +56,9 @@ static QShader getShader(const QString &name) void tst_QShader::simpleCompileCheckResults() { - QShader s = getShader(QLatin1String(":/data/color_simple.vert.qsb")); + QShader s = getShader(QLatin1String(":/data/color_spirv_v1.vert.qsb")); QVERIFY(s.isValid()); + QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 1); QCOMPARE(s.availableShaders().count(), 1); const QShaderCode shader = s.shader(QShaderKey(QShader::SpirvShader, @@ -125,10 +129,11 @@ void tst_QShader::simpleCompileCheckResults() void tst_QShader::genVariants() { - QShader s = getShader(QLatin1String(":/data/color.vert.qsb")); + QShader s = getShader(QLatin1String(":/data/color_all_v1.vert.qsb")); // spirv, glsl 100, glsl 330, glsl 120, hlsl 50, msl 12 // + batchable variants QVERIFY(s.isValid()); + QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 1); QCOMPARE(s.availableShaders().count(), 2 * 6); int batchableVariantCount = 0; @@ -149,8 +154,9 @@ void tst_QShader::genVariants() void tst_QShader::shaderDescImplicitSharing() { - QShader s = getShader(QLatin1String(":/data/color_simple.vert.qsb")); + QShader s = getShader(QLatin1String(":/data/color_spirv_v1.vert.qsb")); QVERIFY(s.isValid()); + QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 1); QCOMPARE(s.availableShaders().count(), 1); QVERIFY(s.availableShaders().contains(QShaderKey(QShader::SpirvShader, QShaderVersion(100)))); @@ -168,6 +174,7 @@ void tst_QShader::shaderDescImplicitSharing() QCOMPARE(d1.inputVariables().count(), 2); QCOMPARE(d1.outputVariables().count(), 1); QCOMPARE(d1.uniformBlocks().count(), 1); + QCOMPARE(d0, d1); d1.detach(); QVERIFY(QShaderDescriptionPrivate::get(&d0) != QShaderDescriptionPrivate::get(&d1)); @@ -177,12 +184,17 @@ void tst_QShader::shaderDescImplicitSharing() QCOMPARE(d1.inputVariables().count(), 2); QCOMPARE(d1.outputVariables().count(), 1); QCOMPARE(d1.uniformBlocks().count(), 1); + QCOMPARE(d0, d1); + + d1 = QShaderDescription(); + QVERIFY(d0 != d1); } void tst_QShader::bakedShaderImplicitSharing() { - QShader s0 = getShader(QLatin1String(":/data/color_simple.vert.qsb")); + QShader s0 = getShader(QLatin1String(":/data/color_spirv_v1.vert.qsb")); QVERIFY(s0.isValid()); + QCOMPARE(QShaderPrivate::get(&s0)->qsbVersion, 1); QCOMPARE(s0.availableShaders().count(), 1); QVERIFY(s0.availableShaders().contains(QShaderKey(QShader::SpirvShader, QShaderVersion(100)))); @@ -229,5 +241,159 @@ void tst_QShader::bakedShaderImplicitSharing() } } +void tst_QShader::mslResourceMapping() +{ + QShader s = getShader(QLatin1String(":/data/texture_all_v2.frag.qsb")); + QVERIFY(s.isValid()); + QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 2); + + const QVector<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 QShader::NativeResourceBindingMap *resMap = + s.nativeResourceBindingMap(QShaderKey(QShader::GlslShader, QShaderVersion(330))); + QVERIFY(!resMap); + + // The Metal shader must come with a mapping table for binding points 0 + // (uniform buffer) and 1 (combined image sampler mapped to a texture and + // sampler in the shader). + resMap = s.nativeResourceBindingMap(QShaderKey(QShader::MslShader, QShaderVersion(12))); + QVERIFY(resMap); + + QCOMPARE(resMap->count(), 2); + QCOMPARE(resMap->value(0).first, 0); // mapped to native buffer 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 QVector<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, 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; + } + } +} + +void tst_QShader::serializeShaderDesc() +{ + // default constructed QShaderDescription + { + QShaderDescription desc; + QVERIFY(!desc.isValid()); + + const QByteArray data = desc.toCbor(); + QVERIFY(!data.isEmpty()); + + QShaderDescription desc2 = QShaderDescription::fromCbor(data); + QVERIFY(!desc2.isValid()); + } + + // a QShaderDescription with inputs, outputs, uniform block and combined image sampler + { + QShader s = getShader(QLatin1String(":/data/texture_all_v3.frag.qsb")); + QVERIFY(s.isValid()); + const QShaderDescription desc = s.description(); + QVERIFY(desc.isValid()); + + const QByteArray data = desc.toCbor(); + QVERIFY(!data.isEmpty()); + + QShaderDescription desc2; + QVERIFY(!desc2.isValid()); + QVERIFY(!(desc == desc2)); + QVERIFY(desc != desc2); + + desc2 = QShaderDescription::fromCbor(data); + QVERIFY(desc2.isValid()); + QCOMPARE(desc, desc2); + } + + // exercise QShader and QShaderDescription comparisons + { + QShader s1 = getShader(QLatin1String(":/data/texture_all_v3.frag.qsb")); + QVERIFY(s1.isValid()); + QShader s2 = getShader(QLatin1String(":/data/color_all_v1.vert.qsb")); + QVERIFY(s2.isValid()); + + QVERIFY(s1.description().isValid()); + QVERIFY(s2.description().isValid()); + + QVERIFY(s1 != s2); + QVERIFY(s1.description() != s2.description()); + } +} + #include <tst_qshader.moc> QTEST_MAIN(tst_QShader) |