summaryrefslogtreecommitdiffstats
path: root/tests/auto/gui/rhi
diff options
context:
space:
mode:
authorLeander Beernaert <leander.beernaert@qt.io>2020-01-22 13:47:08 +0100
committerLeander Beernaert <leander.beernaert@qt.io>2020-01-24 13:17:33 +0100
commit502d3d6744913899da87acfda5ebdab42c40329e (patch)
tree16658a328503bfd5a62b4fd5d69ffb66e9854b18 /tests/auto/gui/rhi
parentd1be8b9ceb2c7b20bbe53a07154c79699540ea3d (diff)
parent06bb315beb6c2c398223cfe52cbc7f66e14a8557 (diff)
Merge remote-tracking branch 'origin/dev' into merge-dev
Diffstat (limited to 'tests/auto/gui/rhi')
-rw-r--r--tests/auto/gui/rhi/qrhi/tst_qrhi.cpp436
-rw-r--r--tests/auto/gui/rhi/qshader/data/texture_all_v4.frag.qsbbin0 -> 1272 bytes
-rw-r--r--tests/auto/gui/rhi/qshader/tst_qshader.cpp142
3 files changed, 514 insertions, 64 deletions
diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
index 533d6b17b1..191260fd41 100644
--- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
+++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
@@ -52,7 +52,7 @@
# define TST_D3D11
#endif
-#ifdef Q_OS_DARWIN
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
# include <QtGui/private/qrhimetal_p.h>
# define TST_MTL
#endif
@@ -73,6 +73,8 @@ private slots:
void create();
void nativeHandles_data();
void nativeHandles();
+ void nativeTexture_data();
+ void nativeTexture();
void resourceUpdateBatchBuffer_data();
void resourceUpdateBatchBuffer();
void resourceUpdateBatchRGBATextureUpload_data();
@@ -91,6 +93,10 @@ private slots:
void renderToTextureTexturedQuadAndUniformBuffer();
void renderToWindowSimple_data();
void renderToWindowSimple();
+ void srbLayoutCompatibility_data();
+ void srbLayoutCompatibility();
+ void renderPassDescriptorCompatibility_data();
+ void renderPassDescriptorCompatibility();
private:
struct {
@@ -375,56 +381,6 @@ void tst_QRhi::nativeHandles()
}
}
- // QRhiTexture::nativeHandles()
- {
- QScopedPointer<QRhiTexture> tex(rhi->newTexture(QRhiTexture::RGBA8, QSize(512, 256)));
- QVERIFY(tex->build());
-
- const QRhiNativeHandles *texHandles = tex->nativeHandles();
- QVERIFY(texHandles);
-
- switch (impl) {
- case QRhi::Null:
- break;
-#ifdef TST_VK
- case QRhi::Vulkan:
- {
- const QRhiVulkanTextureNativeHandles *vkHandles = static_cast<const QRhiVulkanTextureNativeHandles *>(texHandles);
- QVERIFY(vkHandles->image);
- QVERIFY(vkHandles->layout >= 1); // VK_IMAGE_LAYOUT_GENERAL
- QVERIFY(vkHandles->layout <= 8); // VK_IMAGE_LAYOUT_PREINITIALIZED
- }
- break;
-#endif
-#ifdef TST_GL
- case QRhi::OpenGLES2:
- {
- const QRhiGles2TextureNativeHandles *glHandles = static_cast<const QRhiGles2TextureNativeHandles *>(texHandles);
- QVERIFY(glHandles->texture);
- }
- break;
-#endif
-#ifdef TST_D3D11
- case QRhi::D3D11:
- {
- const QRhiD3D11TextureNativeHandles *d3dHandles = static_cast<const QRhiD3D11TextureNativeHandles *>(texHandles);
- QVERIFY(d3dHandles->texture);
- }
- break;
-#endif
-#ifdef TST_MTL
- case QRhi::Metal:
- {
- const QRhiMetalTextureNativeHandles *mtlHandles = static_cast<const QRhiMetalTextureNativeHandles *>(texHandles);
- QVERIFY(mtlHandles->texture);
- }
- break;
-#endif
- default:
- Q_ASSERT(false);
- }
- }
-
// QRhiCommandBuffer::nativeHandles()
{
QRhiCommandBuffer *cb = nullptr;
@@ -524,6 +480,71 @@ void tst_QRhi::nativeHandles()
}
}
+void tst_QRhi::nativeTexture_data()
+{
+ rhiTestData();
+}
+
+void tst_QRhi::nativeTexture()
+{
+ QFETCH(QRhi::Implementation, impl);
+ QFETCH(QRhiInitParams *, initParams);
+
+ QScopedPointer<QRhi> rhi(QRhi::create(impl, initParams, QRhi::Flags(), nullptr));
+ if (!rhi)
+ QSKIP("QRhi could not be created, skipping testing native texture");
+
+ QScopedPointer<QRhiTexture> tex(rhi->newTexture(QRhiTexture::RGBA8, QSize(512, 256)));
+ QVERIFY(tex->build());
+
+ const QRhiTexture::NativeTexture nativeTex = tex->nativeTexture();
+
+ switch (impl) {
+ case QRhi::Null:
+ break;
+#ifdef TST_VK
+ case QRhi::Vulkan:
+ {
+ auto *image = static_cast<const VkImage *>(nativeTex.object);
+ QVERIFY(image);
+ QVERIFY(*image);
+ QVERIFY(nativeTex.layout >= 1); // VK_IMAGE_LAYOUT_GENERAL
+ QVERIFY(nativeTex.layout <= 8); // VK_IMAGE_LAYOUT_PREINITIALIZED
+ }
+ break;
+#endif
+#ifdef TST_GL
+ case QRhi::OpenGLES2:
+ {
+ auto *textureId = static_cast<const uint *>(nativeTex.object);
+ QVERIFY(textureId);
+ QVERIFY(*textureId);
+ }
+ break;
+#endif
+#ifdef TST_D3D11
+ case QRhi::D3D11:
+ {
+ auto *texture = static_cast<void * const *>(nativeTex.object);
+ QVERIFY(texture);
+ QVERIFY(*texture);
+ }
+ break;
+#endif
+#ifdef TST_MTL
+ case QRhi::Metal:
+ {
+ void * const * texture = (void * const *)nativeTex.object;
+ QVERIFY(texture);
+ QVERIFY(*texture);
+ }
+ break;
+#endif
+ default:
+ Q_ASSERT(false);
+ }
+}
+
static bool submitResourceUpdates(QRhi *rhi, QRhiResourceUpdateBatch *batch)
{
QRhiCommandBuffer *cb = nullptr;
@@ -1728,5 +1749,318 @@ void tst_QRhi::renderToWindowSimple()
QVERIFY(redCount < blueCount);
}
+void tst_QRhi::srbLayoutCompatibility_data()
+{
+ rhiTestData();
+}
+
+void tst_QRhi::srbLayoutCompatibility()
+{
+ QFETCH(QRhi::Implementation, impl);
+ QFETCH(QRhiInitParams *, initParams);
+
+ QScopedPointer<QRhi> rhi(QRhi::create(impl, initParams, QRhi::Flags(), nullptr));
+ if (!rhi)
+ QSKIP("QRhi could not be created, skipping testing texture resource updates");
+
+ QScopedPointer<QRhiTexture> texture(rhi->newTexture(QRhiTexture::RGBA8, QSize(512, 512)));
+ QVERIFY(texture->build());
+ QScopedPointer<QRhiSampler> sampler(rhi->newSampler(QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None,
+ QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge));
+ QVERIFY(sampler->build());
+ QScopedPointer<QRhiSampler> otherSampler(rhi->newSampler(QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None,
+ QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge));
+ QVERIFY(otherSampler->build());
+ QScopedPointer<QRhiBuffer> buf(rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 1024));
+ QVERIFY(buf->build());
+ QScopedPointer<QRhiBuffer> otherBuf(rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 256));
+ QVERIFY(otherBuf->build());
+
+ // empty (compatible)
+ {
+ QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings());
+ QVERIFY(srb1->build());
+
+ QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings());
+ QVERIFY(srb2->build());
+
+ QVERIFY(srb1->isLayoutCompatible(srb2.data()));
+ QVERIFY(srb2->isLayoutCompatible(srb1.data()));
+ }
+
+ // different count (not compatible)
+ {
+ QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings());
+ QVERIFY(srb1->build());
+
+ QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings());
+ srb2->setBindings({
+ QRhiShaderResourceBinding::sampledTexture(0, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data())
+ });
+ QVERIFY(srb2->build());
+
+ QVERIFY(!srb1->isLayoutCompatible(srb2.data()));
+ QVERIFY(!srb2->isLayoutCompatible(srb1.data()));
+ }
+
+ // full match (compatible)
+ {
+ QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings());
+ srb1->setBindings({
+ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()),
+ QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data())
+ });
+ QVERIFY(srb1->build());
+
+ QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings());
+ srb2->setBindings({
+ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()),
+ QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data())
+ });
+ QVERIFY(srb2->build());
+
+ QVERIFY(srb1->isLayoutCompatible(srb2.data()));
+ QVERIFY(srb2->isLayoutCompatible(srb1.data()));
+ }
+
+ // different visibility (not compatible)
+ {
+ QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings());
+ srb1->setBindings({
+ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, buf.data()),
+ });
+ QVERIFY(srb1->build());
+
+ QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings());
+ srb2->setBindings({
+ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()),
+ });
+ QVERIFY(srb2->build());
+
+ QVERIFY(!srb1->isLayoutCompatible(srb2.data()));
+ QVERIFY(!srb2->isLayoutCompatible(srb1.data()));
+ }
+
+ // different binding points (not compatible)
+ {
+ QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings());
+ srb1->setBindings({
+ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()),
+ });
+ QVERIFY(srb1->build());
+
+ QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings());
+ srb2->setBindings({
+ QRhiShaderResourceBinding::uniformBuffer(1, QRhiShaderResourceBinding::VertexStage, buf.data()),
+ });
+ QVERIFY(srb2->build());
+
+ QVERIFY(!srb1->isLayoutCompatible(srb2.data()));
+ QVERIFY(!srb2->isLayoutCompatible(srb1.data()));
+ }
+
+ // different buffer region offset and size (compatible)
+ {
+ QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings());
+ srb1->setBindings({
+ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data(), rhi->ubufAligned(1), 128),
+ QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data())
+ });
+ QVERIFY(srb1->build());
+
+ QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings());
+ srb2->setBindings({
+ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()),
+ QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data())
+ });
+ QVERIFY(srb2->build());
+
+ QVERIFY(srb1->isLayoutCompatible(srb2.data()));
+ QVERIFY(srb2->isLayoutCompatible(srb1.data()));
+ }
+
+ // different resources (compatible)
+ {
+ QScopedPointer<QRhiShaderResourceBindings> srb1(rhi->newShaderResourceBindings());
+ srb1->setBindings({
+ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, otherBuf.data()),
+ QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), otherSampler.data())
+ });
+ QVERIFY(srb1->build());
+
+ QScopedPointer<QRhiShaderResourceBindings> srb2(rhi->newShaderResourceBindings());
+ srb2->setBindings({
+ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, buf.data()),
+ QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, texture.data(), sampler.data())
+ });
+ QVERIFY(srb2->build());
+
+ QVERIFY(srb1->isLayoutCompatible(srb2.data()));
+ QVERIFY(srb2->isLayoutCompatible(srb1.data()));
+ }
+}
+
+void tst_QRhi::renderPassDescriptorCompatibility_data()
+{
+ rhiTestData();
+}
+
+void tst_QRhi::renderPassDescriptorCompatibility()
+{
+ QFETCH(QRhi::Implementation, impl);
+ QFETCH(QRhiInitParams *, initParams);
+
+ QScopedPointer<QRhi> rhi(QRhi::create(impl, initParams, QRhi::Flags(), nullptr));
+ if (!rhi)
+ QSKIP("QRhi could not be created, skipping testing texture resource updates");
+
+ // Note that checking compatibility is only relevant with backends where
+ // there is a concept of renderpass descriptions (Vulkan, and partially
+ // Metal). It is perfectly fine for isCompatible() to always return true
+ // when that is not the case (D3D11, OpenGL). Hence the 'if (Vulkan or
+ // Metal)' for all the negative tests. Also note "partial" for Metal:
+ // resolve textures for examples have no effect on compatibility with Metal.
+
+ // tex and tex2 have the same format
+ QScopedPointer<QRhiTexture> tex(rhi->newTexture(QRhiTexture::RGBA8, QSize(512, 512), 1, QRhiTexture::RenderTarget));
+ QVERIFY(tex->build());
+ QScopedPointer<QRhiTexture> tex2(rhi->newTexture(QRhiTexture::RGBA8, QSize(512, 512), 1, QRhiTexture::RenderTarget));
+ QVERIFY(tex2->build());
+
+ QScopedPointer<QRhiRenderBuffer> ds(rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, QSize(512, 512)));
+ QVERIFY(ds->build());
+
+ // two texture rendertargets with tex and tex2 as color0 (compatible)
+ {
+ QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ tex.data() }));
+ QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor());
+ rt->setRenderPassDescriptor(rpDesc.data());
+ QVERIFY(rt->build());
+
+ QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget({ tex2.data() }));
+ QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor());
+ rt2->setRenderPassDescriptor(rpDesc2.data());
+ QVERIFY(rt2->build());
+
+ QVERIFY(rpDesc->isCompatible(rpDesc2.data()));
+ QVERIFY(rpDesc2->isCompatible(rpDesc.data()));
+ }
+
+ // two texture rendertargets with tex and tex2 as color0, and a depth-stencil attachment as well (compatible)
+ {
+ QRhiTextureRenderTargetDescription desc({ tex.data() }, ds.data());
+ QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget(desc));
+ QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor());
+ rt->setRenderPassDescriptor(rpDesc.data());
+ QVERIFY(rt->build());
+
+ QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget(desc));
+ QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor());
+ rt2->setRenderPassDescriptor(rpDesc2.data());
+ QVERIFY(rt2->build());
+
+ QVERIFY(rpDesc->isCompatible(rpDesc2.data()));
+ QVERIFY(rpDesc2->isCompatible(rpDesc.data()));
+ }
+
+ // now one of them does not have the ds attachment (not compatible)
+ {
+ QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ { tex.data() }, ds.data() }));
+ QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor());
+ rt->setRenderPassDescriptor(rpDesc.data());
+ QVERIFY(rt->build());
+
+ QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget({ tex.data() }));
+ QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor());
+ rt2->setRenderPassDescriptor(rpDesc2.data());
+ QVERIFY(rt2->build());
+
+ if (impl == QRhi::Vulkan || impl == QRhi::Metal) {
+ QVERIFY(!rpDesc->isCompatible(rpDesc2.data()));
+ QVERIFY(!rpDesc2->isCompatible(rpDesc.data()));
+ }
+ }
+
+ if (rhi->isFeatureSupported(QRhi::MultisampleRenderBuffer)) {
+ // resolve attachments (compatible)
+ {
+ QScopedPointer<QRhiRenderBuffer> msaaRenderBuffer(rhi->newRenderBuffer(QRhiRenderBuffer::Color, QSize(512, 512), 4));
+ QVERIFY(msaaRenderBuffer->build());
+ QScopedPointer<QRhiRenderBuffer> msaaRenderBuffer2(rhi->newRenderBuffer(QRhiRenderBuffer::Color, QSize(512, 512), 4));
+ QVERIFY(msaaRenderBuffer2->build());
+
+ QRhiColorAttachment colorAtt(msaaRenderBuffer.data()); // color0, multisample
+ colorAtt.setResolveTexture(tex.data()); // resolved into a non-msaa texture
+ QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ colorAtt }));
+ QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor());
+ rt->setRenderPassDescriptor(rpDesc.data());
+ QVERIFY(rt->build());
+
+ QRhiColorAttachment colorAtt2(msaaRenderBuffer2.data()); // color0, multisample
+ colorAtt2.setResolveTexture(tex2.data()); // resolved into a non-msaa texture
+ QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget({ colorAtt2 }));
+ QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor());
+ rt2->setRenderPassDescriptor(rpDesc2.data());
+ QVERIFY(rt2->build());
+
+ QVERIFY(rpDesc->isCompatible(rpDesc2.data()));
+ QVERIFY(rpDesc2->isCompatible(rpDesc.data()));
+ }
+
+ // missing resolve for one of them (not compatible)
+ {
+ QScopedPointer<QRhiRenderBuffer> msaaRenderBuffer(rhi->newRenderBuffer(QRhiRenderBuffer::Color, QSize(512, 512), 4));
+ QVERIFY(msaaRenderBuffer->build());
+ QScopedPointer<QRhiRenderBuffer> msaaRenderBuffer2(rhi->newRenderBuffer(QRhiRenderBuffer::Color, QSize(512, 512), 4));
+ QVERIFY(msaaRenderBuffer2->build());
+
+ QRhiColorAttachment colorAtt(msaaRenderBuffer.data()); // color0, multisample
+ colorAtt.setResolveTexture(tex.data()); // resolved into a non-msaa texture
+ QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ colorAtt }));
+ QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor());
+ rt->setRenderPassDescriptor(rpDesc.data());
+ QVERIFY(rt->build());
+
+ QRhiColorAttachment colorAtt2(msaaRenderBuffer2.data()); // color0, multisample
+ QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget({ colorAtt2 }));
+ QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor());
+ rt2->setRenderPassDescriptor(rpDesc2.data());
+ QVERIFY(rt2->build());
+
+ if (impl == QRhi::Vulkan) { // no Metal here
+ QVERIFY(!rpDesc->isCompatible(rpDesc2.data()));
+ QVERIFY(!rpDesc2->isCompatible(rpDesc.data()));
+ }
+ }
+ } else {
+ qDebug("Skipping multisample renderbuffer dependent tests");
+ }
+
+ if (rhi->isTextureFormatSupported(QRhiTexture::RGBA32F)) {
+ QScopedPointer<QRhiTexture> tex3(rhi->newTexture(QRhiTexture::RGBA32F, QSize(512, 512), 1, QRhiTexture::RenderTarget));
+ QVERIFY(tex3->build());
+
+ // different texture formats (not compatible)
+ {
+ QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ tex.data() }));
+ QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor());
+ rt->setRenderPassDescriptor(rpDesc.data());
+ QVERIFY(rt->build());
+
+ QScopedPointer<QRhiTextureRenderTarget> rt2(rhi->newTextureRenderTarget({ tex3.data() }));
+ QScopedPointer<QRhiRenderPassDescriptor> rpDesc2(rt2->newCompatibleRenderPassDescriptor());
+ rt2->setRenderPassDescriptor(rpDesc2.data());
+ QVERIFY(rt2->build());
+
+ if (impl == QRhi::Vulkan || impl == QRhi::Metal) {
+ QVERIFY(!rpDesc->isCompatible(rpDesc2.data()));
+ QVERIFY(!rpDesc2->isCompatible(rpDesc.data()));
+ }
+ }
+ } else {
+ qDebug("Skipping texture format dependent tests");
+ }
+}
+
#include <tst_qrhi.moc>
QTEST_MAIN(tst_QRhi)
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
--- /dev/null
+++ b/tests/auto/gui/rhi/qshader/data/texture_all_v4.frag.qsb
Binary files differ
diff --git a/tests/auto/gui/rhi/qshader/tst_qshader.cpp b/tests/auto/gui/rhi/qshader/tst_qshader.cpp
index a0082f1e3b..ab7115b74a 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,36 +355,63 @@ 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;
- QVERIFY(!desc2.isValid());
- QVERIFY(!(desc == desc2));
- QVERIFY(desc != desc2);
+ {
+ QShaderDescription desc2;
+ QVERIFY(!desc2.isValid());
+ 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 +422,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<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;
+ }
+ }
}
#include <tst_qshader.moc>