Pipeline 并行性

- 多个 Pipeline 可以并行执行
- 同一个 Pipeline 的不同阶段可以并行
- 不同的 Shader 调用可以并行

Pipeline Barrier 的主要作用

  • 确保内存访问顺序
  • 处理资源布局转换
  • 处理队列所有权转移
  • 处理资源的访问依赖

具体例子

// 场景:将图像从一个布局转换到另一个布局
VkImageMemoryBarrier barrier = {};
barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
barrier.srcAccessMask = 0;  // 之前的访问
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;  // 之后的访问
 
vkCmdPipelineBarrier(
    commandBuffer,
    VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,      // 源阶段
    VK_PIPELINE_STAGE_TRANSFER_BIT,          // 目标阶段
    0,
    0, nullptr,         // Memory barriers
    0, nullptr,         // Buffer barriers
    1, &barrier         // Image barriers
);

实际同步示意

Pipeline A:  Vertex -> Fragment -> ColorAttachmentOutput
                                     ↓ (barrier)
Pipeline B:  Vertex -> Fragment -> ColorAttachmentOutput

常见使用场景

写入后读取同步

// 确保写入完成后才开始读取
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;

布局转换

// 转换图像布局以优化特定操作
barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

队列所有权转移

// 在不同队列族之间转移资源所有权
barrier.srcQueueFamilyIndex = graphicsQueueFamily;
barrier.dstQueueFamilyIndex = computeQueueFamily;

重要概念

  • Pipeline Stage:指定同步点
  • Access Mask:指定内存访问类型
  • Dependencies:指定操作间的依赖关系

总结

Pipeline Barriers 不是简单地同步所有管线的某个阶段,而是提供了一个细粒度的同步机制,允许你:

  1. 精确控制内存访问顺序
  2. 处理资源状态转换
  3. 管理不同队列间的资源访问
  4. 优化性能(通过最小化同步范围)