PAYATHON 2026

VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT 为什么包含 blending?

数据小陈

VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT 涵盖 blending,因为混合计算可能需要读取颜色附件中已有的目标颜色。将混合结果写回附件则属于 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT。一次操作可以同时包含读访问和写访问。

blending 为什么需要读取颜色附件?

问题中引用的定义列举了会产生颜色附件读访问的操作,其中包括 blending。

以常见的非预乘 Alpha 混合为例,RGB 分量可以按下面的公式计算:

C_out = C_src * alpha_src + C_dst * (1 - alpha_src)

这里:

  • C_src 是 fragment shader 输出的源颜色。
  • C_dst 是颜色附件中对应位置已有的目标颜色。
  • C_out 是混合后的颜色。

计算需要用到 C_dst,因此会读取附件中的旧值;写入 C_out 时又会产生写访问。Vulkan 规范将目标颜色定义为当前 fragment/sample 对应的颜色附件中的颜色,见颜色混合规范。

READ 和 WRITE 分别描述什么?

这两个标志描述同步范围内的访问类型,可以同时使用:

访问行为对应标志
为混合计算读取已有的目标颜色VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT
将混合结果写入颜色附件VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT

WRITE_BIT 涵盖 render pass 期间对颜色附件的写入,以及规范规定的某些 load、store 和 resolve 操作,并非仅指 render pass 结束时的 store。具体定义见 VkAccessFlagBits2。

定义中提到的 load 也不能简单理解为所有 load operations 都属于读访问;需要根据具体操作判断。

同步时怎样表达这类访问?

如果某个依赖的目标操作会读取已有颜色并写入混合结果,可以在目标访问范围中同时包含这两个标志。例如,下面只展示一个已配置的 VkImageMemoryBarrier2 的目标阶段和访问掩码:

barrier.dstStageMask =
    VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;

barrier.dstAccessMask =
    VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT |
    VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;

这个依赖的目标访问范围包含颜色附件输出阶段的读取和写入。访问掩码用于描述同步范围;是否执行 blending 由混合状态决定。

实际配置时,需要依次确认:

  1. 之前是哪种操作产生了需要保留的附件内容,据此设置源阶段和源访问掩码。
  2. 后续操作是否读取已有目标颜色,以及是否写入结果,据此选择目标访问掩码。
  3. 图像布局、子资源范围和依赖位置是否符合当前渲染方式的要求。

这个片段只展示了 barrier 的一部分。是否需要显式依赖取决于已有同步关系,开启 blending 不一定需要额外插入 barrier。

注意适用范围

这里讨论的是依赖目标颜色的普通 blending。原定义明确排除了 advanced blend operations,不能直接将上述说明套用于它们。

普通颜色附件 blending 对应 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT。原定义中提到的 fragment shader tile image reads 则发生在 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,配置同步时要区分这两种访问路径。

备注:内容仅供参考。