在 Vulkan 中重新绑定图形管道是否保证无操作?

Is rebinding a graphics pipeline in Vulkan a guaranteed no-op?

在简化的场景中,每个要渲染的对象都被翻译成一个辅助命令缓冲区,并且每个命令缓冲区最初都绑定一个图形管道:是否保证无操作绑定之前立即绑定的管道?或者根本无法保证二级命令缓冲区的执行顺序?

is a guaranteed no-op to bind the pipeline that was immediately bound before?

没有。事实上,如果您正在概述,您应该恰好假设 相反 。为什么?

由于您的每个 CB 都与其他 CB 相互隔离,因此 vkCmdBindPipeline 函数无法知道事先绑定了什么。请记住:已开始记录的命令缓冲区的状态是 undefined。这意味着命令缓冲区构建代码无法对您未在此 CB 中设置的任何状态做出任何假设。

为了让驱动程序实现您正在谈论的优化,它必须在 vkCmdExecuteCommands 时间检查每个辅助命令缓冲区并开始删除跨 CB 边界复制的任何内容.

如果 vkCmdExecuteCommands 必须将所有命令从辅助 CB 复制到主要命令,那么 可能 可行。但这仅适用于硬件级别不存在辅助 CB 的系统,因此必须通过将其命令复制到主 CB 来实现。但即使在这种情况下,与简单地将一些令牌复制到主 CB 的存储中相比,实施这种剔除会使命令执行时间更长。

在处理低级别 API 时,不要假设驱动程序将使用其直接权限之外的信息来优化您的代码。 特别是当您拥有自己进行优化的工具时。

这是(又一个)为什么你不应该给每个单独的对象它自己的 CB 的原因。

Or the order of execution of the secondary command buffers is not guaranteed at all?

命令的执行顺序不会因它们在 CB 中的存在而改变。但是,这些命令使用 的状态的定义明确的性质受到 的影响。

除了次级 CB 继承的状态之外,每个次级 CB 的状态开始时都是未定义的。这就是 为什么 你必须为每个管道绑定一个管道。如果先前发布的状态在包含该命令的 CB 内(或继承状态),则依赖先前发布的状态的命令只有明确定义的行为。