diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-10-07 17:12:59 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-10-09 17:15:06 +0200 |
commit | b2de7f8583a9a2e73f0de507534158354a86ce7d (patch) | |
tree | 6aca8d5c14cf8e93988ff9c9a0b4cf4c1403499c /tests | |
parent | 8f44da1f551a94d99b6772c8c459436e455ca8cd (diff) |
rhi: Autotest rendering a textured quad
Task-number: QTBUG-78971
Change-Id: I0e7e0f3c00f9509031f7b4a8a389e51c915f01c2
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/gui/rhi/qrhi/data/compile.bat | 2 | ||||
-rw-r--r-- | tests/auto/gui/rhi/qrhi/data/qt256.png | bin | 0 -> 6208 bytes | |||
-rw-r--r-- | tests/auto/gui/rhi/qrhi/data/simple.frag.qsb | bin | 908 -> 899 bytes | |||
-rw-r--r-- | tests/auto/gui/rhi/qrhi/data/simple.vert.qsb | bin | 967 -> 961 bytes | |||
-rw-r--r-- | tests/auto/gui/rhi/qrhi/data/simpletextured.frag | 13 | ||||
-rw-r--r-- | tests/auto/gui/rhi/qrhi/data/simpletextured.frag.qsb | bin | 0 -> 1487 bytes | |||
-rw-r--r-- | tests/auto/gui/rhi/qrhi/data/simpletextured.vert | 14 | ||||
-rw-r--r-- | tests/auto/gui/rhi/qrhi/data/simpletextured.vert.qsb | bin | 0 -> 1195 bytes | |||
-rw-r--r-- | tests/auto/gui/rhi/qrhi/tst_qrhi.cpp | 159 |
9 files changed, 188 insertions, 0 deletions
diff --git a/tests/auto/gui/rhi/qrhi/data/compile.bat b/tests/auto/gui/rhi/qrhi/data/compile.bat index 2c97b02180..3dafa33eab 100644 --- a/tests/auto/gui/rhi/qrhi/data/compile.bat +++ b/tests/auto/gui/rhi/qrhi/data/compile.bat @@ -42,3 +42,5 @@ qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o simple.vert.qsb simple.vert qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o simple.frag.qsb simple.frag +qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o simpletextured.vert.qsb simpletextured.vert +qsb --glsl "150,120,100 es" --hlsl 50 -c --msl 12 -o simpletextured.frag.qsb simpletextured.frag diff --git a/tests/auto/gui/rhi/qrhi/data/qt256.png b/tests/auto/gui/rhi/qrhi/data/qt256.png Binary files differnew file mode 100644 index 0000000000..30c621c9c6 --- /dev/null +++ b/tests/auto/gui/rhi/qrhi/data/qt256.png diff --git a/tests/auto/gui/rhi/qrhi/data/simple.frag.qsb b/tests/auto/gui/rhi/qrhi/data/simple.frag.qsb Binary files differindex 264b71ec0f..0b46de1453 100644 --- a/tests/auto/gui/rhi/qrhi/data/simple.frag.qsb +++ b/tests/auto/gui/rhi/qrhi/data/simple.frag.qsb diff --git a/tests/auto/gui/rhi/qrhi/data/simple.vert.qsb b/tests/auto/gui/rhi/qrhi/data/simple.vert.qsb Binary files differindex 31941d18aa..8e44f2a1e3 100644 --- a/tests/auto/gui/rhi/qrhi/data/simple.vert.qsb +++ b/tests/auto/gui/rhi/qrhi/data/simple.vert.qsb diff --git a/tests/auto/gui/rhi/qrhi/data/simpletextured.frag b/tests/auto/gui/rhi/qrhi/data/simpletextured.frag new file mode 100644 index 0000000000..630df7b807 --- /dev/null +++ b/tests/auto/gui/rhi/qrhi/data/simpletextured.frag @@ -0,0 +1,13 @@ +#version 440 + +layout(location = 0) in vec2 uv; +layout(location = 0) out vec4 fragColor; + +layout(binding = 0) uniform sampler2D tex; + +void main() +{ + vec4 c = texture(tex, uv); + c.rgb *= c.a; + fragColor = c; +} diff --git a/tests/auto/gui/rhi/qrhi/data/simpletextured.frag.qsb b/tests/auto/gui/rhi/qrhi/data/simpletextured.frag.qsb Binary files differnew file mode 100644 index 0000000000..876290cbc7 --- /dev/null +++ b/tests/auto/gui/rhi/qrhi/data/simpletextured.frag.qsb diff --git a/tests/auto/gui/rhi/qrhi/data/simpletextured.vert b/tests/auto/gui/rhi/qrhi/data/simpletextured.vert new file mode 100644 index 0000000000..1dd204f84d --- /dev/null +++ b/tests/auto/gui/rhi/qrhi/data/simpletextured.vert @@ -0,0 +1,14 @@ +#version 440 + +layout(location = 0) in vec4 position; +layout(location = 1) in vec2 texcoord; + +layout(location = 0) out vec2 uv; + +out gl_PerVertex { vec4 gl_Position; }; + +void main() +{ + uv = texcoord; + gl_Position = position; +} diff --git a/tests/auto/gui/rhi/qrhi/data/simpletextured.vert.qsb b/tests/auto/gui/rhi/qrhi/data/simpletextured.vert.qsb Binary files differnew file mode 100644 index 0000000000..e4f12bfb9e --- /dev/null +++ b/tests/auto/gui/rhi/qrhi/data/simpletextured.vert.qsb diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp index 65561595a1..ddead9aa44 100644 --- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp +++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp @@ -85,6 +85,8 @@ private slots: void invalidPipeline(); void renderToTextureSimple_data(); void renderToTextureSimple(); + void renderToTextureTexturedQuad_data(); + void renderToTextureTexturedQuad(); private: struct { @@ -818,6 +820,34 @@ void tst_QRhi::resourceUpdateBatchRGBATextureUpload() QVERIFY(imageRGBAEquals(expectedImage, wrapperImage)); } + + // now a QImage from an actual file + { + QImage inputImage; + inputImage.load(QLatin1String(":/data/qt256.png")); + QVERIFY(!inputImage.isNull()); + inputImage = std::move(inputImage).convertToFormat(image.format()); + + QScopedPointer<QRhiTexture> texture(rhi->newTexture(QRhiTexture::RGBA8, inputImage.size(), + 1, QRhiTexture::UsedAsTransferSource)); + QVERIFY(texture->build()); + + QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch(); + batch->uploadTexture(texture.data(), inputImage); + + QRhiReadbackResult readResult; + bool readCompleted = false; + readResult.completed = [&readCompleted] { readCompleted = true; }; + batch->readBackTexture(texture.data(), &readResult); + + QVERIFY(submitResourceUpdates(rhi.data(), batch)); + QVERIFY(readCompleted); + QImage wrapperImage(reinterpret_cast<const uchar *>(readResult.data.constData()), + readResult.pixelSize.width(), readResult.pixelSize.height(), + inputImage.format()); + + QVERIFY(imageRGBAEquals(inputImage, wrapperImage)); + } } void tst_QRhi::resourceUpdateBatchRGBATextureCopy_data() @@ -1201,5 +1231,134 @@ void tst_QRhi::renderToTextureSimple() QVERIFY(redCount > blueCount); } +void tst_QRhi::renderToTextureTexturedQuad_data() +{ + rhiTestData(); +} + +void tst_QRhi::renderToTextureTexturedQuad() +{ + 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 rendering"); + + QImage inputImage; + inputImage.load(QLatin1String(":/data/qt256.png")); + QVERIFY(!inputImage.isNull()); + + QScopedPointer<QRhiTexture> texture(rhi->newTexture(QRhiTexture::RGBA8, inputImage.size(), 1, + QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource)); + QVERIFY(texture->build()); + + QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ texture.data() })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor()); + rt->setRenderPassDescriptor(rpDesc.data()); + QVERIFY(rt->build()); + + QRhiCommandBuffer *cb = nullptr; + QVERIFY(rhi->beginOffscreenFrame(&cb) == QRhi::FrameOpSuccess); + QVERIFY(cb); + + QRhiResourceUpdateBatch *updates = rhi->nextResourceUpdateBatch(); + + static const float verticesUvs[] = { + -1.0f, -1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 0.0f, + -1.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f + }; + QScopedPointer<QRhiBuffer> vbuf(rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(verticesUvs))); + QVERIFY(vbuf->build()); + updates->uploadStaticBuffer(vbuf.data(), verticesUvs); + + QScopedPointer<QRhiTexture> inputTexture(rhi->newTexture(QRhiTexture::RGBA8, inputImage.size())); + QVERIFY(inputTexture->build()); + updates->uploadTexture(inputTexture.data(), inputImage); + + QScopedPointer<QRhiSampler> sampler(rhi->newSampler(QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None, + QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge)); + QVERIFY(sampler->build()); + + QScopedPointer<QRhiShaderResourceBindings> srb(rhi->newShaderResourceBindings()); + srb->setBindings({ + QRhiShaderResourceBinding::sampledTexture(0, QRhiShaderResourceBinding::FragmentStage, inputTexture.data(), sampler.data()) + }); + QVERIFY(srb->build()); + + QScopedPointer<QRhiGraphicsPipeline> pipeline(rhi->newGraphicsPipeline()); + pipeline->setTopology(QRhiGraphicsPipeline::TriangleStrip); + QShader vs = loadShader(":/data/simpletextured.vert.qsb"); + QVERIFY(vs.isValid()); + QShader fs = loadShader(":/data/simpletextured.frag.qsb"); + QVERIFY(fs.isValid()); + pipeline->setShaderStages({ { QRhiShaderStage::Vertex, vs }, { QRhiShaderStage::Fragment, fs } }); + QRhiVertexInputLayout inputLayout; + inputLayout.setBindings({ { 4 * sizeof(float) } }); + inputLayout.setAttributes({ + { 0, 0, QRhiVertexInputAttribute::Float2, 0 }, + { 0, 1, QRhiVertexInputAttribute::Float2, 2 * sizeof(float) } + }); + pipeline->setVertexInputLayout(inputLayout); + pipeline->setShaderResourceBindings(srb.data()); + pipeline->setRenderPassDescriptor(rpDesc.data()); + + QVERIFY(pipeline->build()); + + cb->beginPass(rt.data(), Qt::black, { 1.0f, 0 }, updates); + cb->setGraphicsPipeline(pipeline.data()); + cb->setShaderResources(); + cb->setViewport({ 0, 0, float(texture->pixelSize().width()), float(texture->pixelSize().height()) }); + QRhiCommandBuffer::VertexInput vbindings(vbuf.data(), 0); + cb->setVertexInput(0, 1, &vbindings); + cb->draw(4); + + QRhiReadbackResult readResult; + QImage result; + readResult.completed = [&readResult, &result] { + result = QImage(reinterpret_cast<const uchar *>(readResult.data.constData()), + readResult.pixelSize.width(), readResult.pixelSize.height(), + QImage::Format_RGBA8888_Premultiplied); + }; + QRhiResourceUpdateBatch *readbackBatch = rhi->nextResourceUpdateBatch(); + readbackBatch->readBackTexture({ texture.data() }, &readResult); + cb->endPass(readbackBatch); + + rhi->endOffscreenFrame(); + + QVERIFY(!result.isNull()); + + if (impl == QRhi::Null) + return; + + // Flip with D3D and Metal because these have Y down in images. Vulkan does + // not need this because there Y is down both in images and in NDC, which + // just happens to give correct results with our OpenGL-targeted vertex and + // UV data. + if (rhi->isYUpInFramebuffer() != rhi->isYUpInNDC()) + result = std::move(result).mirrored(); + + // check a few points that are expected to match regardless of the implementation + QRgb white = qRgba(255, 255, 255, 255); + QCOMPARE(result.pixel(79, 77), white); + QCOMPARE(result.pixel(124, 81), white); + QCOMPARE(result.pixel(128, 149), white); + QCOMPARE(result.pixel(120, 189), white); + QCOMPARE(result.pixel(116, 185), white); + + QRgb empty = qRgba(0, 0, 0, 0); + QCOMPARE(result.pixel(11, 45), empty); + QCOMPARE(result.pixel(246, 202), empty); + QCOMPARE(result.pixel(130, 18), empty); + QCOMPARE(result.pixel(4, 227), empty); + + QVERIFY(qGreen(result.pixel(32, 52)) > 2 * qRed(result.pixel(32, 52))); + QVERIFY(qGreen(result.pixel(32, 52)) > 2 * qBlue(result.pixel(32, 52))); + QVERIFY(qGreen(result.pixel(214, 191)) > 2 * qRed(result.pixel(214, 191))); + QVERIFY(qGreen(result.pixel(214, 191)) > 2 * qBlue(result.pixel(214, 191))); +} + #include <tst_qrhi.moc> QTEST_MAIN(tst_QRhi) |