在Vulkan中具有透明度的多个绘图调用之间是否需要同步?

我正在学习Vulkan,我只是使用原始ImGui存储库中的Vulkan-GLFW示例将ImGui集成到了我的代码中,并且效果很好。

现在,我想同时在屏幕上渲染GUI和我的3D模型,并且由于GUI和模型肯定需要不同的着色器,因此我需要使用多个管道并提交多个命令。 GUI是部分透明的,因此我希望在模型之后呈现它。 Vulkan规范指出,命令的执行顺序不太可能是我记录命令的顺序,因此我需要某种形式的同步。在this Reddit post中,提出了几种精确实现目标的方法,我曾经认为我必须使用多个子通道(以及子通道依赖项)或障碍或类似的其他同步方法来解决此问题。

然后我看了SaschaWillems' Vulkan examples,尽管在ImGui示例中,我看不到两个绘制调用之间没有同步,它只是记录了先绘制模型的命令,然后是绘制GUI的命令。

我很困惑。在这种情况下是否真的需要同步,还是我对命令重新排序或混合有误解?谢谢。

zhao_xiao_xin 回答:在Vulkan中具有透明度的多个绘图调用之间是否需要同步?

考虑一下您正在做什么。您为什么认为两组命令之间需要同步?因为第二组命令需要与第一组命令中的数据混合,对吗?因此,它需要执行读/修改/写(RMW),它必须能够读取由上一组命令写入的数据。读取的数据必须已经写入,并且通常需要同步。

但是再想一想这意味着什么。混合必须从帧缓冲区读取以完成其工作。但是...深度测试也是如此,对吗?它必须读取现有样本的深度值,将其与传入的片段进行比较,然后根据深度测试是否丢弃该片段。因此,基本上,使用深度测试的每个绘制调用都包含一个读/修改/可写的帧缓冲区。

但是...您的深度测试仍然有效。它们不仅可以在绘图调用之间工作而无需显式同步,而且还可以在内部绘图调用中工作。如果抽奖活动中的两个三角形重叠,那么看到底部的一个到顶部的一个就没有问题,对吗?您不必进行三角形间同步即可确保在读取之前完成了先前三角形的写入。

以某种方式,深度测试的RMW无需任何显式同步即可工作。那么...为什么您认为这对于混合阶段的RMW是不正确的?

Vulkan规范指出,命令和命令中的阶段将以很大程度上无序的方式执行,但有几个例外。最明显的是存在明确的执行障碍/依赖关系。但是它也说固定功能的每个样本的测试和混合阶段将始终(好像)按照提交顺序(在子过程中)执行。不仅如此,它还要求在命令中 内生成的三角形也要按照明确定义的特定顺序执行这些阶段。

这就是为什么您的深度测试不需要同步; Vulkan要求对此进行处理。这也是为什么您的 blending 不需要同步(在子阶段内)的原因。

因此,您有很多选择(从最快到最慢的顺序):

  • 在与非UI相同的子阶段中渲染您的UI。只需适当地更改管道即可。
  • 在子通道中呈现UI,并且显式依赖于非UI子通道的帧缓冲区图像。尽管从技术上讲这比较慢,但可能根本不会慢很多。另外,这对于延迟渲染很有用,因为您的UI需要在光照通过之后发生,这无疑是它自己的子遍。
  • 使用其他渲染过程渲染您的UI。只有在您需要执行一些全屏工作(SSAO)从而迫使您的非UI渲染通道仍然终止的情况下,才真正需要这样做。
本文链接:https://www.f2er.com/3157767.html

大家都在问