简体   繁体   English

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

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

I'm in the processing of learning Vulkan, and I have just integrated ImGui into my code using the Vulkan-GLFW example in the original ImGui repo, and it works fine.我正在学习 Vulkan,我刚刚使用原始 ImGui 存储库中的 Vulkan-GLFW 示例将 ImGui 集成到我的代码中,并且效果很好。

Now I want to render both the GUI and my 3D model on the screen at the same time, and since the GUI and the model definitely needs different shaders, I need to use multiple pipelines and submit multiples commands.现在我想在屏幕上同时渲染 GUI 和我的 3D model,由于 GUI 和 model 肯定需要不同的着色器,我需要使用多个管道命令并提交多个着色器。 The GUI is partly transparent, so I would like it to be rendered after the model. GUI 是部分透明的,所以我希望它在 model 之后呈现。 The Vulkan specs states that the execution order of commands are not likely to be the order that I record the commands, thus I need synchronization of some kind. Vulkan 规范指出命令的执行顺序不太可能是我记录命令的顺序,因此我需要某种同步。 In this Reddit post several methods of exactly achieving my goals was proposed, and I once believed that I must use multiple subpasses (together with subpass dependency) or barriers or other synchronization methods like that to solve this problem.这篇 Reddit 帖子中,提出了几种完全实现我的目标的方法,我曾经认为我必须使用多个子通道(连同子通道依赖)或屏障或其他类似的同步方法来解决这个问题。

Then I had a look at SaschaWillems' Vulkan examples , in the ImGui example though, I see no synchronization between the two draw calls, it just record the command to draw the model first, and then the command to draw the GUI.然后我看了一下SaschaWillems 的 Vulkan 示例,虽然在 ImGui 示例中,我看到两个绘制调用之间没有同步,它只是记录了先绘制 model 的命令,然后是绘制 GUI 的命令。

I am confused.我很困惑。 Is synchronization really needed in this case, or did I misunderstand something about command re-ordering or blending?在这种情况下真的需要同步,还是我误解了命令重新排序或混合的一些内容? Thanks.谢谢。

Think about what you're doing for a second.想一想你在做什么。 Why do you think there needs to be synchronization between the two sets of commands?为什么你认为两组命令之间需要同步? Because the second set of commands needs to blend with the data in the first set, right?因为第二组命令需要和第一组的数据混合,对吧? And therefore, it needs to do a read/modify/write (RMW), which must be able to read data written by the previous set of commands.因此,它需要进行读/修改/写(RMW),它必须能够读取上一组命令写入的数据。 The data being read has to have been written, and that typically requires synchronization.读取的数据必须已经写入,这通常需要同步。

But think a bit more about what that means.但请多想想这意味着什么。 Blending has to read from the framebuffer to do its job.混合必须从帧缓冲区中读取来完成它的工作。 But... so does the depth test, right?但是......深度测试也是如此,对吗? It has to read the existing sample's depth value, compare it with the incoming fragment, and then discard the fragment or not based on the depth test.它必须读取现有样本的深度值,将其与传入的片段进行比较,然后根据深度测试是否丢弃片段。 So basically every draw call that uses a depth test contains a framebuffer read/modify/wright.所以基本上每个使用深度测试的绘图调用都包含一个帧缓冲区读取/修改/写入。

And yet... your depth tests work.然而......你的深度测试有效。 Not only do they work between draw calls without explicit synchronization, they also work within a draw call.它们不仅可以在没有显式同步的绘图调用之间工作,而且还可以绘图调用中工作。 If two triangles in a draw call overlap, you don't have any problem with seeing the bottom one through the top one, right?如果绘制调用中的两个三角形重叠,则通过顶部看到底部的三角形没有任何问题,对吗? You don't have to do inter-triangle synchronization to make sure that the previous triangles' writes are finished before the reads.您不必进行三角形间同步以确保先前三角形的写入在读取之前完成。

So somehow, the depth test's RMW works without any explicit synchronization.因此,不知何故,深度测试的 RMW 无需任何显式同步即可工作。 So... why do you think that this is untrue of the blend stage's RMW?那么...为什么您认为混合阶段的 RMW 不正确?

The Vulkan specification states that commands, and stages within commands, will execute in a largely unordered way, with several exceptions. Vulkan 规范规定命令和命令中的阶段将以基本上无序的方式执行,但有几个例外。 The most obvious being the presence of explicit execution barriers/dependencies.最明显的是存在显式执行障碍/依赖关系。 But it also says that the fixed-function per-sample testing and blending stages will always execute (as if) in submission order (within a subpass).但它也表示,固定功能的每个样本测试和混合阶段将始终(好像)按提交顺序(在子通道内)执行。 Not only that, it requires that the triangles generated within a command also execute these stages (as if) in a specific, well-defined order.不仅如此,它还要求命令中生成的三角形也(好像)以特定的、明确定义的顺序执行这些阶段。

That's why your depth test doesn't need synchronization;这就是您的深度测试不需要同步的原因; Vulkan requires that this is handled. Vulkan 要求对此进行处理。 This is also why your blending will not need synchronization (within a subpass).这也是您的混合不需要同步(在子通道内)的原因。

So you have plenty of options (in order from fastest to slowest):所以你有很多选择(从最快到最慢的顺序):

  • Render your UI in the same subpass as the non-UI.在与非 UI 相同的子通道中渲染您的 UI。 Just change pipelines as appropriate.只需根据需要更改管道即可。
  • Render your UI in a subpass with an explicit dependency on the framebuffer images of the non-UI subpass.在子通道中渲染您的 UI,显式依赖于非 UI 子通道的帧缓冲区图像。 While this is technically slower, it probably won't be slower by much if at all.虽然这在技术上较慢,但如果有的话,它可能不会慢很多。 Also, this is useful for deferred rendering, since your UI needs to happen after your lighting pass, which will undoubtedly be its own subpass.此外,这对于延迟渲染很有用,因为您的 UI 需要在您的光照通道之后发生,这无疑是它自己的子通道。
  • Render your UI in a different render pass.在不同的渲染通道中渲染您的 UI。 This would only really be needed for cases where you need to do some full-screen work (SSAO) that would force your non-UI render pass to terminate anyway.仅当您需要执行一些全屏工作 (SSAO) 时才需要这样做,这将强制您的非 UI 渲染过程无论如何都终止。

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

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