Vulkan:理解帧缓冲区循环的麻烦

时间:2018-02-11 08:33:45

标签: asynchronous vulkan

在Vulkan,

信号量( A )和围栏( X )可以传递给{{1} }。该信号量( A )随后传递给vkAcquireNextImageKHR,等待 Presentation Engine (PE)释放图像。围栏( Y )也可以传递给vkQueueSubmit。客户代码可以通过检查围栏( Y )来检查提交何时完成。

当栅栏( Y )发出信号时,这表示PE可以显示图像。

我的问题:

如何在调用vkQueueSubmit后知道PE何时完成图像的使用?对我而言,似乎不是通过检查fence( X ),因为这是客户端代码知道何时可以通过{写入图像{1}},不是吗?将图像发送到vkQueuePresentKHR后,似乎栅栏( X )的用处已完成。或者,在调用vkQueueSubmit之后,是否可以使用相同的围栅( X )查询图像可用性?

我不知道在致电vkQueueSubmit后图片何时可用,而无需致电vkQueuePresentKHR

这给我带来麻烦的原因是,在一个异步的,60fps,三重缓冲应用程序(一次性学习代码)中,事情就像这样摆脱了怪癖:

  1. 向PE发送初始帧缓冲区。此帧缓冲现在不可用16毫秒。
  2. 在16ms内,获取第二个图像/帧缓冲区,提交命令,但不要出现。
  3. 对于第三张图像,与#2相同。我们在16ms之前提交。
  4. 16ms过去了,所以我们vkQueuePresentKHR第二张图片。
  5. 现在,如果我打电话给vkAcquireNextImageKHR,如果尚未使用图片#1,整件事情都会失败,因为此时我已经获得了三张图片。
  6. 如何在不致电vkQueuePresentKHR的情况下再次了解图片#1是否可用?

2 个答案:

答案 0 :(得分:3)

  

如何在调用vkQueuePresentKHR之后知道PE何时完成图像使用?

您通常不需要知道。

要么你需要获得一个新的VkImage,要么你没有。 PE是否已经完成甚至不会做出决定。

唯一想知道的原因是您是否想要衡量演示时间。有一个特殊的扩展:VK_GOOGLE_display_timing

  

将图片发送到vkQueueSubmit后,似乎栅栏( X )的用处已经完成。

好吧,你可以重复使用围栏。但是一旦发出信号,实施已经停止使用它,并且不再将其状态改变为任何东西,如果这就是你所要求的(因此你可以自由地vkDestroy它或用它做其他事情)。

  

我不知道在致电vkQueuePresentKHR后图片何时可用,而无需致电vkAcquireNextImageKHR

希望我在下面介绍它,但我不确定这里的问题是什么。我不知道如何在没有汤匙的情况下吃汤。简单地用勺子 - 我的意思是vkAcquireNextImageKHR

  
      
  1. 现在,如果我致电vkAcquireNextImageKHR,如果尚未使用图片#1>,整件事情可能会失败,因为此时我已经获得了3张图片。
  2.   
  3. 如何在不调用> vkAcquireNextImageKHR
  4. 的情况下再次了解图片#1是否可用   

与图像#1和#2有什么不同?

是的,您可能已经获得了交换链所提供的所有图像,或者即使有两张图像,PE也“没有准备好”放弃图像。

在第一种情况下,规范建议不要使用vkAcquireNextImageKHR timeout来调用UINT64_MAX。计算成功的vkAcquireNextImageKHR次呼叫与vkQueuePresentKHR的简单计算是一件简单的事情。一种方法是简单地做一个vkAcquireNextImageKHR,然后做一个vkQueuePresentKHR

在第二种情况下,您只需拨打vkAcquireNextImageKHR即可获得图像。

答案 1 :(得分:2)

要使用交换链图像,您需要获取它。之后,用于渲染目的的图像的实际可用性由信号量(A)或栅栏(X)发出信号。您可以在提交期间使用信号量(X)作为等待信号量,或者在CPU上等待栅栏(X)并在此之后提交。出于性能原因,信号量是一种首选方式。

现在,当您呈现图像时,您将其返回到Presentation Engine。从现在开始,您不能将该图像用于任何目的。无法再次检查该图像何时可用,以便您可以再次渲染它。你不能这样做。如果要再次渲染到交换链图像,则需要获取另一个图像。在此操作过程中,您再次提供信号量或栅栏(可能与您之前获取交换链图像时提供的信号量或栅栏不同)。 除了通过调用vkAcquireNextImageKHR()函数之外,没有其他方法可以检查图像何时可用。

当您想要实现三重缓冲时,您应该只选择适当的演示模式(邮箱模式是最接近的匹配)。在呈现图像之前,您不应该等待特定时间。当你完成渲染时,你应该呈现它。您的同步应完全基于在这些操作期间和提交期间提供的获取,当前命令和信号量或围栏。适当的现有模式应该完成其余的工作。有关不同现有模式的详细说明,请参见Intel's tutorial