当 srcStageMask 指定一个不在命令管道中的阶段时会发生什么?

What happens when srcStageMask specifies a stage which is not in the pipeline of a command?

我的理解是,当您提交 vkCmdPipelineBarrier 命令时,源同步范围内的所有命令都必须到达 srcStage,然后目标同步范围内的任何命令才被允许开始其管道的 dstStage。

但是,如果 srcStageMask 指定了源同步作用域中的命令不包含的阶段怎么办?例如,如果命令是 vkCmdDispatch 并且 srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT.

规范似乎回答了这个问题:

If a synchronization command includes a source stage mask, its first synchronization scope only includes execution of the pipeline stages specified in that mask

那么我希望该命令(上一个示例中的 vkCmdDispatch)的任何阶段执行的操作中的 none 将包含在同步范围内。但是在yet another blog explaining Vulkan synchronization中,作者说这会产生一个执行依赖链:

   1. vkCmdDispatch
   2. vkCmdDispatch
   3. vkCmdPipelineBarrier(srcStageMask = COMPUTE, dstStageMask = TRANSFER)
   4. vkCmdPipelineBarrier(srcStageMask = TRANSFER, dstStageMask = COMPUTE)
   5. vkCmdDispatch
   6. vkCmdDispatch

In this example we actually get a dependency between {1, 2} and {5, 6}. This is because we created a chain of dependencies between COMPUTE -> TRANSFER -> COMPUTE. When we wait for TRANSFER in 4. we must also wait for anything which is currently blocking TRANSFER.

但是规范说

An execution dependency chain is a sequence of execution dependencies that form a happens-before relation between the first dependency’s A' and the final dependency’s B'. For each consecutive pair of execution dependencies, a chain exists if the intersection of BS in the first dependency and AS in the second dependency is not an empty set.

在博客 post 的示例中,第一个管道屏障的 BS 不会是空集,因为 vkCmdDispatch 不包含传输阶段?那么 BS 和 AS 的交集就是空集,不应该存在依赖链。

但显然确实存在,所以这让我相信我对当 srcStageMask 或 dstStageMask 指定不在命令管道中的阶段时发生的情况有错误的理解。那么会发生什么?

编辑:

来自 Nicol 的回答:

It was talking specifically about the set of stages involved. Bs lists TRANSFER. As include TRANSFER. The intersection of the two stage masks is TRANSFER and therefore not empty. Therefore, there is a dependency chain.

那么 AS = {TRANSFER} union {逻辑上比 TRANSFER 更早}

和 BS = {TRANSFER} 联合{逻辑上比 TRANSFER 晚}?

如果是这样的话,我的困惑就迎刃而解了。但是...(来自 Nicol 的回答)

The spec said nothing about what commands get executed.

这似乎与我对规范的解释相矛盾。第 6.6 章说:

If vkCmdPipelineBarrier was recorded outside a render pass instance, the second synchronization scope includes all commands that occur later in submission order.

BS 是规范为第二个同步作用域提供的另一个名称。那么 BS 包含命令,而不是流水线阶段,对吗?那TRANSFER阶段怎么会在BS?

我并不是要学究气,我是真心想学习如何解释规范并自己得出这个结论,这样我就不会依赖 Whosebug。

规格states:

Pipeline stages that execute as a result of a command logically complete execution in a specific order, such that completion of a logically later pipeline stage must not happen-before completion of a logically earlier stage. This means that including any stage in the source stage mask for a particular synchronization command also implies that any logically earlier stages are included in AS for that command.

至于其余的:

In the blog post's example, wouldn't BS for the first pipeline barrier be the empty set since vkCmdDispatch doesn't contain a transfer stage?

没有。规范说没有关于执行什么命令。它专门讨论所涉及的阶段集。 Bs 列出 TRANSFER。 As包括TRANSFER。两个阶段掩码的交集是 TRANSFER,因此不为空。因此,存在依赖链。


看来您可能不完全理解同步 scope 是什么,它与该范围所界定的实际操作是分开的。规范指出:

The synchronization scopes define which other operations a synchronization command is able to create execution dependencies with. Any type of operation that is not in a synchronization command’s synchronization scopes will not be included in the resulting dependency. For example, for many synchronization commands, the synchronization scopes can be limited to just operations executing in specific pipeline stages, which allows other pipeline stages to be excluded from a dependency. Other scoping options are possible, depending on the particular command.

规范还特别区分了同步作用域和可能受该作用域约束的命令

  • Let A and B be separate sets of operations.
  • Let S be a synchronization command.
  • Let AS and BS be the synchronization scopes of S.
  • Let A' be the intersection of sets A and AS.
  • Let B' be the intersection of sets B and BS.

AB 表示作为操作一部分的实际命令。 ASBS分别代表命令的哪些部分可以参与依赖。当你把它们放在一起时,你会得到 A'B':实际命令的实际阶段得到同步。

您引用的关于依赖链的引述部分基于匹配 scopes 的存在,而不是匹配 commands 的存在那些范围。