How to deal with the layouts of presentable images

2020-04-07 18:50发布

问题:

A presentable image starts out in VK_IMAGE_LAYOUT_UNDEFINED but will be VK_IMAGE_LAYOUT_PRESENT_SRC_KHR after they have been presented once.

A lot of examples do a transition of all vkImages to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR immediately after creating the vkSwapchain. Which allows them to use an VK_IMAGE_LAYOUT_PRESENT_SRC_KHR for oldLayout. But doing the transition right after creation of the swapchain is not allowed.

Use of a presentable image must occur only after the image is returned by vkAcquireNextImageKHR, and before it is presented by vkQueuePresentKHR. This includes transitioning the image layout and rendering commands.

What are my options to deal with the swapchain image layouts correctly?

回答1:

There are 3 options. Ordered from best to worst (IMO):

  1. Simply set the initialLayout of the attachment in the renderPass to VK_IMAGE_LAYOUT_UNDEFINED or transition from VK_IMAGE_LAYOUT_UNDEFINED every time. This is allowed and will imply that you don't care about the data still in the image. Most often you will be clearing or fully overwriting the image anyway.

    valid Usage [of VkImageMemoryBarrier]
    [...]

    • oldLayout must be VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PREINITIALIZED or the current layout of the image region affected by the barrier
  2. Keep track of which images have been through the pipeline already and select the oldLayout accordingly when recording the commandBuffer.

  3. Do the transitions after creating the swapchain but using vkAcquireNextImageKHR and vkQueuePresentKHR to ensure the application owns the image while transitioning. There is no guarantee in which order you get the images So it may be possible one image never gets returned.



回答2:

I've been trying a fourth option but some input on its validity would be useful. When creating the swapchain the images are in VK_IMAGE_LAYOUT_UNDEFINED, which to me seems to indicate that they're all available to the application because they need VK_IMAGE_LAYOUT_PRESENT_SRC_KHR for presentation and so shouldn't be displayed or in queue. I didn't find anything in the spec that would guarantee this however.

The spec says that we can acquire multiple images from the swapchain if we want:

If a swapchain has enough presentable images, applications can acquire multiple images without an intervening vkQueuePresentKHR. Applications can present images in a different order than the order in which they were acquired.

Using the conclusion above I just called vkAcquireNextImageKHR to get every image of the swapchain and changed layout on all of them at once. After that I presented all of them to get them into the system so to speak.

It seems to work in the sense that all images are handed to me by the swapchain, but then again, I found no guarantee that all of them can actually be acquired immediately after creating the swapchain.