【问题标题】:Pipeline barriers across multiple shaders?跨多个着色器的管道障碍?
【发布时间】:2017-08-15 02:56:53
【问题描述】:

Vulkan barriers explained 来看,似乎每个vkCmdPipelineBarrier 都在两个后续管道“运行”之间引入了依赖关系。对于写入图像的着色器 A 和对同一图像进行采样的着色器 B 的典型场景,它可能如下所示:

  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 读取的调度着色器

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

【问题讨论】:

    标签: vulkan


    【解决方案1】:

    您正在寻找活动。 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 命令之间没有直接的顺序保证,因此这些命令之间必须包含一些其他的执行依赖关系(例如信号量)。

    【讨论】:

    • 谢谢。这似乎回答了我的问题,但不幸的是,它也让我陷入困境,因为我不知道我是否会立即重新使用纹理,或者我是否会在以后的某个时间重新使用它 - 所以我提前不知道我是否需要发出事件信号。所以我相信我会一直使用 vmCmdPipeline 并忍受低效率。
    • 据我所知,事件是一种更高级的信号量,因为它们用于同步。另一方面,障碍定义了内存依赖。所以我认为在这种情况下使用事件将是一种矫枉过正。重新排序操作在这里没有帮助吗?如果命令没有接触到提到的图像,不能提前提交吗?
    • 事件是轻量级的。它不是信号量,也不是“高级信号量”。阅读文档。
    • @haasn 好吧,无论如何您都可以举办活动。如果您最终从不等待它,或者立即等待它也没关系,只需确保在下次使用之前正确重置它。
    • 事件可以从客户端(重新)设置,但这并不会使它们本身很重。事件几乎与管道屏障一样快,而 haasn 的问题正是您想要事件的地方,通过过早的屏障停止会更糟。事件也可以跨命令缓冲区工作,但避免竞争条件是开发人员的工作。这些不是栅栏,而且与栅栏不同,您不能等待客户端的事件。
    猜你喜欢
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 2018-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多