Let's say I create a swap chain with presentMode = VK_PRESENT_MODE_MAILBOX_KHR and minImageCount = 3. Which of the following two behaviors will I get?
vkAcquireNextImageKHR simultaneously and the driver has a 2 additional images internally to implement the queue and presentation engine.With my NVIDIA driver I appear to get 2 simultaneously acquirable images in this case, which is yet another scenario inbetween these. Does the spec guarantee certain behavior in this regard or is this an implementation detail and should I assume the worst case (scenario 2)?
I was answering this somewhere already... hmm can't find it.
Neither. You have to let driver keep VkSurfaceCapabilitiesKHR::minImageCount - 1. Therefore if as you say your swapchain has 3 images and VkSurfaceCapabilitiesKHR::minImageCount is 2 then you are allowed to acquire 2 images. You are allowed to acquire more if you do not cause a deadlock.
To be precise if VkSurfaceCapabilitiesKHR::minImageCount == 2 and swapchain has 2 images:
vkAcquireNextImage(UINT32_MAX);
vkAcquireNextImage(UINT32_MAX);
// ^ invalid; 2 swapchain images, 2 minImages ->
// only allowed to acquire one image with endless wait. Undefined behavior (VU violation)
but
vkAcquireNextImage(UINT32_MAX);
vkAcquireNextImage(1 s); // OK, but may fail
and
vkAcquireNextImage(UINT32_MAX);
vkQueuePresent();
vkAcquireNextImage(UINT32_MAX);
// ^ OK, `vkQueuePresent`ed image always counts as released (irrespective of the semaphore wait)
PS:
Let's say I create a swap chain with presentMode = VK_PRESENT_MODE_MAILBOX_KHR and minImageCount = 3.
Technically the count vkGetSwapchainImagesKHR returns counts. vkCreateSwapchain can create more.
PS2:
This applies to all present modes really.
PS3:
Whether vkAcquireNextImage gives you the image immediatelly OR lets you wait for it is a different matter.
Thank you for clarifying, but this seems to be inconsistent with the comments on the VK_KHR_swapchain extension. They state that minImageCount + 1 is required whereas your answer implies that only minImageCount is required (assuming my application never holds more than 1 image).
@Overv Yes, that somewhat relates to PS3 above. Guaranteeing non-blocking behavior, and guaranteeng something is valid in the first place are two different things.
@krOoze Ah, alright, thanks.
minImageCount + 1 makes sense. minImageCount means the PE can only give you one image. Assuming that image was previously vkQueuePresented, that means it may still be in the process of being copied into the real compositor buffer. Ergo acquire may theoretically block (though copies can be fast). If there are no worries over RAM then why not have minImageCount + 1.
Then again drivers may report overinflated VkSurfaceCapabilitiesKHR::minImageCount so the above may mean wasted memory. Indeed some platforms allow you to get all the swapchain images without problems, so they should report VkSurfaceCapabilitiesKHR::minImageCount == 1 and not more.
PS: though Vulkan driver may be innocent here and may not know itself. IIRC e.g. X may work any way and does not tell either whether it needs some images forever OR if all are acquirable.
I haven't read this conversation carefully, but want to make sure there are no outstanding questions ...
One thing I'll point out from the spec (re: VkSwapchainCreateInfoKHR::minImageCount) is:
minImageCount is the minimum number of presentable images that the application needs. The implementation will either create the swapchain with at least that many images, or it will fail to create the swapchain.
You might get more images than minImageCount. Therefore, you need to base your code on what's returned by vkGetSwapchainImagesKHR (I mention this because of seeing code that didn't do that:-).
I'll also state what I think you both know: the implementation may create different numbers of images depending on the present mode. For example, on Android, if you ask for 2 images AND MAILBOX, you'll get 3 images. This is as suggested:
A final point is that, for the sake of portability and longevity, you shouldn't assume a compositor (or lack thereof), nor a particular set of semantics. I've seen some implementations change their behavior overtime, or in certain cases (e.g. if they notice your window is the full size of the screen, they may use HW instead of a compositor).
Hope this is helpful. I'll try to look to see if there are follow-up questions.
@ianelliottus Can the number of swapchain images returned by vkGetSwapchainImagesKHR vary between devices even if the settings are the same?
For example, on Android, if you ask for 2 images AND MAILBOX, you'll get 3 images.
On Android with:
VK_PRESENT_MODE_MAILBOX_KHR,VkSurfaceCapabilitiesKHR::minImageCount = 2, andVkSurfaceCapabilitiesKHR::maxImageCount = 3I'm seeing vkGetSwapchainImagesKHR return 3 as I would expect on a Mali-based device, but return 4 on NVIDIA's Shield (which has a Tegra).
Sorry for not seeing this sooner. Yes, I believe you can see different numbers returned. The Android implementation is supposed to be common, but I believe we changed things at one of the recent dessert releases. I also know that OEMs (e.g. NVIDIA for the Shield) can change things, or may be running a newer/older version of Android than another OEM's device.
@ianelliottus The spec for vkAcquireNextImageKHR says that
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.
Does this mean in that case, when minImageCount = 2 and the present mode is mailbox, I can actually acquire both images that aren't being displayed?
In other words, you generally can acquire swapchainImageCount - minImageCount + 1 number of images. If the swapchain has 3+ images, then yes, if it has 2 then no.