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 不是简单地同步所有管线的某个阶段,而是提供了一个细粒度的同步机制,允许你:
- 精确控制内存访问顺序
- 处理资源状态转换
- 管理不同队列间的资源访问
- 优化性能(通过最小化同步范围)