如何处理可呈现图像的布局?

How to deal with the layouts of presentable images?

一张可展示的图片从 VK_IMAGE_LAYOUT_UNDEFINED 开始,但展示一次后将是 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR

很多示例在创建 vkSwapchain 后立即将所有 vkImages 转换为 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR。这允许他们为 oldLayout 使用 VK_IMAGE_LAYOUT_PRESENT_SRC_KHRBut doing the transition right after creation of the swapchain is not allowed.

Use of a presentable image must occur only after the image is returned by vkAcquireNextImageKHR, and before it is presented by vkQueuePresentKHR. This includes transitioning the image layout and rendering commands.

我有哪些选项可以正确处理交换链图像布局?

有3个选项。从最好到最差(IMO)排序:

  1. 只需将renderPass中attachment的initialLayout设置为VK_IMAGE_LAYOUT_UNDEFINED或者每次都从VK_IMAGE_LAYOUT_UNDEFINED过渡。 This is allowed 并暗示您不关心图像中的数据。大多数情况下,您无论如何都会清除或完全覆盖图像。

    valid Usage [of VkImageMemoryBarrier]
    [...]

    • oldLayout must be VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PREINITIALIZED or the current layout of the image region affected by the barrier
  2. 记录 commandBuffer 时记录哪些图像已经通过管道并 select oldLayout

  3. 创建交换链后进行转换,但使用 vkAcquireNextImageKHRvkQueuePresentKHR 以确保应用程序在转换时拥有图像。无法保证您获取图像的顺序因此可能永远不会返回一张图像。

我一直在尝试第四个选项,但对其有效性的一些输入会很有用。创建交换链时,图像在 VK_IMAGE_LAYOUT_UNDEFINED 中,这对我来说似乎表明它们都可用于应用程序,因为它们需要 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR 进行演示,因此不应显示或在队列中。然而,我没有在规范中找到任何可以保证这一点的内容。

规范说如果我们需要,我们可以从交换链获取多个图像:

If a swapchain has enough presentable images, applications can acquire multiple images without an intervening vkQueuePresentKHR. Applications can present images in a different order than the order in which they were acquired.

使用上面的结论,我只是调用 vkAcquireNextImageKHR 来获取交换链的每个图像并立即更改所有图像的布局。之后,我展示了所有这些,可以这么说,让他们进入系统。

从某种意义上说,所有图像都由交换链交给我,这似乎是可行的,但话又说回来,我发现并不能保证在创建交换链后可以立即获取所有图像。