繁体   English   中英

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

[英]Is synchronization needed between multiple draw calls with transparency in Vulkan?

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

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

然后我看了一下SaschaWillems 的 Vulkan 示例,虽然在 ImGui 示例中,我看到两个绘制调用之间没有同步,它只是记录了先绘制 model 的命令,然后是绘制 GUI 的命令。

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

想一想你在做什么。 为什么你认为两组命令之间需要同步? 因为第二组命令需要和第一组的数据混合,对吧? 因此,它需要进行读/修改/写(RMW),它必须能够读取上一组命令写入的数据。 读取的数据必须已经写入,这通常需要同步。

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

然而......你的深度测试有效。 它们不仅可以在没有显式同步的绘图调用之间工作,而且还可以绘图调用中工作。 如果绘制调用中的两个三角形重叠,则通过顶部看到底部的三角形没有任何问题,对吗? 您不必进行三角形间同步以确保先前三角形的写入在读取之前完成。

因此,不知何故,深度测试的 RMW 无需任何显式同步即可工作。 那么...为什么您认为混合阶段的 RMW 不正确?

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

这就是您的深度测试不需要同步的原因; Vulkan 要求对此进行处理。 这也是您的混合不需要同步(在子通道内)的原因。

所以你有很多选择(从最快到最慢的顺序):

  • 在与非 UI 相同的子通道中渲染您的 UI。 只需根据需要更改管道即可。
  • 在子通道中渲染您的 UI,显式依赖于非 UI 子通道的帧缓冲区图像。 虽然这在技术上较慢,但如果有的话,它可能不会慢很多。 此外,这对于延迟渲染很有用,因为您的 UI 需要在您的光照通道之后发生,这无疑是它自己的子通道。
  • 在不同的渲染通道中渲染您的 UI。 仅当您需要执行一些全屏工作 (SSAO) 时才需要这样做,这将强制您的非 UI 渲染过程无论如何都终止。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM