我编写了一个简单的三角形示例,该示例适用于我的计算机,但我收到了一个错误报告,其中用户无法运行该示例并获得以下验证错误。
vkAcquireNextImageKHR:应用程序已经获取了最大数量的图像(0x1)“线程'主要'在'
Result::unwrap()
上对'Err
值进行了恐慌:ErrorValidationFailedExt'
我在交换链中创建了minImageCount + 1
或maxImageCount
个图像。
如果您好奇我如何展示图片,您可以看到它here。如果你好奇我如何提交命令缓冲区,那么record_submit_commandbuffer。
用户还报告说他可以运行SaschaWillems Vulkan examples,因此错误很可能就在我身边。
我能发现的唯一区别是SaschaWillems Vulkan examples会创建N个预先录制的命令缓冲区,其中N是交换链中的图像数。
VK_CHECK_RESULT(swapChain.acquireNextImage(presentCompleteSemaphore, ¤tBuffer));
// 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
。
令n为交换链中的图像总数,m为VkSurfaceCapabilitiesKHR :: minImageCount的值,a为应用程序当前获取的可呈现图像的数量(即使用vkAcquireNextImageKHR获取的图像,但尚未显示与vkQueuePresentKHR)。如果在调用vkAcquireNextImageKHR时≤n - m,则vkAcquireNextImageKHR始终可以成功。如果>不应该调用vkAcquireNextImageKHR。 n - m,超时为UINT64_MAX;在这种情况下,vkAcquireNextImageKHR可能会无限期地阻止。
所以在我的情况下,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转储
答案 0 :(得分:3)
这是unique_objects
验证层中的错误(尚未修复)。它还没有修复,所以还没有真正的解决方案。票证:https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/issues/1670
要解决该错误,您可以:
a)使用成功的东西(如pResults
)初始化VK_RESULT_SUCCESS
数组值,并确保同时检查vkQueuePresentKHR()
返回的值,因为此值已经有效。这将在他们修复它时起作用,或者你不会使用验证层,但是现在这些值将保持初始化状态,因此它不会打扰其他验证层。
b)将nullptr
作为pResults
传递。这将不允许您在将来修复时检查每个交换链的特定结果。如果您只有一个交换链,那么检查它们可能是多余的...虽然我更愿意使用(a)
解决方案。
答案 1 :(得分:2)
我有机会在linux(Ubuntu)Mesa13 Intel驱动程序上重现它。
驱动程序似乎在VkPresentInfoKHR::pResults
中返回垃圾。
如果我为其分配null_mut
,则程序开始正常运行。
(顺便说一句,您的深度图像创建为"稀疏",我发现它很奇怪。)