6

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?

ratchet freak
  • 47,288
  • 5
  • 68
  • 106

2 Answers2

7

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.

ratchet freak
  • 47,288
  • 5
  • 68
  • 106
  • 2
    There is little reason (also dangerous) to read those image after present, so 1. in 95 % of cases. – krOoze May 31 '16 at 11:51
  • 1
    2. seems reasonable (you need to keep track of them for reading purposes anyway) - I would only change it to "when submiting" not "recording" – krOoze May 31 '16 at 11:52
  • 1
    3. is madness, with no guarantee of completion. Also leaking empty frames. ; propose 4. For minImages < 2 it is possible to acquire them all before present. I would prefer that to 2. – krOoze May 31 '16 at 12:04
  • @krOoze but it's when recording of the buffer that you need to do the selection of whether to transition from present or undefined. – ratchet freak May 31 '16 at 12:07
  • Some hybrid of 2. and 3. should be possible, but I don't think it's worth doing to optimalize away one simple `if` – krOoze May 31 '16 at 12:08
  • 1
    @krOoze well it's also the state tracking in itself that's the issue with 2. Having to look elsewhere to check some state is a cache miss that you may not want. And after you recreate the swapchain the tracking state needs to be reset as well... – ratchet freak May 31 '16 at 12:11
  • yes, right. I ment something like "Keep track of which images have been through the pipeline already and select the !command buffer with! need oldLayout accordingly. – krOoze May 31 '16 at 12:11
  • There's insignificant state to track (simple vector of pair image index-bool). But if you really need to optimalize even that away, then that hybrid solution (track until you get them all and then have unhindered loop) – krOoze May 31 '16 at 12:23
  • 1
    I think that the point in doing 1 is that it by always transitioning from undefined, you're telling the driver to do the minimal amount of work to transition to the destination layout, without having to keep track of it yourself. While a boolean per image is nearly insignificant, it's still more than tracking nothing per image. – Jherico May 31 '16 at 20:48
  • @Jherico I am not comparing it to 1. (as per comments above - the first above all) – krOoze May 31 '16 at 21:21
1

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.

Andreas Flöjt
  • 349
  • 4
  • 10
  • tl;dr: A variant of number 3 where you attempt to acquire all images before transitioning them. But with similar issues in that you cannot be sure that you can acquire all images in the first place. I'd rank it between options 2 and 3 of my answer. – ratchet freak Jun 21 '16 at 15:22
  • Pretty much, although if all images are available to us at this time those issues are rendered moot. That's why some input on that particular point is needed. – Andreas Flöjt Jun 21 '16 at 15:28
  • Yes, there is no guarantee of that (except minImages==1). IMHO if they were usable after creation you would already get them pre-acquired after creation. But that's questioning the Vulkan design... You are not guaranteed to get them -- that's simply how it is currently. – krOoze Jun 22 '16 at 16:58