Details
-
Bug
-
Resolution: Fixed
-
P2: Important
-
6.5.3
-
-
cff5a49cc (dev), eb3529ea3 (6.7), 87d075f7b (6.6), 51886d7c9 (tqtc/lts-6.5), 1bd755465 (dev), 81581819c (6.7), 4f2c36dd4 (6.6), 294fb8e9b (tqtc/lts-6.5)
Description
Please use this code to reproduce.
#include <QtWidgets/QApplication> #include <QtWidgets/QWidget> #include <QtCore/QTimer> int main(int argc, char** argv) { // QT_WIDGETS_RHI is the suggested workaround to avoid re-creating native windows in Qt 6.5. // Windows: DX11 RHI. This is the default. Just to make sure DX11 is used. // All native windows will have a DX11 swapchain. qputenv("QT_WIDGETS_RHI", "1"); qputenv("QT_WIDGETS_RHI_BACKEND", "d3d11"); QApplication app(argc, argv); // The first top-level window with a native child. QWidget tlw1; tlw1.resize(640, 480); tlw1.setStyleSheet("QWidget { background-color: red; }"); // The child is a native window. QT_WIDGETS_RHI=1 so it's RHI flush. QWidget child(&tlw1); child.setGeometry(0, 0, 640, 480); child.setStyleSheet("QWidget { background-color: green; }"); child.winId(); // Wait for the child to show. RHI flush will create a DX11 swapchain for the child native window. // But the swap chain is owned by tlw1. QTimer::singleShot(1000, [&]() { // The second top-level window. QWidget* tlw2 = new QWidget(); tlw2->resize(640, 480); tlw2->setStyleSheet("QWidget { background-color: blue; }"); // Now reparent the native child from tlw1 into tlw2. child.setParent(tlw2); child.setGeometry(0, 0, 640, 480); // Show the second top-level window. tlw2->show(); // Qt will create a new DX11 swap chain for the native child window in tlw2. But there is already a // swap chain and it's not released. // Windows will return Access Denied error when calling CreateSwapChainForHwnd(). // Failed to create D3D11 swapchain: COM error 0x80070005: Access is denied. // Failed to create swapchain for window flushed with an RHI - enabled backingstore // Crash in RHI flush. }); tlw1.show(); return app.exec(); }
This can also be reproduced without any environment variable override
#include <QtWidgets/QApplication> #include <QtWidgets/QWidget> #include <QtCore/QTimer> #include <QtWebEngineWidgets/QWebEngineView> int main(int argc, char** argv) { QApplication app(argc, argv); // The first top-level window with a native child. QWidget tlw1; tlw1.resize(640, 480); tlw1.setStyleSheet("QWidget { background-color: red; }"); // The child is a native window. QWidget child(&tlw1); child.setGeometry(0, 0, 640, 480); child.setStyleSheet("QWidget { background-color: green; }"); child.winId(); // This will cause both tlw and the native child to be RHI flush. QWebEngineView web(&child); web.setGeometry(0, 0, 640, 480); web.setUrl(QUrl("chrome://gpu")); // Wait for the child to show. RHI flush will create a DX11 swapchain for the child native window. // But the swap chain is owned by tlw1. QTimer::singleShot(1000, [&]() { // The second top-level window. QWidget* tlw2 = new QWidget(); tlw2->resize(640, 480); tlw2->setStyleSheet("QWidget { background-color: blue; }"); // Now reparent the native child from tlw1 into tlw2. child.setParent(tlw2); child.setGeometry(0, 0, 640, 480); // Show the second top-level window. tlw2->show(); // Qt will create a new DX11 swap chain for the native child window in tlw2. But there is already a // swap chain and it's not released. // Windows will return Access Denied error when calling CreateSwapChainForHwnd(). // Failed to create D3D11 swapchain: COM error 0x80070005: Access is denied. // Failed to create swapchain for window flushed with an RHI - enabled backingstore // Crash in RHI flush. }); tlw1.show(); return app.exec(); }
The previous swap chain is not released. Even all references are released, the swap chain will not be removed immediately. FYI: https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devicecontext-flush#deferred-destruction-issues-with-flip-presentation-swap-chains
Attachments
Issue Links
- relates to
-
QTBUG-119221 The mainwindow will be recreated when add a QWebEngineView to it
-
- Closed
-
-
QTBUG-119760 Crash when dereferencing a deleted QRhi after native window is re-created
-
- Closed
-
For Gerrit Dashboard: QTBUG-120276 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
533140,2 | WIP: QTBUG-120276 | dev | qt/qtbase | Status: ABANDONED | -2 | 0 |
537476,4 | rhi: d3d11: Flush() when destroying a swapchain | dev | qt/qtbase | Status: MERGED | +2 | 0 |
537481,9 | widgets: Invalidate RHI swapchain when window moves to new top level | dev | qt/qtbase | Status: MERGED | +2 | 0 |
542343,2 | rhi: d3d11: Flush() when destroying a swapchain | 6.7 | qt/qtbase | Status: MERGED | +2 | 0 |
542521,2 | rhi: d3d11: Flush() when destroying a swapchain | 6.6 | qt/qtbase | Status: MERGED | +2 | 0 |
542601,2 | rhi: d3d11: Flush() when destroying a swapchain | tqtc/lts-6.5 | qt/tqtc-qtbase | Status: MERGED | +2 | 0 |
552662,3 | widgets: Invalidate RHI swapchain when window moves to new top level | tqtc/lts-6.5 | qt/tqtc-qtbase | Status: MERGED | +2 | 0 |
553128,2 | widgets: Invalidate RHI swapchain when window moves to new top level | 6.7 | qt/qtbase | Status: MERGED | +2 | 0 |
553157,1 | widgets: Invalidate RHI swapchain when window moves to new top level | 6.6 | qt/qtbase | Status: MERGED | +2 | 0 |