diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-10-03 14:28:23 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-10-09 15:15:05 +0000 |
commit | 89ec1b3618f0f26a8f92049aabfc2df4d84c34c5 (patch) | |
tree | 1432a975da140b93d737d9dde865ed4c4864427b /tests/auto/gui | |
parent | 4a3ee77f650868ba408827d9793e8b86a93400f0 (diff) |
rhi: Add support for buffer readbacks
This also marks the beginnings of significantly extending autotesting
of the resource and rendering functionality in QRhi.
Also involves fixing up the buffer operation lists like we did
for textures before. This is to ensure updates and reads on the
same batch execute in the correct order. So just have two lists:
one with buffer, one with texture operations.
Also simplify the struct layouts. No need for those inner structs
with many duplicate members. This reduces the size even, since using a
union was never an option here. Also switch to a VLA, the size is around
253 KB per batch.
The Null backend now keeps track of the QRhiBuffer data so it can return
valid results in readbacks.
Task-number: QTBUG-78984
Task-number: QTBUG-78986
Task-number: QTBUG-78971
Task-number: QTBUG-78883
Change-Id: I9694bd7fec523a4e71cf8a5c77c828123ebbb3bd
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'tests/auto/gui')
-rw-r--r-- | tests/auto/gui/rhi/qrhi/tst_qrhi.cpp | 109 |
1 files changed, 108 insertions, 1 deletions
diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp index ac64cf5265..409152db0d 100644 --- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp +++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp @@ -71,6 +71,8 @@ private slots: void create(); void nativeHandles_data(); void nativeHandles(); + void resourceUpdateBatchBuffer_data(); + void resourceUpdateBatchBuffer(); private: struct { @@ -103,9 +105,26 @@ void tst_QRhi::initTestCase() #endif #ifdef TST_VK +#ifndef Q_OS_ANDROID + vulkanInstance.setLayers({ QByteArrayLiteral("VK_LAYER_LUNARG_standard_validation") }); +#else + vulkanInstance.setLayers({ QByteArrayLiteral("VK_LAYER_GOOGLE_threading"), + QByteArrayLiteral("VK_LAYER_LUNARG_parameter_validation"), + QByteArrayLiteral("VK_LAYER_LUNARG_object_tracker"), + QByteArrayLiteral("VK_LAYER_LUNARG_core_validation"), + QByteArrayLiteral("VK_LAYER_LUNARG_image"), + QByteArrayLiteral("VK_LAYER_LUNARG_swapchain"), + QByteArrayLiteral("VK_LAYER_GOOGLE_unique_objects") }); +#endif + vulkanInstance.setExtensions(QByteArrayList() + << "VK_KHR_get_physical_device_properties2"); vulkanInstance.create(); initParams.vk.inst = &vulkanInstance; #endif + +#ifdef TST_D3D11 + initParams.d3d.enableDebugLayer = true; +#endif } void tst_QRhi::cleanupTestCase() @@ -248,7 +267,9 @@ void tst_QRhi::create() QRhi::WideLines, QRhi::VertexShaderPointSize, QRhi::BaseVertex, - QRhi::BaseInstance + QRhi::BaseInstance, + QRhi::TriangleFanTopology, + QRhi::ReadBackNonUniformBuffer }; for (size_t i = 0; i <sizeof(features) / sizeof(QRhi::Feature); ++i) rhi->isFeatureSupported(features[i]); @@ -484,5 +505,91 @@ void tst_QRhi::nativeHandles() } } +void tst_QRhi::resourceUpdateBatchBuffer_data() +{ + rhiTestData(); +} + +void tst_QRhi::resourceUpdateBatchBuffer() +{ + 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 resource updates"); + + const int bufferSize = 23; + const QByteArray a(bufferSize, 'A'); + const QByteArray b(bufferSize, 'B'); + + // dynamic buffer, updates, readback + { + QScopedPointer<QRhiBuffer> dynamicBuffer(rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, bufferSize)); + QVERIFY(dynamicBuffer->build()); + + QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch(); + QVERIFY(batch); + + batch->updateDynamicBuffer(dynamicBuffer.data(), 10, bufferSize - 10, a.constData()); + batch->updateDynamicBuffer(dynamicBuffer.data(), 0, 12, b.constData()); + + QRhiBufferReadbackResult readResult; + bool readCompleted = false; + readResult.completed = [&readCompleted] { readCompleted = true; }; + batch->readBackBuffer(dynamicBuffer.data(), 5, 10, &readResult); + + QRhiCommandBuffer *cb = nullptr; + QRhi::FrameOpResult result = rhi->beginOffscreenFrame(&cb); + QVERIFY(result == QRhi::FrameOpSuccess); + QVERIFY(cb); + cb->resourceUpdate(batch); + rhi->endOffscreenFrame(); + + // Offscreen frames are synchronous, so the readback must have + // completed at this point. With swapchain frames this would not be the + // case. + QVERIFY(readCompleted); + QVERIFY(readResult.data.size() == 10); + QCOMPARE(readResult.data.left(7), QByteArrayLiteral("BBBBBBB")); + QCOMPARE(readResult.data.mid(7), QByteArrayLiteral("AAA")); + } + + // static buffer, updates, readback + { + QScopedPointer<QRhiBuffer> dynamicBuffer(rhi->newBuffer(QRhiBuffer::Static, QRhiBuffer::VertexBuffer, bufferSize)); + QVERIFY(dynamicBuffer->build()); + + QRhiResourceUpdateBatch *batch = rhi->nextResourceUpdateBatch(); + QVERIFY(batch); + + batch->uploadStaticBuffer(dynamicBuffer.data(), 10, bufferSize - 10, a.constData()); + batch->uploadStaticBuffer(dynamicBuffer.data(), 0, 12, b.constData()); + + QRhiBufferReadbackResult readResult; + bool readCompleted = false; + readResult.completed = [&readCompleted] { readCompleted = true; }; + + if (rhi->isFeatureSupported(QRhi::ReadBackNonUniformBuffer)) + batch->readBackBuffer(dynamicBuffer.data(), 5, 10, &readResult); + + QRhiCommandBuffer *cb = nullptr; + QRhi::FrameOpResult result = rhi->beginOffscreenFrame(&cb); + QVERIFY(result == QRhi::FrameOpSuccess); + QVERIFY(cb); + cb->resourceUpdate(batch); + rhi->endOffscreenFrame(); + + if (rhi->isFeatureSupported(QRhi::ReadBackNonUniformBuffer)) { + QVERIFY(readCompleted); + QVERIFY(readResult.data.size() == 10); + QCOMPARE(readResult.data.left(7), QByteArrayLiteral("BBBBBBB")); + QCOMPARE(readResult.data.mid(7), QByteArrayLiteral("AAA")); + } else { + qDebug("Skipping verifying buffer contents because readback is not supported"); + } + } +} + #include <tst_qrhi.moc> QTEST_MAIN(tst_QRhi) |