3

这个问题是另一个问题的答案的副产品:https ://stackoverflow.com/a/37948367/3256878 。

创建交换链时,其图像位于VK_IMAGE_LAYOUT_UNDEFINED. 为了呈现,他们需要在VK_IMAGE_LAYOUT_PRESENT_SRC_KHR. vkAcquireNextImageKHR出于这个原因,在创建交换链之后,即在任何渲染发生之前,它们都可以通过多次调用立即用于应用程序,这似乎是合理的。

我假设由于图像在其中,VK_IMAGE_LAYOUT_UNDEFINED它们应该可供应用程序使用,因为演示引擎无法呈现它们,因此不应该被锁定,除非是由于简单的所有权。这个假设正确吗?我没有在规范中找到任何明确允许或不允许这样做的内容。

我想另一种问同样问题的方法是:交换链图像是否可以始终由应用程序获取,只要它位于VK_IMAGE_LAYOUT_UNDEFINED

4

2 回答 2

4

不,它们通常不能一次全部获得。

规范报价解释为:

n是交换链中的图像总数,m是 的值VkSurfaceCapabilitiesKHR::minImageCounta是应用程序当前已获取的可呈现图像的数量(即vkAcquireNextImageKHR,使用 获取但尚未使用 呈现的图像vkQueuePresentKHR)。如果当时被调用,总vkAcquireNextImageKHR 成功。if时不能调用在这种情况下,如果可能会无限期地阻塞。[1.0.19 change] 如果带有 a of ,则不应调用;在这种情况下,可能会无限期地阻塞。a ≤ n - mvkAcquireNextImageKHRvkAcquireNextImageKHR a > n - mtimeoutUINT64_MAXvkAcquireNextImageKHR vkAcquireNextImageKHR a > n - mtimeoutUINT64_MAXvkAcquireNextImageKHR

m = 1因此,只有在我没有记错的情况下才能获得它们。

更新:通过一些扭曲,可以将引用解释为,您可以尝试全部获取它们(提供 non-infinite timeout),但不能保证成功。
我将在 GitHub 上要求验证。

解决方案:我在 GitHub 上得到初步回答,这个解释是正确的。引用中的must可能是should

问题是,你不需要为了第一次转换的目的而全部获取它们,因为在 95% 的情况下,在当前(即紧随其后vkAcquire)读取图像是没有意义的,所以你几乎总是提供oldLayout==UNDEFINED(这意味着:无论布局是before + GPU 可以报废数据)。

于 2016-06-21T20:21:29.823 回答
2

我相信我编写了规范的以下部分(在其他 Khronos 成员的帮助下):

令 n 为交换链中的图像总数,m 为 VkSurfaceCapabilitiesKHR::minImageCount 的值,a 为应用程序当前已获取的可呈现图像的数量(即使用 vkAcquireNextImageKHR 获取的图像,但尚未使用 vkQueuePresentKHR 呈现的图像) . 如果在调用 vkAcquireNextImageKHR 时 a ≤ n - m,vkAcquireNextImageKHR总是可以成功。如果 a > n - m 超时为 UINT64_MAX,则不应调用vkAcquireNextImageKHR 在这种情况下,vkAcquireNextImageKHR可能会无限期地阻塞。

注意 例如,如果 VkSurfaceCapabilitiesKHR 的 minImageCount 成员为 2,并且应用程序创建了具有 2 个可呈现图像的交换链,则应用程序可以获取一个图像,并且必须在尝试获取另一个图像之前呈现它。

如果我们修改此示例以使应用程序希望同时获取最多 3 个可呈现的图像,则它必须在创建交换链时请求最少 4 个图像计数。

目的是您不能/不应该尝试获取所有图像,即使在创建交换链之后也是如此。正如 krOoze 所示,我们软化了一句话,将must改为should not。因此,您可以通过一些实现来摆脱它,但您不应该指望它。

我可以看到,既然一句话讲了无限超时无限阻塞,你可能会认为如果超时不是无限也可以的。这可能是规范中的弱点。使用有限的超时,您可能会收到错误,并且应该从验证中收到一条消息,表明您处于不安全的区域。我上次查看的立方体演示(在 LunarG/Khronos SDK 中)正确地做到了这一点,并且是如何做到这一点的官方来源。

于 2017-08-09T21:30:19.937 回答