如何处理可呈现图像的布局?
Posted
技术标签:
【中文标题】如何处理可呈现图像的布局?【英文标题】:How to deal with the layouts of presentable images? 【发布时间】:2016-05-30 11:01:22 【问题描述】:可呈现的图像以VK_IMAGE_LAYOUT_UNDEFINED
开头,但在呈现一次后将变为VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
。
许多示例在创建vkSwapchain
后立即将所有vkImages
转换为VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
。这允许他们将VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
用于oldLayout
。 But doing the transition right after creation of the swapchain is not allowed.
只能在
vkAcquireNextImageKHR
返回图像之后,在vkQueuePresentKHR
提供图像之前使用可呈现的图像。 这包括转换图像布局和渲染命令。
我有哪些正确处理交换链图像布局的选项?
【问题讨论】:
【参考方案1】:有 3 个选项。从最好到最差 (IMO) 排序:
只需将renderPass中附件的initialLayout设置为VK_IMAGE_LAYOUT_UNDEFINED
或每次从VK_IMAGE_LAYOUT_UNDEFINED
过渡。 This is allowed 并暗示您不关心图像中的数据。大多数情况下,无论如何您都会清除或完全覆盖图像。
有效用法 [VkImageMemoryBarrier] [...]
oldLayout 必须为VK_IMAGE_LAYOUT_UNDEFINED
、VK_IMAGE_LAYOUT_PREINITIALIZED
或受屏障影响的图像区域的当前布局
跟踪哪些图像已经通过管道,并在记录 commandBuffer 时相应地选择oldLayout
。
在创建交换链后执行转换,但使用vkAcquireNextImageKHR
和vkQueuePresentKHR
以确保应用程序在转换时拥有图像。无法保证您获取图像的顺序因此可能永远不会返回一张图像。
【讨论】:
现在没有理由(也很危险)阅读这些图像,所以 1. 在 95 % 的情况下。 2.似乎是合理的(无论如何,您都需要跟踪它们以供阅读)-我只会将其更改为“提交时”而不是“记录” 3.是疯狂的,无法保证完成。还泄漏空帧。 ;建议 4. 对于 minImages @krOoze 好吧,状态跟踪本身也是 2 的问题。不得不在其他地方检查某些状态是您可能不想要的缓存未命中。在你重新创建交换链之后,跟踪状态也需要重置...... 我认为做 1 的关键在于它总是从未定义转换,你告诉驱动程序做最少的工作来转换到目标布局,而不必跟踪它自己。虽然每张图片的布尔值几乎是微不足道的,但它仍然不仅仅是跟踪每张图片。【参考方案2】:我一直在尝试第四个选项,但对其有效性的一些输入会很有用。创建交换链时,图像位于VK_IMAGE_LAYOUT_UNDEFINED
中,对我来说这似乎表明它们都可供应用程序使用,因为它们需要VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
进行演示,因此不应显示或排队。但是,我在规范中没有找到任何可以保证这一点的内容。
规范说我们可以根据需要从交换链中获取多个图像:
如果交换链有足够的可展示图像,应用程序可以获取多个图像而无需干预 vkQueuePresentKHR。应用程序可以按照与获取图像的顺序不同的顺序呈现图像。
使用上面的结论,我刚刚调用了vkAcquireNextImageKHR
来获取交换链的每个图像并立即更改所有图像的布局。之后,我将它们全部展示出来,让它们进入系统。
从某种意义上说,似乎所有图像都由交换链交给我,但话又说回来,我发现不能保证在创建交换链后可以立即获取所有图像。
【讨论】:
tl;dr:数字 3 的变体,您尝试在转换之前获取所有图像。但是有类似的问题,你不能确定你可以首先获取所有图像。我会在答案的选项 2 和 3 之间对其进行排名。 差不多,尽管如果此时我们可以使用所有图像,那么这些问题将变得毫无意义。这就是为什么需要就该特定点提供一些意见的原因。 是的,不能保证这一点(minImages==1 除外)。恕我直言,如果它们在创建后可用,您将在创建后预先获取它们。但这是对 Vulkan 设计的质疑……你不能保证得到它们——这就是目前的情况。以上是关于如何处理可呈现图像的布局?的主要内容,如果未能解决你的问题,请参考以下文章