如何检测哪个交换链已过期?

问题描述

我有多个交换链,其中一个已过期。

if (swapchain_count) {
    VkPresentInfoKHR present_info = {
        VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,NULL,swapchain_count,swapchain_array,swapchain_index_array,};

    vkQueuePresentKHR(queue,&present_info);
}

vkQueuePresentKHR 正在返回 VK_ERROR_OUT_OF_DATE_KHR

如何确定哪个交换链已过期?

如果忽略vkQueuePresentKHR返回的错误
错误交换链的下一个 vkAcquireNextimageKHR 将返回 VK_ERROR_OUT_OF_DATE_KHR
生成以下日志:

VUID-vkAcquireNextimageKHR-swapchain-01802(ERROR / SPEC): msgNum: 1050126472 - Validation Error:
[ VUID-vkAcquireNextimageKHR-swapchain-01802 ] Object 0:
handle = 0x948acd0000000008,type = VK_OBJECT_TYPE_SWAPCHAIN_KHR;
| MessageID = 0x3e97a888 | vkAcquireNextimageKHR:
Application has already prevIoUsly acquired 1 image from swapchain.
Only 1 is available to be acquired using a timeout of UINT64_MAX
(given the swapchain has 2,and VkSurfaceCapabilitiesKHR::minImageCount is 2).
The Vulkan spec states: If the number of currently acquired images is greater than the difference between
the number of images in swapchain and the value of VkSurfaceCapabilitiesKHR::minImageCount as returned
by a call to vkGetPhysicalDeviceSurfaceCapabilities2KHR with the surface used to create swapchain,timeout must not be UINT64_MAX

解决方法

VkPresentInfoKHR 结构有一个 pResults 字段:如果非 NULL,则 pResults 中的每个条目将被设置为 VkResult 以呈现与 {{ 中相同索引对应的交换链1}}。

pSwapchains

在代码中,您将 // Provided by VK_KHR_swapchain typedef struct VkPresentInfoKHR { VkStructureType sType; const void* pNext; uint32_t waitSemaphoreCount; const VkSemaphore* pWaitSemaphores; uint32_t swapchainCount; const VkSwapchainKHR* pSwapchains; const uint32_t* pImageIndices; VkResult* pResults; } VkPresentInfoKHR; 设置为 pResults

尝试将 NULL 设置为 pResults 的数组。

VkResult
,

过时的交换链是您传递给获取调用的交换链。交换链中的哪些图像已过时很简单:所有图像。当交换链过期时,该链中的所有图像都无法获取或呈现。

当交换链过期时,您必须为表面创建一个新的交换链,然后使用它。

,

我不认为有一种方法可以使用 vkQueuePresentKHR 找出哪个交换链没有数据,但是你怎么能做这样的事情,
如果 vkQueuePresentKHR 的结果是 VK_ERROR_OUT_OF_DATE_KHR,您可以使用 vkGetSwapchainStatusKHR 检查每一个并检查需要重新创建哪个交换链。

是的,这可能会很慢,因为您必须遍历整个交换链数组才能找到那个交换链。

另一种方式是规范规定:Link

VK_ERROR_OUT_OF_DATE_KHR 表面发生变化,使其不再与交换链兼容,使用交换链的进一步呈现请求将失败。如果应用程序希望继续向表面呈现,则它们必须查询新的表面属性并重新创建它们的交换链。

这意味着您可以跟踪哪个表面(窗口)发生了变化并重新创建其依赖项(交换链,可能是物理设备和逻辑设备)并在它抛出该错误之前更新阵列。