何时更喜欢在渲染通道中使用 vkCmdPipelineBarrier 而不是子通道依赖?

问题描述

假设我们有两个子通道,其中第一个的渲染目标成为第二个中片段着色器的输入。

我们可以使用管道屏障来确保第二个子通道片段着色器不会开始读取图像,除非前一个子通道已经完成写入。

const VkImageMemoryBarrier imageMemoryBarriers =
{
    VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,nullptr,VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,// srcAccessMask
    VK_ACCESS_SHADER_READ_BIT,// dstAccessMask
    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,// oldLayout
    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,// newLayout
    VK_QUEUE_FAMILY_IGnorED,VK_QUEUE_FAMILY_IGnorED,image,{                                           // subresourceRange
        VK_IMAGE_ASPECT_COLOR_BIT,// aspectMask
        0,// baseMipLevel
        VK_REMAINING_MIP_LEVELS,// levelCount
        0,// baseArrayLayer
        VK_REMAINING_ARRAY_LAYERS               // layerCount
    }
};

vkCmdPipelineBarrier(m_currentCommandBuffer,VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,1,&imageMemoryBarrier);

但是我们可以使用 subpass 依赖来实现相同的同步,如下所示:

const VkSubpassDependency dependencies =
{
        0,// srcSubpass
        1,// dstSubpass
        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,// srcStageMask
        VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,// dstStageMask
        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,// srcAccessMask
        VK_ACCESS_SHADER_READ_BIT,// dstAccessMask
        VK_DEPENDENCY_BY_REGION_BIT                     // dependencyFlags
}

我有两个问题:

(1) 我读到使用 subpass 依赖是首选,为什么?似乎使用内存屏障缩小了仅针对特定图像的约束,而 subpass 依赖将同步应用于执行。这意味着当使用内存屏障时,GPU 避免等待其他涉及的图像,只等待屏障中设置的特定图像,而在子通道依赖中,阶段的执行正在等待,对于整个图像。

(2) 我们什么时候应该更喜欢在 subpass 中使用内存/执行屏障而不是 subpass 依赖?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)