title: How to recreate swapchain after vkAcquireNextImageKHR is VK_SUBOPTIMAL_KHR?
body: <p>This <a href="https://vulkan-tutorial.com/Drawing_a_triangle/Swap_chain_recreation" rel="nofollow noreferrer">vulkan tutorial</a> discusses swapchain recreation:</p>
  <blockquote>
  <p>You could also decide to [recreate the swapchain] that if the swap chain is suboptimal, but I've chosen to proceed anyway in that case because we've already acquired an image.</p>
  </blockquote>
  <p>My question is: how would one recreate the swapchain and not proceed in this case of VK_SUBOPTIMAL_KHR?</p>
  <p>To see what I mean, let's look at the tutorial's <a href="https://github.com/Overv/VulkanTutorial/blob/master/code/16_swap_chain_recreation.cpp" rel="nofollow noreferrer">render function</a>:</p>
  <pre class="lang-cpp prettyprint-override"><code>void drawFrame() {
          vkWaitForFences(device, 1, &amp;inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
  
          uint32_t imageIndex;
          VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &amp;imageIndex);
  
          if (result == VK_ERROR_OUT_OF_DATE_KHR) { 
              recreateSwapChain();
              return;
          /* else if (result == VK_SUBOPTIMAL_KHR) { createSwapchain(); ??? } */
          } else if (result != VK_SUCCESS &amp;&amp; result != VK_SUBOPTIMAL_KHR) {
              throw std::runtime_error(&quot;failed to acquire swap chain image!&quot;);
          }
  
          if (imagesInFlight[imageIndex] != VK_NULL_HANDLE) {
              vkWaitForFences(device, 1, &amp;imagesInFlight[imageIndex], VK_TRUE, UINT64_MAX);
          }
          imagesInFlight[imageIndex] = inFlightFences[currentFrame];
  
          VkSubmitInfo submitInfo{};
          submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
  
          VkSemaphore waitSemaphores[] = {imageAvailableSemaphores[currentFrame]};
          VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
          submitInfo.waitSemaphoreCount = 1;
          submitInfo.pWaitSemaphores = waitSemaphores;
          submitInfo.pWaitDstStageMask = waitStages;
  
          submitInfo.commandBufferCount = 1;
          submitInfo.pCommandBuffers = &amp;commandBuffers[imageIndex];
  
          VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[currentFrame]};
          submitInfo.signalSemaphoreCount = 1;
          submitInfo.pSignalSemaphores = signalSemaphores;
  
          vkResetFences(device, 1, &amp;inFlightFences[currentFrame]);
  
          if (vkQueueSubmit(graphicsQueue, 1, &amp;submitInfo, inFlightFences[currentFrame]) != VK_SUCCESS) {
              throw std::runtime_error(&quot;failed to submit draw command buffer!&quot;);
          }
  
          VkPresentInfoKHR presentInfo{};
          presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
  
          presentInfo.waitSemaphoreCount = 1;
          presentInfo.pWaitSemaphores = signalSemaphores;
  
          VkSwapchainKHR swapChains[] = {swapChain};
          presentInfo.swapchainCount = 1;
          presentInfo.pSwapchains = swapChains;
  
          presentInfo.pImageIndices = &amp;imageIndex;
  
          result = vkQueuePresentKHR(presentQueue, &amp;presentInfo);
  
          if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized) {
              framebufferResized = false;
              recreateSwapChain();
          } else if (result != VK_SUCCESS) {
              throw std::runtime_error(&quot;failed to present swap chain image!&quot;);
          }
  
          currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
      }
  </code></pre>
  <p>The trouble is as follows:</p>
  <ol>
  <li>vkAcquireImageKHR succeeds, signaling the semaphore and returning a valid, suboptimal image</li>
  <li>Recreate the swapchain</li>
  <li>We can't present the image from 1 with the swapchain from 2 due to <code>VUID-VkPresentInfoKHR-pImageIndices-01430</code>.  We need to call vkAcquireImageKHR again to get a new image.</li>
  <li>When we call vkAcquireImageKHR again, the semaphore is in the signaled state which is not allowed (<code>VUID-vkAcquireNextImageKHR-semaphore-01286</code>), we need to 'unsignal' it.</li>
  </ol>
  <p>Is the best solution here to destroy and recreate the semaphore?</p>