mafulechkaOct. 4, 2019, 4 a.m.

Running Qt Quick on Vulkan, Metal and Direct3D - Part 2

Let's pick up where we left off in the first article. An example of a Qt Quick application running on Linux on top of OpenGL and Vulkan was considered. We also saw the Vulkan frame capture in RenderDoc, which is not only an invaluable tool when developing Qt, but can also be useful to anyone who wants to dig deeper and better understand how Qt Quick renders a frame (or troubleshoot issues in application rendering). Now in this article, let's focus on what Qt 5.14 offers for macOS and Windows.

Metal on macOS

Not surprisingly, running the qt5-cinematic-experience demo with QSG_RHI=1 (and QSG_INFO=1) on macOS 10.13 or 10.14 results in:

qt.scenegraph.general: Using QRhi with backend Metal
  graphics API debug/validation layers: 0
  QRhi profiling and debug markers: 0
qt.scenegraph.general: threaded render loop
qt.scenegraph.general: Using sg animation driver
qt.scenegraph.general: Animation Driver: using vsync: 16.67 ms
qt.rhi.general: Metal device: Intel(R) HD Graphics 615
qt.scenegraph.general: MSAA sample count for the swapchain is 1. Alpha channel requested = no.
qt.scenegraph.general: rhi texture atlas dimensions: 4096x2048
qt.rhi.general: got CAMetalLayer, size 2560x1440

In line with Qt 6's goal to default to the core, most supported platform graphics API (while still allowing applications to set their own preferences if they so choose), by enabling a QRhi-based rendering path in Qt Quick on macOS, Metal is the default.

Just as the Vulkan-based rendering path builds on the Vulkan sample and surface support introduced to the QtGui module, QPA, and some platform plugins, the Metal QRhi backend relies on the Metal support for the cocoa platform plugin that appeared around Qt 5.12. QWindow with QSurface::MetalSurface gets an NSView backed by CAMetalLayer under the hood. This is exactly what the Metal QRhi backend needs (this all works because QQuickWindow gets the appropriate QSurface::SurfaceType set whenever a QRhi-based code path is active).

One important feature here is the ability to work with Qt Quick's multi-threaded render loop. This is very welcome because due to multithreading issues with some NSOpenGLContext and related APIs in macOS 10.14, Qt disables multithreaded looping with OpenGL on macOS, defaulting to the base loop instead. This results in somewhat reduced animation smoothness in Qt Quick. As for Metal, developers don't (according to current knowledge) have any problem setting threads, so one can once again use the default multi-threaded render loop (the default selection for the render loop can be changed by setting the QSG_RENDER_LOOP environment variable, this variable is supported also in combination with QSG_RHI)

RenderDoc has already been mentioned as a tool for debugging Qt application frame rendering when running on OpenGL, Vulkan, or Direct3D. For Metal, you can use XCode and the built-in GPU frame capture.

One useful way to quickly open a Qt project in XCode ready for debugging is to run make xcodeproj && open .xcodeproj (or qmake -spec macx-xcode* if qmake has not already been started) from a terminal. Pressing Cmd-R immediately launches the debugger. Developers also often use this during Qt development. In case Metal GPU capture is not available, even if Qt Quick is configured to render via Metal, select Product -> Scheme -> Edit scheme ... and change GPU Frame Capture to Metal.

When you run a debug build of your application, XCode will have Metal checking enabled, which means that XCode will (hopefully) issue a useful warning and abort program execution if the Metal API is used in any way that is not correct. Unlike other platforms, Metal API validation cannot be enabled unless debugging through XCode (so, unlike Vulkan and D3D, setting QSG_RHI_DEBUG_LAYER will have no effect).

Metal on iOS

What about iOS or tvOS?

Well, at the time of writing, there is no Metal related plugin in the platform plugin, which also means that the Metal QRhi backend has not yet been tested on those platforms. This is why the Qt 5.14 New Features page only mentions macOS in the Qt Quick section. Support is expected to be added in the near future, possibly in version 5.15.

Volcano on macOS

How about Vulkan via MoltenVK?

