vkAcquireNextImageKHR:应用程序已经获取了最大数量的图像

vkAcquireNextImageKHR: Application has already acquired the maximum number of images

我写了一个简单的三角形示例,它可以在我的机器上运行,但我收到了一个错误报告,其中用户无法 运行 该示例并出现以下验证错误。

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

我在交换链中创建了 minImageCount + 1maxImageCount 图像。

如果你好奇我如何呈现图像你可以看到它here. And record_submit_commandbuffer如果你好奇我如何提交命令缓冲区。

用户也反映他可以运行SaschaWillems Vulkan examples,所以这个错误很有可能在我这边

我能发现的唯一区别是 SaschaWillems Vulkan examples 会创建 N 个预先记录的命令缓冲区,其中 N 是交换链中的图像数量。

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]));

我在调用 acquireNextImage 后重新记录了一个新的命令缓冲区,我立即在命令缓冲区栅栏上等待,然后调用 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.

所以在我的情况下会是 a > (m + 1) - m => a > 1 所以错误似乎表明我调用 vkAcquireNextImageKHR 太早了。但是我还是不太清楚为什么会这样。

在我的机器上 运行 示例没有问题,我也没有收到任何验证错误。我似乎也在做与 SaschaWillems Vulkan examples

基本相同的事情

此外,如果您想自己 运行,它需要 Rust 和 LunarG 验证层。

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

API render_loop

的转储

我有机会在 linux(Ubuntu) Mesa13 Intel 驱动程序上重现它。

驱动程序似乎 return 垃圾 VkPresentInfoKHR::pResults

如果我将 null_mut 分配给它,程序就会开始正常运行。

(顺便说一句,您的深度图像创建为 "sparse",我觉得这很奇怪。)

这是 unique_objects 验证层中的一个错误(尚未修复)。它尚未修复,因此还没有真正的解决方案。门票:https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/issues/1670

要解决该错误,您可以:

a) 用成功的东西(比如 VK_RESULT_SUCCESS)初始化 pResults 数组值,并确保还检查 vkQueuePresentKHR() 返回的值,因为这个值已经是有效值。这将在他们修复它时起作用,或者您不会使用验证层,但现在这些值将简单地保持初始化状态,因此不会打扰其他验证层。

b) 将 nullptr 作为 pResults 传递。这将不允许您在将来修复它时检查每个交换链的特定结果。如果你只有一个交换链,那么检查两者可能是多余的......虽然我更愿意使用 (a) 解决方案。