Vulkan:难以理解帧缓冲区的循环

Vulkan: trouble understanding cycling of framebuffers

在 Vulkan 中,

一个信号灯(A)和一个栅栏(X ) 可以传递给 vkAcquireNextImageKHR。该信号量 (A) 随后传递给 vkQueueSubmit,等待图像由 Presentation 释放引擎 (PE)。围栏(Y)也可以传递给vkQueueSubmit。客户端代码可以通过检查 fence(Y).

来检查提交何时完成

当fence(Y)发出信号时,表示PE可以显示图像

我的问题:

调用 vkQueuePresentKHR 后如何知道 PE 何时结束使用图像?对我来说,这似乎不是通过检查 fence(X),因为这是为了让客户端代码知道何时图像可以被 vkQueueSubmit 写入,不是吗?图片发送到vkQueueSubmit后,好像fence(X)的用处就完成了。或者,调用vkQueuePresentKHR?[=22=后是否可以使用同一个fence(X)查询图片可用性]

我不知道在调用 vkQueuePresentKHR 后图像何时再次可用,而无需调用 vkAcquireNextImageKHR


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

  1. 向 PE 发送初始帧缓冲区。此帧缓冲区现在有 16 毫秒不可用。
  2. 在 16 毫秒内,获取第二个 image/framebuffer,提交命令,但不显示。
  3. 对第三张图片执行与#2 相同的操作。我们在16ms之前提交。
  4. 16 毫秒过去了,所以我们 vkQueuePresentKHR 第二张图片。
  5. 现在,如果我调用 vkAcquireNextImageKHR,如果图像 #1 尚未使用完毕,整个过程可能会失败,因为此时我已经获取了三张图像。
  6. 如何在不调用 vkAcquireNextImageKHR 的情况下知道图像 #1 是否再次可用?

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

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

当你想实现三重缓冲时,你应该select适当的呈现模式(邮箱模式是最接近的匹配)。在呈现图像之前,您不应该等待特定的时间。当你完成渲染后,你应该展示它。您的同步应该完全基于在这些操作和提交期间提供的获取、呈现命令和信号量或栅栏。适当的呈现模式应该完成其余的工作。 Intel's tutorial.

中提供了不同呈现模式的详细说明

How do I know when the PE has finished using the image after a call to vkQueuePresentKHR?

你通常不需要知道。

您要么需要购买新的 VkImage,要么不需要。 PE有没有做完都不进那个决定。

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

After the image is sent to vkQueueSubmit, it seems the usefulness of fence(X) is done.

嗯,你可以重复使用围栏。但是,一旦它被发出信号,实现就会停止使用它,并且不会再将其状态更改为任何东西,如果这就是你要问的(所以你可以自由地 vkDestroy 它或用它做其他事情).

I don't know when the image is available again after a call to vkQueuePresentKHR, without having to call vkAcquireNextImageKHR.

希望我在下面介绍它,但我不确定这里的问题是什么。我也不知道没有勺子怎么喝汤。只需用一把勺子——我是说 vkAcquireNextImageKHR.

  1. Now, if I call vkAcquireNextImageKHR, the whole thing can fail if image #1 >is not yet done being used, because I have acquired 3 images at this point.
  2. How to know if image #1 is available again without calling >vkAcquireNextImageKHR?

它与图片 #1 和 #2 有何不同?

是的,你可能已经获得了交换链必须提供的所有图像,或者 PE 是 "not ready" 即使它有两个图像也可以放弃。

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

在第二种情况下,您只需调用 vkAcquireNextImageKHR 即可最终获得图像。