As mentioned in Part 1, requesting to render through Vulkan and then using MoltenVK to translate SPIR-V API calls and shaders at runtime into Metal and Metal Shading Language is also possible. This requires building Qt with Vulkan support, which cannot be said about ready-made solutions on Apple platforms. The key is to pass -I and to set up and make sure libraries can be found at runtime, perhaps by setting QT_VULKAN_LIB.

It is important to note that this approach will only be supported on a best effort basis. The primary supported rendering on Apple platforms will be via Metal.

Running the demo application with QSG_RHI_BACKEND=vulkan (using an appropriately configured Qt 5.14 build) yields:

qt.scenegraph.general: Using QRhi with backend Vulkan
  graphics API debug/validation layers: 0
  QRhi profiling and debug markers: 0
qt.scenegraph.general: threaded render loop
qt.scenegraph.general: Using sg animation driver
qt.scenegraph.general: Animation Driver: using vsync: 16.67 ms
qt.rhi.general: Physical device 0: 'Intel(R) UHD Graphics 630' 0.2.1835 (api 1.0.92 vendor 0x8086 device 0x3E9B type 1)
qt.rhi.general: using this physical device
qt.rhi.general: queue family 0: flags=0x7 count=1
qt.rhi.general: 17 device extensions available
qt.scenegraph.general: MSAA sample count for the swapchain is 1. Alpha channel requested = no.
qt.scenegraph.general: rhi texture atlas dimensions: 2048x1024
qt.rhi.general: Creating new swapchain of 2 buffers, size 1280x720, presentation mode 2

It's worth noting that there were issues running this on macOS 10.13, blocking and crashing when using a multi-threaded render loop. Upgrading to the newer (1.0.121) Vulkan SDK (including MoltenVK) resulted in a new set of issues and an inability to launch the application.


Windows is the platform with the most features. Of the 4 main QRhi backends (Vulkan, Metal, D3D11, OpenGL), at least 3 can be used on Windows: Direct3D 11, Vulkan and OpenGL.

This begs the obvious question: why only 3? Shouldn't it be 4 with Direct3D 12?

There is currently no D3D12 backend. This may change later as it is in the plans but not at this time. It's worth noting that the experimental D3D12 backend for Qt Quick added in Qt 5.8 is now architecturally deprecated (because the developers handle the problem of multiple graphics APIs in a completely new way), and is due to be removed in Qt 6.

On Windows, by default setting QSG_RHI=1 uses Direct3D 11. As usual, override with QSG_RHI_BACKEND if Vulkan or OpenGL is required.

qt.scenegraph.general: Using QRhi with backend D3D11
  graphics API debug/validation layers: 0
  QRhi profiling and debug markers: 0
qt.scenegraph.general: threaded render loop
qt.scenegraph.general: Using sg animation driver
qt.scenegraph.general: Animation Driver: using vsync: 16.67 ms
qt.rhi.general: DXGI 1.2 = true, FLIP_DISCARD swapchain supported = true
qt.rhi.general: Adapter 0: 'NVIDIA GeForce RTX 2060' (flags 0x0)
qt.rhi.general: using this adapter
qt.rhi.general: Adapter 1: 'Microsoft Basic Render Driver' (flags 0x2)
qt.scenegraph.general: MSAA sample count for the swapchain is 1
qt.scenegraph.general: rhi texture atlas dimensions: 2048x1024

It's worth noting that you need Direct3D 11.1, not 11.0. This is mainly because VSSetConstantBuffers1 is needed
(and related PS and CS variants). This shouldn't be a problem if someone doesn't want to run plain Windows 7 without a platform upgrade. Speaking of Windows 7, it's important to note that D3D11 based rendering does not currently work correctly on Windows 7 with Qt 5.14, so the 5.14 new features page only mentions Windows 10. This will be fixed later (but only if Windows 7 remains a supported platform). for Qt 6).

To enable the Direct3D debug layer, set the QSG_RHI_DEBUG_LAYER environment variable to 1. This also works for Vulkan if inspection layers are available (for example, from the installed Vulkan SDK). Qt conveniently routes messages to debug output (as if they were output via qDebug).

Vulkan and OpenGL should work as expected on Windows.

