I. Motivation▲
C'est à partir de Qt 5.8 que l'on a commencé la recherche pour l'implémentation d'autres API graphiques qu'OpenGL. Jusqu'à maintenant, Qt Quick était le principal centre d'occupation des développeurs, sans impliquer les spécificités des plateformes ni être disponible sur seulement une seule plateforme ou système de fenêtre (comme Direct3D 12).
Comme montré dans le travail préparatoire pour notre test D3D12, commencer avec de telles API est facile :
- Récupérer le descripteur (handle) de la fenêtre (dans le cas de Windows, QWindow::winId() renvoie le descripteur) ;
- Ajouter votre code spécifique à votre plateforme pour le rendu ;
- Terminé !
Maintenant, la même chose est bien sûr possible avec Vulkan, le montrent divers projets variés sur GitHub et sur bien d'autres plateformes. Mais alors, quel est le point commun entre Qt GUI, les interfaces QPA et les extensions de plateforme ?
La situation devient en fait bien plus intéressante quand plusieurs plateformes entrent en jeu : l'intégration du système de fenêtrage avec Vulkan nécessite l'écriture d'un code spécifique à la plateforme, souvent dirigé depuis un ensemble de directives de préprocesseur ifdef.
Grâce à cela nous avons une API multiplateforme (Qt) qui permet de ne pas écrire soi-même une série de ifdef rébarbative.
À la place de cela :
QWindow
*
window;
#if defined(VK_USE_PLATFORM_WIN32_KHR)
VkWin32SurfaceCreateInfoKHR createInfo;
createInfo.hwnd =
(HWND) window->
winId();
...
err =
vkCreateWin32SurfaceKHR(...);
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
VkWaylandSurfaceCreateInfoKHR createInfo;
...
err =
vkCreateWaylandSurfaceKHR(...);
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
VkAndroidSurfaceCreateInfoKHR createInfo;
...
err =
vkCreateAndroidSurfaceKHR(...)
#elif defined(VK_USE_PLATFORM_XCB_KHR)
VkXcbSurfaceCreateInfoKHR createInfo;
...
err =
vkCreateXcbSurfaceKHR(...)
#elif ...
nous avons quelque chose comme ça :
QWindow
*
window;
VkSurfaceKHR surface =
QVulkanInstance
::
surfaceForWindow(window);
Le système de fenêtrage spécifique est maintenant correctement géré dans les extensions de plateforme Qt. Il n'y a plus de ifdef.
Le second facteur de motivation très important est le test de D3D12, qui a montré que beaucoup d'applications s'accommodent d'un haut niveau d'abstraction, comme QD3D12Window, suivant l'exemple de QOpenGLWindow. Elles sont intrinsèquement limitées à certains égards, mais évitent de partir de zéro avec QWindow (et jongler avec les ifdef comme dans l'exemple précédent…).
Utiliser QWindow directement restera toujours la manière la plus puissante de procéder, cela vous donnant les pleins contrôles de votre application, mais, comme nous le verrons plus tard, faire un Vulkan stable basé sur QWindow de manière présentable est quelque chose de difficile (pensez aux chaînes de tampons, à exposeEvent(), au redimensionnement, à QPlatformSurfaceEvent, etc.). D'où l'introduction de QVulkanWindow.
II. Ses possibilités et ses limites▲
Avant de s'intéresser aux nouvelles classes QVulkan* en détail, il faut clarifier ce que Qt 5.10 offrira vraiment pour Vulkan :
- Qt 5.10 permet aux applications d'effectuer un rendu Vulkan multiplateforme dans un QWindow et avec le confort des sous-classes QVulkanWindow ;
- Excepté la simplification des spécificités de fenêtrage système, une surcouche mince est fournie pour les instances Vulkan et les fonctions spécifiques de Vulkan 1.0 ;
- L'API Vulkan n'est en aucun cas simplifiée. Qt fait seulement ce qu'il devrait en tant que bibliothèque graphique multiplateforme, par exemple aider avec le fenêtrage, les spécificités des plateformes, les résolutions de fonctions pour le cœur de l'API, mais pas plus que ça ;
- Les classes QWindows basées sur Vulkan peuvent être combinées avec les interfaces basées sur QWidget en utilisant QWidget::createWindowContainer(). Il n'y a pas de différences avec les fenêtres utilisant OpenGL. Ce sont de très bonnes nouvelles pour le développement d'applications 3D avec QWidget, puisqu'il y a maintenant une alternative Vulkan à QGLWidget/QWindow/QOpenGLWindow ;
- Vulkan n'est pas actuellement présent dans des modules comme Qt Quick, Qt 3D, Qt Canvas 3D, le rendu par OpenGL dans QPainter, la bibliothèque graphique basée sur QOpenGLWidget/QQuickWidget, etc. ;
- Peut-être en introduira-t-on certains dans le support Vulkan, toutefois ce n'est pas dans les objectifs de Qt 5.10.
III. Plateformes▲
Quelles sont donc les plateformes gérées ?
En ce qui concerne Qt 5.10, la situation est la suivante :
- Windows (version de bureau, pas WinRT) : quand le SDK LunarG est installé et que la variable d'environnement VULKAN_SDK est définie, Vulkan sera automatiquement activé lors de la compilation de Qt ;
- Linux (seulement xcb pour le moment ; la plateforme Wayland sera gérée plus tard) : il est activé dès que les en-têtes Vulkan sont détectés ;
- Android (testé sur les API niveaux 23 et 24 ; notez que les en-têtes Vulkan et toutes ses fonctions sont seulement présents au niveau 24 et pour les versions de NDK plus récentes).
Notez que Vulkan ne dépend pas de la liaison à une bibliothèque Vulkan,0 puisque Qt fait tout à l'exécution.
Par conséquent, la seule chose dont vous avez besoin, c'est un pack d'en-têtes Vulkan récent (de préférence, au moins la version 1.0.13).
Voici pour la partie 1. Restez à l'écoute pour la partie 2, où nous ferons un peu de pratique.
IV. Remerciements▲
Au nom de toute l'équipe Qt, j'aimerais adresser le plus grand remerciement à KDAB pour nous avoir autorisés à traduire cet article !
Je tiens à remercier Thibaut Cuvelier pour ses conseils et relectures.