vkAcquireNextImageKHR: Application has already acquired the maximum number of images

2.8k views Asked by At

I have written a simple triangle example which works on my machine but I got a bug report where the user was unable to run the example and got the following validation error.

vkAcquireNextImageKHR: Application has already acquired the maximum number of images (0x1)" thread 'main' panicked at 'called Result::unwrap() on an Err value: ErrorValidationFailedExt'

I create either minImageCount + 1 or maxImageCount images in the swapchain.

If you are curious how I present the images you can see it here. And record_submit_commandbuffer if you are curious how I submit the command buffers.

The user also reported that he can run SaschaWillems Vulkan examples, so the error is most likely on my side.

The only difference that I could spot is that SaschaWillems Vulkan examples would create N pre recorded commandbuffers where N is the number of images in the swapchain.

VK_CHECK_RESULT(swapChain.acquireNextImage(presentCompleteSemaphore, &currentBuffer));

// Use a fence to wait until the command buffer has finished execution before using it again
VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[currentBuffer], VK_TRUE, UINT64_MAX));
VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[currentBuffer]));

Where I just rerecord a new command buffer after I have called acquireNextImage and I immediately wait on the command buffer fence and then I call queuePresent.

https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/xhtml/vkspec.html#vkAcquireNextImageKHR

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.

So in my case that would be a > (m + 1) - m => a > 1 So the error seems to indicate that I call vkAcquireNextImageKHR too early. But I am still not quite sure why this happens.

On my machine I have no problems running the examples, nor do I get any validation errors. I also seem to be doing essentially the same thing as SaschaWillems Vulkan examples

Also if you want to run it yourself, it requires Rust and the LunarG validation layers.

git clone https://github.com/MaikKlein/ash
cd examples
cargo run --bin triangle

API dump for the render_loop

2

There are 2 answers

6
krOoze On BEST ANSWER

I had the opportunity to reproduce it on linux(Ubuntu) Mesa13 Intel driver.

The driver seems to return garbage in VkPresentInfoKHR::pResults.

If I assign null_mut to it instead the program starts to work without issues.

(BTW, your depth image is created as "sparse", which I found odd.)

0
RippeR On

It's a bug (not yet fixed) in unique_objects validation layer. It's not yet fixed so there isn't really a solution yet. Ticket: https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/issues/1670

To workaround that bug you can:

a) Initialize pResults array values with something successful (like VK_RESULT_SUCCESS) and make sure to also check value returned by vkQueuePresentKHR() as this value is already valid one. This will work when they fix it or you won't use validation layers, but for now these values will simply stay as initialized so it won't bother other validation layers.

b) Pass nullptr as pResults. This won't allow you to inspect specific results per swapchain in the future when they will fix it. If you have only one swapchain, it might be redundant to check both anyway... Though I'd prefer to use (a) solution.