As with Vulkan and Metal, the OpenGL QRhi backend relies on some (but not all) of the existing OpenGL activators and platform tracking, such as QOpenGLContext, QOpenGLFunctions and in the Windows platform plugin (WGL, EGL). Therefore, everything related to Qt Quick applications running directly in OpenGL applies here as well (desktop (desktop) vs. ANGLE vs. software, environment variables like QT_OPENGL).

Speaking of ANGLE, it is expected that it may be removed as a direct dependency in Qt 6. This needs further study to fully ensure that support for special use cases is not lost, but for now the plan is to have it based on QRhi rendering path with support for Direct3D 11, OpenGL (via WGL itself) and Vulkan will suffice for Qt 6 applications on Windows.

The third part will look at what QRhi is and how shaders work.

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Support the author Donate


Only authorized users can post comments.
Please, Log in or Sign up

Let me recommend you a great European Fornex hosting.

Fornex has proven itself to be a stable host over the years.

For Django projects I recommend VPS hosting

Following the link you will receive a 5% discount on shared hosting services, dedicated servers, VPS and VPN

View Hosting

C++ - Test 001. The first program and data types

  • Result:66points,
  • Rating points-1
  • korsar
  • Nov. 23, 2022, 8:57 a.m.

C++ - Test 005. Structures and Classes

  • Result:50points,
  • Rating points-4

C++ - Тест 003. Условия и циклы

  • Result:78points,
  • Rating points2
Last comments

GameDev on Qt - Tutorial 5. The explosion of bullets using sprite images

Если вдруг кто-то прочитает.... Скачал проект, скомпилил, запустил. Всё красиво и объектно ориентировано, но вот FPS дико страдает, когда появляется 10+ врагов. Может есть какие-то надстрой…
  • juvf
  • Nov. 25, 2022, 12:14 a.m.

Qt/C++ - Lesson 051. QMediaPlayer – simple audio player

Добрый день. Подскажите, как можно перехватить в Qt или Qml уровень воспроизводимого звука? Т.е. требуется сделать виртуальный винтажный индикатор (стрелочный или светодиодный), который бы …
  • juvf
  • Nov. 3, 2022, 3:20 a.m.

QML - Lesson 007. ListView. Dynamic creation and deletion of elements

Добрый день. Очень полезная статья. Спасибо. Вопрос такой: 1) нужно "взять" кнопку 2 пальцем (прикаснулись пальцем к кнопке 2, держим, через 2-3 кнопка оторвалась от ListView) и пере…

PyQt5 - Lesson 007. Works with QML QtQuick (Signals and slots)

А можно ли из QML сделать привязку свойства к свойству пайтоновского объекта? Ну, т.е. , например, у нашего объекта Calculator обхвялем свойства sumresult и subresult c с декоратором @pyqtProp…

Python Image Recognition with TensorFlow and Keras

А что собственно выводит программа, как вывести то что она смогла распознать?
Now discuss on the forum

Sorting the added QML elements in the ListModel

I am writing an alarm clock in QML, I am required to sort the alarms in ascending order (depending on the date or time (if there are several alarms on the same day). I've done the sorting …

Как добавить в скрипт размер каждого файла в Мб ?

IDLE (Python 3.10 64-bit) Win 10 Есть такой скрипт: Поиск перечня файлов в папке и запись списка: import ospath = 'E:\Мой Python\__Видеокурсы Python'rez = sorted(os.listdir(pa…
  • nkly
  • Oct. 18, 2022, 9:14 a.m.

Как сохранить данные древовидной модели на основе QStandardItemModel в файл

Вы меня неправильно поняли. Допустим я собираю кулинарные рецепты и один из них - рецепт супа Харчо. Структура файла данных такова: { node:Рецепт супа Харчо parent:Вкусные блюда, …

Вопрос по Qt Creator

Добрый день. Не знаю, подобную проблему я не решал.

Задать другой класс div-у

Добрый день. Попробуйте использовать Selenium. Это библиотека есть в виде Python модуля и она позволяет загружать страницу и манипулировать html элементами. Как я понимаю, в ней можно…
© EVILEG 2015-2022
Recommend hosting TIMEWEB