2017-08-14 79 views
2

通过Vulkan barriers explained判断,似乎每个vkCmdPipelineBarrier都引入了两个后续管道“运行”之间的依赖关系。对于写入图像和着色器B中的样品相同的图像着色器A的典型情况下,它可能是这样的:跨越多个着色器的流水线障碍?

  1. 调度着色器写入图像A
  2. vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, ...);
  3. 调度着色器从图像读取A

这定义了从第一个着色器执行的颜色附件阶段到第二个着色器执行的片段阶段的依赖关系。但如果我想在两者之间运行独立命令,该怎么办?例如

  1. 调度着色器写入图像A
  2. 调度无关着色器不触及图像A
  3. vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, ...);
  4. 调度着色器,从图像A

这仍然读但是效率不高:因为片段着色器阶段现在必须等待前一个,不相关的的颜色附件输出阶段着色器。如何在之前指定对着色器的依赖关系?

回答

2

您正在寻找活动。 https://vulkan.lunarg.com/doc/view/1.0.57.0/windows/vkspec.html#synchronization-events

事件是原始的同步可以被用来插入提交到相同的队列之间,或主机和一个队列中的命令之间的细粒度依赖性。事件有两个状态 - 有信号和无信号。应用程序可以在主机或设备上发出事件信号或无信号事件。在执行进一步的操作之前,设备可以等待事件发出信号。不存在等待主机发出事件信号的命令,但可以查询事件的当前状态。

当记录命令缓冲区时,您在操作后通过vkCmdSetEvent发送事件信号。此后,可以使用vkCmdWaitEvents来定义先前事件信号操作与后续命令之间的存储器依赖性。见https://vulkan.lunarg.com/doc/view/1.0.57.0/windows/vkspec.html#vkCmdWaitEvents

确保在通过vkCmdResetEvent再次使用之前重置该事件。并且注意:

应用程序在使用事件时应小心避免竞态条件。在vkCmdResetEvent命令和后面提交的vkCmdWaitEvents命令之间没有直接的顺序保证,因此这些命令之间必须包含其他一些执行依赖关系(例如信号量)。

+0

谢谢。这似乎回答了我的问题,但不幸的是,它也让我卡住了,因为我不知道我是否会立即重新使用纹理,或者我是否会在以后的某个时间点重新使用它 - 所以我事先不知道我是否需要发出事件信号。所以我相信我会一直使用vmCmdPipeline并且效率低下。 – haasn

+0

据我所知,事件是一种更先进的信号量,因为它们用于同步。另一方面,障碍定义了内存依赖性。所以我认为在这种情况下使用事件会是一个矫枉过正的事情。重新排序操作不会在这里帮助吗?如果命令没有触及提到的图像,是不是可以提前提交? – Ekzuzy

+1

事件轻而易举。它不是信号量,也不是“先进的信号量”。阅读文档。 – ssteinberg