Andreas Flöjt
Andreas Flöjt

Reputation: 349

Can all images be acquired from a swapchain immediately after creating it?

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?

Upvotes: 4

Views: 1279

Answers (2)

Ian Elliott
Ian Elliott

Reputation: 41

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.

Upvotes: 4

krOoze
krOoze

Reputation: 13246

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).

Upvotes: 4

Related Questions