创建后可以立即从交换链中获取所有图像吗?

时间:2016-06-21 15:38:58

标签: vulkan

这个问题是另一个问题答案的副产品: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提供的应用程序获取?

2 个答案:

答案 0 :(得分:2)

不,他们通常不能一次性获得。

说明的规范引用是:

  

n 为交换链中的图片总数, m VkSurfaceCapabilitiesKHR::minImageCount的值, a 为应用程序当前获取的可呈现图像的数量(即使用vkAcquireNextImageKHR获取但尚未显示vkQueuePresentKHR的图像)。如果vkAcquireNextImageKHR被调用a ≤ n - m,则vkAcquireNextImageKHR 可以始终成功。如果vkAcquireNextImageKHR a > n - m 必须才能被调用在这种情况下,如果timeoutUINT64_MAX,则vkAcquireNextImageKHR 可能无限期阻止。 [1.0.19更改]   如果vkAcquireNextImageKHR a > n - mtimeout,则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中)正确地做到了这一点,并且是如何做到这一点的官方来源。