4

This question is a by-product of an answer to another question: https://stackoverflow.com/a/37948367/3256878.

When a swapchain is created, its images are in VK_IMAGE_LAYOUT_UNDEFINED. In order to present they need to be in VK_IMAGE_LAYOUT_PRESENT_SRC_KHR. For this reason it seems plausible that all of them are available to the application via multiple invocations of vkAcquireNextImageKHR immediately after creating the swapchain, that is, before any rendering takes place.

I'm assuming that since the images are in VK_IMAGE_LAYOUT_UNDEFINED they should be available to the application because the presentation engine can't present them and so shouldn't be locked other than due to plain ownership. Is this assumption correct? I haven't found anything in the spec explicitly allowing or disallowing this.

I guess another way to ask the same is: can a swapchain image always be acquired by an application provided it's in VK_IMAGE_LAYOUT_UNDEFINED?

Community
  • 1
  • 1
Andreas Flöjt
  • 349
  • 4
  • 10
  • A better question is... why do you want to? What's the point of having more than one image for a swapchain be acquired? – Nicol Bolas Jun 21 '16 at 19:30
  • To make an initial layout change as per the linked question. In a more general sense it could also be useful if you need to prepare frames in advance, but that particular use case is not relevant for me. – Andreas Flöjt Jun 22 '16 at 06:42
  • But again, why? Whether the image is in the initial undefined layout or the present layout, you're going to have to change the image's layout before you can actually use it. So what exactly is the point? What's wrong with transitioning from UNDEFINED that you have to go combing through the spec for an alternative? – Nicol Bolas Jun 22 '16 at 13:04

2 Answers2

4

No they usually can't be acquired all at once.

The spec quote explaining that is:

Let n be the total number of images in the swapchain, m be the value of VkSurfaceCapabilitiesKHR::minImageCount, and a be the number of presentable images that the application has currently acquired (i.e. images acquired with vkAcquireNextImageKHR, but not yet presented with vkQueuePresentKHR). vkAcquireNextImageKHR can always succeed if a ≤ n - m at the time vkAcquireNextImageKHR is called. vkAcquireNextImageKHR must not be called when if a > n - m; in such a case, and if timeout is UINT64_MAX, vkAcquireNextImageKHR may block indefinitely. [1.0.19 change] vkAcquireNextImageKHR should not be called if a > n - m with a timeout of UINT64_MAX; in such a case, vkAcquireNextImageKHR may block indefinitely.

So they can all be acquired only in the case of m = 1 if I am not mistaken.

UPDATE: With some twisting, the quote can be interpreted as such, that you can attempt to get them all (with providing non-infinite timeout), but there is no guarantee of success.
I am gonna ask that on the GitHub to verify.

RESOLUTION: I got preliminary answer on the GitHub that this interpretation is correct. That the must in the quote is perhaps meant to be should.

The thing is, you do not need to acquire them all for purposes of first transition, because in 95 % of cases reading the images after present (i.e. immediately after vkAcquire) makes no sense, so you almost always provide oldLayout==UNDEFINED (which means: whatever layout was before + GPU can scrap data).

krOoze
  • 12,301
  • 1
  • 20
  • 34
  • I saw that quote and it makes sense when you have already started rendering because some images may be locked by the presentation engine. However I'm interested in the very special case of acquiring all of them one time immediately after creating the swapchain and before any rendering takes place, assuming that since they are undefined they should be available. It's this assumption I need clarification on. I'll edit my question to better indicate this. – Andreas Flöjt Jun 22 '16 at 07:02
  • The quote and inequalities applies always, regardless of case. If you have suggestion for the spec or curious about that design choice, you better ask on the [Khronos forum](https://forums.khronos.org/forumdisplay.php/114-Vulkan-High-Efficiency-GPU-Graphics-and-Compute) or on [GitHub](https://github.com/KhronosGroup/Vulkan-Docs/issues). (I think the GitHub would have more chance of being frequented by authors and you being answered.) – krOoze Jun 22 '16 at 13:07
3

I believe that I wrote the following part of the spec (with help from other Khronos members):

Let n be the total number of images in the swapchain, m be the value of VkSurfaceCapabilitiesKHR::minImageCount, and a be the number of presentable images that the application has currently acquired (i.e. images acquired with vkAcquireNextImageKHR, but not yet presented with vkQueuePresentKHR). vkAcquireNextImageKHR can always succeed if a ≤ n - m at the time vkAcquireNextImageKHR is called. vkAcquireNextImageKHR should not be called if a > n - m with a timeout of UINT64_MAX; in such a case, vkAcquireNextImageKHR may block indefinitely.

Note For example, if the minImageCount member of VkSurfaceCapabilitiesKHR is 2, and the application creates a swapchain with 2 presentable images, the application can acquire one image, and must present it before trying to acquire another image.

If we modify this example so that the application wishes to acquire up to 3 presentable images simultaneously, it must request a minimum image count of 4 when creating the swapchain.

The intention is that you can't/shouldn't try to acquire all of the images, even right after creating the swapchain. As krOoze showed, we softened the one sentence, changing must to should not. Thus, you may be able to get away with it with some implementation(s), but you should not count on it.

I can see that since the one sentence talks about blocking indefinitely with an infinite timeout, you may think it's okay if the timeout isn't infinite. That may be weakness in the spec. With a finite timeout, you may get an error, and should get a message from validation that you're in unsafe territory. The last I looked, the cube demo (in the LunarG/Khronos SDK) did this correctly, and is the official source for how to do this.