@@ -72,13 +72,18 @@ chargement. Lancez le code et vérifiez que votre carte graphique est capable de
7272la disponibilité de la queue de présentation implique que l'extension de la swap chain est supportée. Mais soyons
7373tout de mêmes explicites pour cela aussi.
7474
75- L'activation de l'extension ne requiert qu'un léger changement à la structure de création du logical device :
75+ ## Activation des extensions du device
76+
77+ L'utilisation de la swap chain nécessite l'extension ` VK_KHR_swapchain ` . Son activation ne requiert qu'un léger
78+ changement à la structure de création du logical device :
7679
7780``` c++
7881createInfo.enabledExtensionCount = static_cast <uint32_t >(deviceExtensions.size());
7982createInfo.ppEnabledExtensionNames = deviceExtensions.data();
8083```
8184
85+ Supprimez bien l'ancienne ligne ` createInfo.enabledExtensionCount = 0; ` .
86+
8287## Récupérer des détails à propos du support de la swap chain
8388
8489Vérifier que la swap chain est disponible n'est pas suffisant. Nous devons vérifier qu'elle est compatible avec notre
@@ -205,17 +210,7 @@ Pour l'espace de couleur nous utiliserons sRGB si possible, car il en résulte
205210compliqué donc nous utilserons un espace linéaire pour manipuler les couleurs. Le format le plus commun est
206211`VK_FORMAT_B8G8R8A8_UNORM`.
207212
208- Dans le meilleur des mondes la surface n'a pas de format préféré, ce que Vulkan indique en ne retournant qu'un seul
209- `VkSurfaceFormatKHR` dont la valeur du membre `format` est `VK_FORMAT_UNDEFINED`.
210-
211- ```c++
212- if (availableFormats.size() == 1 && availableFormats[0].format == VK_FORMAT_UNDEFINED) {
213- return {VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR};
214- }
215- ```
216-
217- Si nous ne pouvons choisir librement le format, nous itérerons toute la liste et choisirons la meilleure combinaison
218- pour nous si elle est disponible :
213+ Itérons dans la liste et voyons si le meilleur est disponible :
219214
220215```c++
221216for (const auto& availableFormat : availableFormats) {
@@ -230,9 +225,6 @@ prendrons le premier format disponible.
230225
231226``` c++
232227VkSurfaceFormatKHR chooseSwapSurfaceFormat (const std::vector<VkSurfaceFormatKHR >& availableFormats) {
233- if (availableFormats.size() == 1 && availableFormats[ 0] .format == VK_FORMAT_UNDEFINED) {
234- return {VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR};
235- }
236228
237229 for (const auto& availableFormat : availableFormats) {
238230 if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
@@ -267,15 +259,15 @@ Seul `VK_PRESENT_MODE_FIFO_KHR` est toujours disponible. Nous aurons donc encore
267259un choix, car le mode que nous choisirons préférentiellement est `VK_PRESENT_MODE_MAILBOX_KHR` :
268260
269261```c++
270- VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR> availablePresentModes) {
262+ VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR> & availablePresentModes) {
271263 return VK_PRESENT_MODE_FIFO_KHR;
272264}
273265```
274266
275267Je pense que le triple buffering est un très bon compromis. Vérifions si ce mode est disponible :
276268
277269``` c++
278- VkPresentModeKHR chooseSwapPresentMode (const std::vector<VkPresentModeKHR > availablePresentModes) {
270+ VkPresentModeKHR chooseSwapPresentMode (const std::vector<VkPresentModeKHR > & availablePresentModes) {
279271 for (const auto& availablePresentMode : availablePresentModes) {
280272 if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
281273 return availablePresentMode;
@@ -290,7 +282,7 @@ Malheuresement certains drivers ne supportent pas bien `VK_PRESENT_MODE_FIFO_KHR
290282`VK_PRESENT_MODE_IMMEDIATE_MODE` si `VK_PRESENT_MODE_MAILBOX_KHR` n'est pas disponible :
291283
292284```c++
293- VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR> availablePresentModes) {
285+ VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR> & availablePresentModes) {
294286 VkPresentModeKHR bestMode = VK_PRESENT_MODE_FIFO_KHR;
295287
296288 for (const auto& availablePresentMode : availablePresentModes) {
@@ -368,21 +360,30 @@ void createSwapChain() {
368360}
369361```
370362
371- Il existe en fait encore une dernière chose que nous devons choisir, mais c'est suffisement simple pour ne pas mériter
372- de fonction. Nous devons déterminer le nombre d'images dans la swap chain. L'implémentation spécifie le minimum
373- nécessaire à un bon fonctionnement, et nous essayerons d'en avoir une de plus que ce nombre pour pouvoir implémenter
374- correctement le triple buffering.
363+ Il nous reste une dernière chose à faire : déterminer le nombre d'images dans la swap chain. L'implémentation décide
364+ d'un minimum nécessaire pour fonctionner :
365+
366+ ``` c++
367+ uint32_t imageCount = swapChainSupport.capabilities.minImageCount;
368+ ```
369+
370+ Se contenter du minimum pose cependant un problème. Il est possible que le driver fasse attendre notre programme car il
371+ n'a pas fini certaines opérations, ce que nous ne voulons pas. Il est recommandé d'utiliser au moins une image de plus
372+ que ce minimum :
375373
376374``` c++
377375uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1 ;
376+ ```
377+
378+ Il nous faut également prendre en compte le maximum d'images supportées par l'implémentation. La valeur ` 0 ` signifie
379+ qu'il n'y a pas de maximum autre que la mémoire.
380+
381+ ``` c++
378382if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount) {
379383 imageCount = swapChainSupport.capabilities.maxImageCount;
380384}
381385```
382386
383- La valeur ` 0 ` pour ` maxImageCount ` signifie que la seule limite est la mémoire, c'est pourquoi dans ce cas nous
384- laissons ` imageCount ` à la valeur que nous avons déterminée.
385-
386387Comme la tradition le veut avec Vulkan, la création d'une swap chain nécessite de remplir une grande structure. Elle
387388commence de manière familière :
388389
@@ -525,18 +526,15 @@ Ces images ont été crées par l'implémentation avec la swap chain et elles se
525526destruction de la swap chain, nous n'aurons donc rien à rajouter dans la fonction ` cleanup ` .
526527
527528Ajoutons le code nécessaire à la récupération des références à la fin de ` createSwapChain ` , juste après l'appel à
528- ` vkCreateSwapchainKHR ` . Cette récupération est quasiment identique à la procédure standarde pour récupérer des tableaux
529- d'objets .
529+ ` vkCreateSwapchainKHR ` . Comme notre logique n'a au final informé Vulkan que d'un minimum pour le nombre d'images dans la
530+ swap chain, nous devons nous enquérir du nombre d'images avant de redimensionner le conteneur .
530531
531532``` c++
532533vkGetSwapchainImagesKHR (device, swapChain, &imageCount, nullptr);
533534swapChainImages.resize(imageCount);
534535vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImages.data());
535536```
536537
537- Notez que lorsque nous avons créé la swap chain nous avons indiqué une valeur `minImageCount`, mais nous ne pouvons
538- nous y fier car l'implémentation peut en créer plus, et c'est pourquoi nous devons demander le nombre d'images.
539-
540538Une dernière chose : gardez dans des variables le format et le nombre d'images de la swap chain, nous en aurons
541539besoin dans de futurs chapitres.
542540
0 commit comments