diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2021-07-27 19:42:27 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2021-08-02 14:35:33 +0200 |
commit | b594374ba84da986c5ebc93984961040338465d0 (patch) | |
tree | 41880eaf968ce0c5be934612a71edc61b0dbab58 /tests/auto/gui/rhi/qrhi/tst_qrhi.cpp | |
parent | ee68257b61268ef8f5f4c9b4090d8a1624cd98ce (diff) |
rhi: Be more graceful when one destroys a resource after the QRhi
One is a bad application or library in this case, but nonetheless
we should handle this more gracefully then just crashing due to
the QRhi already having been destroyed. Mainly because in Qt 5 one
could get away with the same: releasing OpenGL objects underneath,
for example, a QSGPlainTexture with no (or wrong) GL context did
not generate any user visible fatal errors. So we should not crash
in Qt 6 either with these code bases.
In debug builds or when QT_RHI_LEAK_CHECK is set, one will get the
unreleased resources warning printed in Qt 6, which is a step
forward compared to Qt 5. So there is still some indication that
something is badly designed, even if the application survives.
Task-number: QTBUG-95394
Pick-to: 6.2
Change-Id: I944f4f425ff126e7363a82aff926b280ccf1dfc3
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'tests/auto/gui/rhi/qrhi/tst_qrhi.cpp')
-rw-r--r-- | tests/auto/gui/rhi/qrhi/tst_qrhi.cpp | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp index 8b6f55b3b6..be825c8ac2 100644 --- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp +++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp @@ -137,6 +137,8 @@ private slots: void renderbufferImportOpenGL(); void threeDimTexture_data(); void threeDimTexture(); + void leakedResourceDestroy_data(); + void leakedResourceDestroy(); private: void setWindowType(QWindow *window, QRhi::Implementation impl); @@ -3985,5 +3987,52 @@ void tst_QRhi::threeDimTexture() } } +void tst_QRhi::leakedResourceDestroy_data() +{ + rhiTestData(); +} + +void tst_QRhi::leakedResourceDestroy() +{ + QFETCH(QRhi::Implementation, impl); + QFETCH(QRhiInitParams *, initParams); + + QScopedPointer<QRhi> rhi(QRhi::create(impl, initParams)); + if (!rhi) + QSKIP("QRhi could not be created, skipping"); + + // Incorrectly destroy the QRhi before the resources created from it. Attempting to + // destroy the resources afterwards is pointless, the native resources are leaked. + // Nonetheless, it should not crash, which is what we are testing here. + // + // We do not however have control over other, native and 3rd party components: a + // validation or debug layer, or a memory allocator may warn, assert, or abort when + // not releasing all native resources correctly. +#ifndef QT_NO_DEBUG + // don't want asserts from vkmemalloc, skip the test in debug builds + if (impl == QRhi::Vulkan) + QSKIP("Skipping leaked resource destroy test due to Vulkan and debug build"); +#endif + + QScopedPointer<QRhiBuffer> buffer(rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, 256)); + QVERIFY(buffer->create()); + + QScopedPointer<QRhiTexture> texture(rhi->newTexture(QRhiTexture::RGBA8, QSize(512, 512), 1, QRhiTexture::RenderTarget)); + QVERIFY(texture->create()); + + QScopedPointer<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ texture.data() })); + QScopedPointer<QRhiRenderPassDescriptor> rpDesc(rt->newCompatibleRenderPassDescriptor()); + QVERIFY(rpDesc); + rt->setRenderPassDescriptor(rpDesc.data()); + QVERIFY(rt->create()); + + if (impl == QRhi::Vulkan) + qDebug("Vulkan validation layer warnings may be printed below - this is expected"); + + rhi.reset(); + + // let the scoped ptr do its job with the resources +} + #include <tst_qrhi.moc> QTEST_MAIN(tst_QRhi) |