@@ -539,8 +539,58 @@ void createSyncObjects() {
539539}
540540```
541541
542- Le programme devrait maintenant fonctionner normalement et la perte de mémoire ne devrait plus exister! Et nous avons
543- maintenant implémenté tout ce qu'il faut pour s'assurer que nous n'avons jamais plus de deux frames en vol!
542+ La fuite de mémoire n'est plus, mais le programme ne fonctionne pas encore correctement. Si ` MAX_FRAMES_IN_FLIGHT ` est
543+ plus grand que le nombre d'images de la swapchain ou que ` vkAcquireNextImageKHR ` ne retourne pas les images dans l'ordre,
544+ alors il est possible que nous lancions le rendu dans une image qui est déjà * en vol* . Pour éviter ça, nous devons pour
545+ chaque image de la swapchain si une frame en vol est en train d'utiliser celle-ci. Cette correspondance permettra de suivre
546+ les images en vol par leur fences respective, de cette façon nous aurons immédiatement un objet de synchronisation à attendre
547+ avant qu'une nouvelle frame puisse utiliser cette image.
548+
549+ Tout d'abord, ajoutez une nouvelle liste nommée ` imagesInFlight ` :
550+
551+ ``` c++
552+ std::vector<VkFence> inFlightFences;
553+ std::vector<VkFence> imagesInFlight;
554+ size_t currentFrame = 0 ;
555+ ```
556+
557+ Préparez-la dans ` CreateSyncObjects ` :
558+
559+ ``` c++
560+ void createSyncObjects () {
561+ imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
562+ renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
563+ inFlightFences.resize(MAX_FRAMES_IN_FLIGHT);
564+ imagesInFlight.resize(swapChainImages.size(), VK_NULL_HANDLE);
565+
566+ ...
567+ }
568+ ```
569+
570+ Initiallement aucune frame n'utilise d'image, donc on peut explicitement l'initialiser à * pas de fence* . Maintenant, nous allons modifier
571+ ` drawFrame ` pour attendre la fin de n'importe quelle frame qui serait en train d'utiliser l'image qu'on nous assigné pour la nouvelle frame.
572+
573+ ``` c++
574+ void drawFrame () {
575+ ...
576+
577+ vkAcquireNextImageKHR (device, swapChain, UINT64_MAX, imageAvailableSemaphores[ currentFrame] , VK_NULL_HANDLE, &imageIndex);
578+
579+ // Vérifier si une frame précédente est en train d'utiliser cette image (il y a une fence à attendre)
580+ if (imagesInFlight[imageIndex] != VK_NULL_HANDLE) {
581+ vkWaitForFences (device, 1, &imagesInFlight[ imageIndex] , VK_TRUE, UINT64_MAX);
582+ }
583+ // Marque l'image comme étant à nouveau utilisée par cette frame
584+ imagesInFlight[ imageIndex] = inFlightFences[ currentFrame] ;
585+
586+ ...
587+ }
588+ ```
589+
590+ Nous avons implémenté tout ce qui est nécessaire à la synchronisation pour certifier qu'il n'y a pas plus de deux frames de travail
591+ dans la queue et que ces frames n'utilise pas accidentellement la même image. Notez qu'il est tout à fait normal pour d'autre parties du code,
592+ comme le nettoyage final, de se reposer sur des mécanismes de synchronisation plus durs comme ` vkDeviceWaitIdle ` . Vous devriez décider
593+ de la bonne approche à utiliser en vous basant sur vos besoins de performances.
544594
545595Pour en apprendre plus sur la synchronisation rendez vous sur
546596[ ces exemples complets] ( https://github.com/KhronosGroup/Vulkan-Docs/wiki/Synchronization-Examples#swapchain-image-acquire-and-present )
0 commit comments