首页 > 解决方案 > Vulkan:为什么我们需要在 VkQueuePresentKHR 之后检查窗口调整大小

问题描述

我正在关注 vulkan 教程,目前是交换链娱乐的一部分。

https://vulkan-tutorial.com/Drawing_a_triangle/Swap_chain_recreation

我们应该通过将布尔变量 framebufferResized 设置为 true 来显式处理调整大小,无论是否调用窗口调整大小回调方法。然后,如果窗口已调整大小,我们会在每帧调用的 drawFrame 方法中重新创建交换链。像下面的东西。

VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
...
result = vkQueuePresentKHR(presentQueue, &presentInfo);
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized) {
    framebufferResized = false;
    recreateSwapChain();
}

这是我在教程中感到困惑的陈述:“在 vkQueuePresentKHR 之后执行此操作以确保信号量处于一致状态非常重要,否则可能永远无法正确等待已发出信号量。” 我假设的“this”是检查 boolean framebufferResized 和随后的 recreateSwapChain()。信号量只是确保我们在绘制到图像之前成功获取图像,然后在呈现之前成功绘制到它的信号量。因此,作者在说什么对我来说毫无意义。

标签: vulkan

解决方案


据推测,“信号”是指vkAcquire和交换链娱乐受到类似保护vkDeviceWaitIdle。并且推测,作者很担心VK_SUBOPTIMAL,并想在这种情况下重新创建交换链。

vkDeviceWaitIdle不包括来自 的未决信号量vkAcquire,正如此处确认的那样:https ://github.com/KhronosGroup/Vulkan-Docs/issues/1059 。

这意味着信号量必须首先由 a 等待vkQueueSubmit。只有这样,信号量才能被vk*WaitIdle命令捕获,并且只有在以有效方式销毁之后。


推荐阅读