summaryrefslogtreecommitdiffstats
path: root/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2021-07-27 19:42:27 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2021-08-02 14:35:33 +0200
commitb594374ba84da986c5ebc93984961040338465d0 (patch)
tree41880eaf968ce0c5be934612a71edc61b0dbab58 /tests/auto/gui/rhi/qrhi/tst_qrhi.cpp
parentee68257b61268ef8f5f4c9b4090d8a1624cd98ce (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.cpp49
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)