这个问题是另一个问题答案的副产品: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
提供的应用程序获取?
答案 0 :(得分:2)
不,他们通常不能一次性获得。
说明的规范引用是:
让 n 为交换链中的图片总数, m 为
VkSurfaceCapabilitiesKHR::minImageCount
的值, a 为应用程序当前获取的可呈现图像的数量(即使用vkAcquireNextImageKHR
获取但尚未显示vkQueuePresentKHR
的图像)。如果vkAcquireNextImageKHR
被调用a ≤ n - m
,则vkAcquireNextImageKHR
可以始终成功。如果vkAcquireNextImageKHR
,[1.0.19更改] 如果a > n - m
必须才能被调用在这种情况下,如果timeout
为UINT64_MAX
,则vkAcquireNextImageKHR
可能无限期阻止。vkAcquireNextImageKHR
a > n - m
为timeout
,则UINT64_MAX
不应在这种情况下,vkAcquireNextImageKHR
可能无限期阻止。
所以如果我没有弄错的话,只有在m = 1
的情况下才能获得它们。
更新:通过一些扭曲,引用可以解释为这样,你可以尝试全部获取(提供非无限timeout
),但不能保证成功。
我会在GitHub上要求验证。
决议:我在GitHub上得到了初步答案,这种解释是正确的。引号中的必须可能意味着应该。
问题是,你不需要为了第一次转换而获取它们,因为在95%的情况下,在现有之后(即在vkAcquire
之后立即读取图像)没有任何意义,所以你几乎总是提供oldLayout==UNDEFINED
(这意味着:在+ GPU可以废弃数据之前的任何布局)。
答案 1 :(得分:1)
我相信我写了以下部分规范(在其他Khronos成员的帮助下):
令n为交换链中的图像总数,m为VkSurfaceCapabilitiesKHR :: minImageCount的值,a为应用程序当前获取的可呈现图像的数量(即使用vkAcquireNextImageKHR获取的图像,但尚未显示与vkQueuePresentKHR)。 vkAcquireNextImageKHR 可以在调用vkAcquireNextImageKHR时≤n - m时始终成功。如果> vkAcquireNextImageKHR 不应该被调用n - m,超时为UINT64_MAX;在这种情况下,vkAcquireNextImageKHR 可能无限期阻止。
请注意 例如,如果VkSurfaceCapabilitiesKHR的minImageCount成员为2,并且应用程序创建了包含2个可显示图像的交换链,则应用程序可以获取一个图像,必须在尝试之前显示它获得另一张图片。
如果我们修改此示例以便应用程序希望同时获取最多3个可呈现图像,则必须在创建交换链时请求最小图像数为4。
目的是即使在创建交换链之后,您也无法尝试获取所有图像。正如krOoze所示,我们软化了一句话,将必须改为不应该。因此,可能能够通过一些实现来逃脱它,但你不应指望它。
我可以看到,由于一句话无限期地谈论无限期的阻塞,你可能会认为如果超时不是无限的,那就没关系。这可能是规范中的弱点。如果有限超时,您可能会收到错误,并且应该从验证中收到您处于不安全区域的消息。我看到的最后一个,立方体演示(在LunarG / Khronos SDK中)正确地做到了这一点,并且是如何做到这一点的官方来源。