I am confused about the semantics of vkAcquireNextImageKHR
. Specifically, under what circumstances can the function return VK_TIMEOUT
? ie What could block it from not being able to acquire an image immediately? What might it wait for to happen?
It seems that an image can be acquired even if the presentation engine hasn't finished reading from the image, and one needs to use a semaphore or fence to synchronize usage of the acquired image anyway. What am I missing?
Nicol Bolas's answer is correct, but since the responses to it asked for details about where this is used in real implementations I'll add another answer here.
On Android, vkQueuePresentKHR
sends the image to the compositor (SurfaceFlinger), which displays it. The compositor re-displays this image on every display refresh until it gets a new image to display for that window. Until it gets that next image, it doesn't know whether or how many times it will need to read the buffer again in the future, and can't create a semaphore that will signal when the last read completes. (Hypothetically, you could build a system that could do that, but that's not how the Linux kernel sync mechanisms Android uses for this work.) So until you present image N+1, the compositor can't release image N back to your app for it to acquire, since it can't give you a semaphore to go along with it.
It's a little more complicated than that, since even if you present frame N+1, the compositor doesn't know how long it will take until the rendering semaphore signals, so it still doesn't know immediately how much longer it will need to be able to read the image for frame N.
This extends to swapchains with more than two buffers.
I'm not as familiar with other systems, but I believe others have similar constraints that prevent them from allowing you to acquire images arbitrarily far ahead of presenting them. It's definitely possible to build a presentation engine that would allow that, but Vulkan needed to work on existing systems and existing presentation engines, so had to live with the restrictions those existing systems impose. Khronos members can't change the Windows compositor, and others like X11, Wayland, and Android are difficult/slow to change since doing so could impact all existing apps, frameworks, etc.
All of that is implementation-defined.
However, the standard gives one clear case:
An image will eventually be acquired if the number of images that the application has currently acquired (but not yet presented) is less than or equal to the difference between the number of images in swapchain and the value of
VkSurfaceCapabilitiesKHR::minImageCount
. If the number of currently acquired images is greater than this,vkAcquireNextImageKHR
should not be called; if it is,timeout
must not beUINT64_MAX
.
So if you have acquired all available images in the swapchain and have not presented them, then you can get timeouts.
There may be other circumstances, but again, those are implementation-defined. A perfectly valid implementation of vkAcquireNextImageKHR
can signal the semaphore/fence that you provide before it returns a successful acquisition, thus forcing any delay into the vkAcquireNextImageKHR
call itself. You have no control over this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With