使用管道障碍而不是信号量

时间:2016-07-26 06:49:26

标签: vulkan

我想确保我正确理解管道障碍。 因此,如果第二屏障的源阶段晚于第一屏障的目标阶段,则屏障能够同步两个命令缓冲区。它是否正确? 当然,如果命令缓冲区在管道的不同迭代期间执行,我将需要使用信号量。

在我看来,同步是Vulkan最难掌握的部分。 IMO的规范还不够清楚。

2 个答案:

答案 0 :(得分:4)

序言:

适用于Vulkan Pipeline Barriers的大部分内容适用于通用障碍和记忆障碍,因此您可以从那里开始构建您的直觉。

我会注意到,虽然规范不是教程,但它相当清晰可读。同步 可能是最难的部分,规范中的描述反映了这一点。最重要的是,尤其是内存障碍对大多数人来说都是新颖的(通过高级语言编译器,它们通常不受这种概念的影响)。

需要的定义:

管道是如何处理工作单元的抽象方案。有四种类型(尽管Vulkan并没有说供应商只要按照规则做事情):

  1. 主机访问伪管道(有一个阶段)
  2. 转移(一阶段)
  3. 计算(有一个阶段)
  4. 图形(有很多阶段,即DI→VI→VS→TCS→TES→GS→EFT→FS→LFT→输出)
  5. 有特殊阶段TOP(在完成任何事情之前),BOTTOM(在完成所有事情之后)和ALL(与所有阶段设置的位域相同)。

    (操作)命令是需要(一个或多个)通过管道的命令。必须将其记录到命令缓冲区(主机通过vkMapMemory()读取和写入除外)。

    命令缓冲区是一些命令序列(记录顺序!)。 队列也是一系列记录的命令(与提交的命令缓冲区连接)。

    队列有一些余地,它执行命令的顺序(只要保留用户设置状态,它可以重新排序命令),也可以重叠命令(例如,在完成上一个命令的FS之前执行下一个命令的VS) 。用户定义的同步原语为此余地设置了边界。 (也有一些隐含的保证 - 但最好不要依赖它们并且在确信之前过度同步)

    我对解释管道障碍的看法:

    (也许不幸的是)管道障碍合并了三个不同的方面 - 执行障碍,记忆障碍和布局过渡(如果是图像)。

    执行障碍部分确保在执行中至少在srcStageMask 之前在障碍开始执行dstStageMask中指定的阶段(或阶段)之后记录的任何命令。

    它只处理执行依赖而不是内存! 内存屏障部分确保内存(缓存)在执行障碍依赖关系之间(即依赖关系之前和依赖命令和阶段之前)之间的某处正确刷新和无效。

    您提供了什么样的内存依赖性以及在哪种类型的源/消费者之间(因此驱动程序可以选择适当的操作而不记住状态本身)。典型的读写依赖性(读取 - 读取和读写不需要任何内存同步,写入通常没有多大意义 - 为什么要在不先读取数据的情况下覆盖某些数据)。

    内存中的不同数据布局在某些硬件上可能是有利的(甚至是必要的)。在内存依赖性被处理的同时,数据被重新排序以遵守新的指定布局。

答案 1 :(得分:0)

  

因此,如果第二屏障的源阶段晚于第一屏障的目标阶段,则屏障能够同步两个命令缓冲区。这是对的吗?

1.0.35 Vulkan规范改进了措辞,明确了这一点:

  

如果在渲染过程实例之外记录vkCmdPipelineBarrier,则第一个同步范围包括提交到之前相同队列的每个命令,包括在同一命令缓冲区和批处理中的那些命令。

     

...

     

如果在渲染通道实例之外记录vkCmdPipelineBarrier,则第二个同步范围包括提交到其后的同一队列的每个命令,包括在同一命令缓冲区和批处理中的那些命令。

请注意,源或目标阶段没有要求。你可以将一个源作为片段着色器和目标同步为顶点着色器就好了。