As stated in http://disq.us/p/32wdmkz, a recent [Vulkan Validation Layer update](https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/9802) exposed the problem that most Vulkan tutorials (also [vkguide](https://github.com/vblanco20-1/vulkan-guide/issues/149), and other derivative works of VulkanTutorial) and Vulkan programs (even [vkcube](https://github.com/KhronosGroup/Vulkan-Tools/issues/1106)) did not correctly make use of semaphores to synchronize presentation. I am not a Vulkan professor, and here's my understanding. In the following code: ```c VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[currentFrame]}; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]); ``` Here we are actually expecting that the `renderFinishedSemaphores[currentFrame]` to have already been acquired/consumed by presentation queue during the several previous iterations. However there's no guarantee. So it is possible for the graphics queue to signal an already signaled semaphore. To fix this problem, program should create the `renderFinishedSemaphores` array of `swapChainImages.size()` semaphores, and use the `imageIndex` returned from `vkAcquireNextImageKHR` to index into the array, ensuring that the semaphore has been acquired/consumed: https://github.com/kennyalive/vulkan-base/commit/27bcaad9d519cc2f9c5cde4872742d4a5212eee6 https://github.com/JasonPhone/vrtr/commit/c459d8829458da8d9bd4c3ea78cb1ee5de8f3922 https://github.com/JorriFransen/v10/commit/3652d32a52ba64b5fccfb48a2abe1e7181c1dd23 I also made my personal fix on my own Java version tutorial: [old](https://github.com/chuigda/vulkan4j/blob/6fd25db9c81758a50f13f69e0d5cc74655ffcc10/tutorial/src/main/java/tutorial/vulkan/part04/ch16_bad/Main.java#L1) -> [new](https://github.com/chuigda/vulkan4j/blob/6fd25db9c81758a50f13f69e0d5cc74655ffcc10/tutorial/src/main/java/tutorial/vulkan/part04/ch16/Main.java)