summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qbackingstorerhisupport.cpp
Commit message (Collapse)AuthorAgeFilesLines
* rhi: Don't fall back to OpenGL backingstore if Metal is not availableTor Arne Vestbø2024-05-231-2/+2
| | | | | | | | | | | | | We were reusing the QRhiMetalInitParams when falling back to OpenGL, which caused crashes at runtime. We remove the fallback altogether, as tests or clients that rely on a specific RHI backingstore backend should do feature-testing before requesting the specific backend. Pick-to: 6.7 Change-Id: Iee38348ae06ea118aafcada33a8956ae07bb2228 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
* widgets: Invalidate RHI swapchain when window moves to new top levelTor Arne Vestbø2024-04-041-3/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When a QWidget with an associated RHI swapchain (via its QWindow) is moved to a different top level window, that top level window has its own backing store, and QBackingStoreRhiSupport, which doesn't know anything about the fact that the window already has an associated swap chain in the original top level window's QBackingStoreRhiSupport. As having multiple swap chains for the same window is not supported on all RHI backends (Vulkan and DX in particular), we need to throw away the swap chain when detecting that the window is moved to a new top level. We do this by hooking into the existing WindowAboutToChangeInternal event delivery to renderToTexture children, which now delivers the event both to renderToTexture QWidget children as well as QWindows in the hierarchy. The condition of when to deliver the event has been updated to reflect whether the top level uses RHI for flushing, instead of only including renderToTexture children, as the former also includes setting QT_WIDGETS_RHI=1 explicitly. The event is then caught by QBackingStoreRhiSupportWindowWatcher, and handled the same way as for SurfaceAboutToBeDestroyed. Renaming qSendWindowChangeToTextureChildrenRecursively would make sense at this point, but to make cherry-picks easier we keep the current name for now. Fixes: QTBUG-120276 Pick-to: 6.7 6.5 Change-Id: Ic4c60e89be985f12a84e9f893c299e602b70851a Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
* Add configure feature for MetalTor Arne Vestbø2024-03-191-3/+3
| | | | | | | Simplifies maintenance of code paths that rely on Metal. Change-Id: I1d1f705fffc14dbafde346eeb555b43be6d5be54 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
* Sync also the profile env.var between Quick and RHI backingstoresLaszlo Agocs2023-10-161-2/+5
| | | | | | | | | Amends ffb857e9d0745fdd31bca091333f1120c5857d7b. Pick-to: 6.6 6.5 Task-number: QTBUG-118116 Change-Id: Ifb55130fd66b8ea1446363ae22f11cfe4f4d48bb Reviewed-by: Christian Strømme <christian.stromme@qt.io>
* Sync rhi backingstore d3d12 behavior with QuickLaszlo Agocs2023-09-191-1/+7
| | | | | | | | | | | | When adding the D3D12 code path in widgets it seems it was ignored that the retry-with-WARP logic was present both for D3D11 and 12 in Qt Quick. For consistency, the same logic must be used. Right now widgets only has the retry logic for D3D11. Pick-to: 6.6 Change-Id: I08d5728acfb9a68db7e0a4b0477050f08546ffac Reviewed-by: Christian Strømme <christian.stromme@qt.io>
* Sync rhi backingstore prefer-software env.var with QuickLaszlo Agocs2023-09-181-0/+5
| | | | | | | | | | | | | Behaving differently in QQuickWindow vs. a QRhi-based widget window is not great for WebEngine. The env.var naming is not the best (QSG prefix) but we already have some precedent for this (recognizing QSG_INFO in QRhi), and there is no other choice anyway. Pick-to: 6.6 6.5 6.6.0 6.5.3 Task-number: QTBUG-116445 Change-Id: Ibfd495cbd1d42502441d6629325bdeb033e813f3 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
* Handle Null rhi backend in backingstoreLaszlo Agocs2023-07-311-0/+5
| | | | | | | | Was missing for some reason when this got added in 6.4. Pick-to: 6.6 6.5 Change-Id: I4f8b780c7119649688d8d8a197e8ef59730b0b61 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* rhi: Make it a QPA-style private but semi-public APILaszlo Agocs2023-05-211-11/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | qrhi.h, qshader.h, qshaderdescription.h (and qshaderbaker.h from shadertools; done separately) become "RHI APIs", following the concept of QPA APIs. Mirror completely what is done for QPA headers, but using the "rhi" prefix for the headers. This involves updating syncqt to handle the new category of headers. (a note on the regex: matching everything starting with "qrhi" is not acceptable due to incorrectly matching existing and future headers, hence specifying the four header names explicitly) There is going to be one difference to QPA: the documentation for everything RHI is going to be public and part of the regular docs, not hidden with \internal. In addition to the header renaming and adding the comments and documentation notes and warnings, there is one significant change here: there is no longer a need to do API-specific includes, such as qrhid3d11[_p].h, qrhivulkan[_p].h, etc. These are simply merged into a single header that is then included from qrhi.h. This means that users within Qt, and any future applications can just do #include <rhi/qrhi.h> (or rhi/qshader.h if the QRhi stuff is not relevant), no other headers are needed. There are no changes to functionality in this patch. Only the documentation is expanded, quite a lot, to eliminate all qdoc warnings and make the generated API docs complete. An example, with a quite extensive doc page is added as well. Task-number: QTBUG-113331 Change-Id: I91c749826348f14320cb335b1c83e9d1ea2b1d8b Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* rhi: widgets: Try sw adapter if D3D11 init failsLaszlo Agocs2023-03-211-0/+6
| | | | | | | | | | | | | | | | | create() for D3D11 performs a smoke test with creating a vertex shader to ensure the created graphics device is actually usable for Qt's purposes. When this fails, create() returns false. Qt Quick automatically retries with the PreferSoftwareRenderer flag which causes picking up the WARP device ("Microsoft Basic Render Driver"). Synchronize this behavior to the QRhi-based backing store so that widget apps using QQuickWidget (or anything running QT_WIDGETS_RHI=1) get this same behavior out of the box. Pick-to: 6.5 6.4 Change-Id: Idff795401dbed8ba465102d075808010d421d34e Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* rhi: Add D3D12 supportLaszlo Agocs2023-02-071-4/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - The optional nice-to-haves DebugMarkers, Timestamps, PipelineCache are not yet implemented (features reported as false, to be implemented later, although buffer/texture resource name setting already works as-is, regardless of DebugMarkers). - Mipmap generation for 3D textures is missing. Won't matter much given that 3D textures are not used in Qt for anything atm. For generating mipmaps for 2D (or 2D array) textures, the MiniEngine compute shader and approach is used. 3D support for the mipmap generator may be added later. 1D textures / arrays are supported except for mipmap generation, and so the OneDimensionalTextureMipmaps feature is reported as false. - Qt Quick and Qt Quick 3D are expected to be fully functional. (unforeseen issues are not impossible, of course) - Uses minimum feature level 11.0 when requesting the device. It is expected to be functional on resource binding tier 1 hardware even, although this has not been verified in practice. - 2 frames in flight with the usual resource buffering (QRhiBuffer::Dynamic is host visible (UPLOAD) and always mapped and slotted, other buffers and textures are device local (DEFAULT). Requests 3 swapchain buffers. Swapchains are mostly like with D3D11 (e.g. FLIP_DISCARD and SCALING_NONE). - The root signature generation is somewhat limited by the SPIR-V binding model and that we need to map every binding point using the nativeResourceBindingMap from the QShader. Thus the root signature is laid out so each stage has its own set of resources, with shader register clashes being prevented by setting the visibility to a given stage. Sampler handling is somewhat suboptimal but we are tied by the binding model and existing API design. It is in a fairly special situation due to the 2048 limit on a shader visible sampler heap, as opposed to 1000000 for SRVs and UAVS, so the approach we use for textures (just stage the CPU SRVs on the (per-frame slot) shader visible heap as they are encountered, effectively treating the heap as a ring buffer) would quickly lead to having to switch heaps many times with scenes with many draw calls and sampledTexture/sampler bindings in the srb. Whereas static samplers, which would be beautiful, are impossible to utilize safely since we do not have that concept (i.e. samplers specified upfront, tied to the graphics/compute pipeline) in the QRhi API, and an srb used at pipeline creation may change its associated resources, such as the QRhiSampler reference, by the time the shader resources are set for the draw call (or another, compatible srb may get used altogether), so specifying the samplers at root signature creation time is impossible. Rather, the current approach is to treat each sampler as a separate root parameter (per stage) having a descriptor table with a single entry. The shader visible sampler heap has exactly one instance of each unique sampler encountered during the lifetime of the QRhi. - Shader-wise no different from D3D11, works with HLSL/DXBC 5.0 (i.e. existing .qsb files with DXBC in them work as-is). But unlike D3D11, this one will try to pick 6.7, 6.6, ..., down to 5.0 from the QShader, in that order. - Uses D3D12MA for suballocating. As a result it can report vmem allocation statistics like the Vulkan backend, and it does more since the DXGI memory usage (incl. implicit resources) is also reported. This is optional technically, so we also have the option of going straight with the heavyweight CreateCommittedResource() instead. That is what we do if the adapter chosen reports it's software-based or when QT_D3D_NO_SUBALLOC=1 is set. - PreferSoftwareRenderer (picking the WARP device) and the env.var. QT_D3D_ADAPTER_INDEX work as with the D3D11 backend. - It is not unexpected that with large scenes that generate lots of draw calls with multiple textures/samplers per call the performance may be slightly below D3D11 (probably mostly due to descriptor management). Similarly, the reported memory usage will be higher, which is partly natural due to creating heaps, descriptor pools, staging areas, etc. upfront. Will need to be evaluated later how these can be tuned. Change-Id: I5a42580bb65f391ebceaf81adc6ae673cceacb74 Reviewed-by: Andy Nichols <andy.nichols@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Remove unused internal rhi backingstore parametersLaszlo Agocs2022-11-101-1/+0
| | | | | | | | | | | | | There is no user for these at this point: QOpenGLWidget does not need any of these by nature, whereas QQuickWidget is also currently in the works-as-is category, it has no need to communicate the need for additional Vulkan device extensions for example. Pick-to: 6.4 Task-number: QTBUG-108277 Change-Id: Idc09552027377a21a0e904fbb9bfbd95c3d0e0a1 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* rhi: Make it possible to query the backend name beforehandLaszlo Agocs2022-07-051-20/+1
| | | | | | | | | | | | | | | | The goal is to make it possible to implement QSGRhiSupport::backendName() in Qt Quick with just a single line: return QString::fromUtf8(QRhi::backendName(m_rhiBackend)); instead of duplicating the strings and the logic. Similarly, QBackingStoreRhiSupport can now drop its apiName() helper entirely. Change-Id: Ia8cbb1f1243539ed4d7a98e71dcc2ed56b017e40 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* Use SPDX license identifiersLucie Gérard2022-05-161-38/+2
| | | | | | | | | | | | | Replace the current license disclaimer in files by a SPDX-License-Identifier. Files that have to be modified by hand are modified. License files are organized under LICENSES directory. Task-number: QTBUG-67283 Change-Id: Id880c92784c40f3bbde861c0d93f58151c18b9f1 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
* Fix heap-use-after-free with rhi-based backingstoreLaszlo Agocs2022-03-291-2/+3
| | | | | | Task-number: QTBUG-102030 Change-Id: I6b05007c6ae3d653197c5680b9fc5768b0e3690f Reviewed-by: Michal Klocek <michal.klocek@qt.io>
* Compose render-to-texture widgets through QRhiLaszlo Agocs2022-03-111-0/+355
QPlatformTextureList holds a QRhiTexture instead of GLuint. A QPlatformBackingStore now optionally can own a QRhi and a QRhiSwapChain for the associated window. Non-GL rendering must use this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still rely on resource sharing between contexts. A widget tells that it wants QRhi and the desired configuration in a new virtual function in QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is evaluated (among a top-level's all children) upon create() before creating the repaint manager and the QWidgetWindow. In QOpenGLWidget what do request is obvious: it will request an OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget) will be more interesting: it needs to honor the standard Qt Quick env.vars. and QQuickWindow APIs (or, in whatever way the user configured the QRhiWidget), and so will set up the config struct accordingly. In addition, the rhiconfig and surface type is (re)evaluated when (re)parenting a widget to a new tlw. If needed, this will now trigger a destroy - create on the tlw. This should be be safe to do in setParent. When multiple child widgets report an enabled rhiconfig, the first one (the first child encountered) wins. So e.g. attempting to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same top-level window will fail one of the widgets (it likely won't render). RasterGLSurface is no longer used by widgets. Rather, the appropriate surface type is chosen. The rhi support in the backingstore is usable without widgets as well. To make rhiFlush() functional, one needs to call setRhiConfig() after creating the QBackingStore. (like QWidget does to top-level windows) Most of the QT_NO_OPENGL ifdefs are eliminated all over the place. Everything with QRhi is unconditional code at compile time, except the actual initialization. Having to plumb the widget tlw's shareContext (or, now, the QRhi) through QWindowPrivate is no longer needed. The old approach does not scale: to implement composeAndFlush (now rhiFlush) we need more than just a QRhi object, and this way we no longer pollute everything starting from the widget level (QWidget's topextra -> QWidgetWindow -> QWindowPrivate) just to send data around. The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split is all gone. Instead, there is a QBackingStoreDefaultCompositor in QtGui which is what the default implementations of composeAndFlush and toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs should continue working mostly as-is, apart from adapting to the texture list changes and getting the native OpenGL texture id out of the QRhiTexture) As QQuickWidget is way too complicated to just port as-is, an rhi manual test (rhiwidget) is introduced as a first step, in ordewr to exercise a simple, custom render-to-texture widget that does something using a (not necessarily OpenGL-backed) QRhi and acts as fully functional QWidget (modeled after QOpenGLWidget). This can also form the foundation of a potential future QRhiWidget. It is also possible to force the QRhi-based flushing always, regardless of the presence of render-to-texture widgets. To exercise this, set the env.var. QT_WIDGETS_RHI=1. This picks a platform-specific default, and can be overridden with QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be extended to query the platform plugin as well to check if the platform plugin prefers to always do flushes with a 3D API. QOpenGLWidget should work like before from the user's perspective, while internally it has to do some things differently to play nice and prevent regressions with the new rendering architecture. To exercise this better, the qopenglwidget example gets a new tab-based view (that could perhaps replace the example's main window later on?). The openglwidget manual test is made compatible with Qt 6, and gets a counterpart in form of the dockedopenglwidget manual test, which is a modified version of the cube example that features dock widgets. This is relevant in particular because render-to-texture widgets within a QDockWidget has its own specific quirks, with logic taking this into account, hence testing is essential. For existing applications there are two important consequences with this patch in place: - Once the rhi-based composition is enabled, it stays active for the lifetime of the top-level window. - Dynamically creating and parenting the first render-to-texture widget to an already created tlw will destroy and recreate the tlw (and the underlying window). The visible effects of this depend on the platform. (e.g. the window may disappear and reappear on some, whereas with other windowing systems it is not noticeable at all - this is not really different from similar situtions with reparenting or when moving windows between screens, so should be acceptable in practice) - On iOS raster windows are flushed with Metal (and rhi) from now on (previously this was through OpenGL by making flush() call composeAndFlush(). Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>