微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Vulkan - 在 vkCmdPipelineBarrier 命令中设置的渲染通道中存在哪些“阶段”

如何解决Vulkan - 在 vkCmdPipelineBarrier 命令中设置的渲染通道中存在哪些“阶段”

从渲染通道提交 srcStageMask/dstStageMask 时可以为 vkCmdPipelineBarrier 设置哪些阶段,因为在这种情况下,没有子通道绑定点到图形管道?

在 subpass 中提交 vkCmdPipelineBarrier 时的相同问题,它具有到计算管道的绑定点,我猜它没有像 VK_PIPELINE_STAGE_VERTEX_SHADER_BIT 这样的阶段,也许还有更多。

谢谢

编辑

首先,感谢@Nicol Bolas 的评论无法在 subpass 中间调度计算着色器

我想澄清一下我的问题:

假设我有一个图像,在渲染通道之后将具有 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL 的布局。

renderpass 之后,我想用新数据更新图像,并希望将其布局更改为 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL。

因此,在记录 vkCmdEndRenderPass 之后,我记录了一个 vkCmdPipelineBarrier 命令,如下所示:

const VkImageMemoryBarrier imageMemoryBarrier =
{
    VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,     
    nullptr,                                    
    VK_ACCESS_SHADER_READ_BIT,                  // srcAccessMask
    VK_ACCESS_TRANSFER_WRITE_BIT,               // dstAccessMask
    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,   // oldLayout
    VK_IMAGE_LAYOUT_TRANSFER_DST_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(currentCommandBuffer,                     VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,                     VK_PIPELINE_STAGE_TRANSFER_BIT,                     0,nullptr,                     1,&imageMemoryBarrier);

这确保只要渲染过程中的前一个命令仍未跨越片段着色器阶段,过渡就会等待。

但是如果 vulkan 在 renderpass 执行完成后执行 vkCmdPipelineBarrier 呢?现在没有绑定管道,没有阶段 - 这是否意味着屏障将进入无休止的等待,直到新的渲染通道开始并且片段着色器阶段才会发生?

解决方法

只需检查 Valid Usage

所有这些都是允许的,除了那些在整个设备上禁用其功能的(例如几何着色器),或者队列系列不支持的那些。

对于 subpass 依赖项,仅允许 pipelineBindPoint 管道支持的那些(即目前只有图形)。


我认为让您深感困惑的主要问题是您认为管道是一个有限状态机。但是管道不是 FSM,它是一个管道(顾名思义)。它始终存在(就像它的所有阶段一样),即使当前没有任何东西流经管道。

具体来说,在英语中你的障碍只是简单地说:“在我开始复制到这个图像之后记录的任何命令之前,确保在我完成读取这个图像之前记录的所有命令作为纹理。”

当阶段“存在”不是一个有效的问题时(如上所述);存在和不存在并不是他们真正拥有的属性。正如您在屏障的语义中看到的那样,改变其含义甚至都无关紧要。

某些阶段被有效用法所禁止,但这比减少混乱更重要。即使没有被禁止,也不会改变什么。此类阶段的障碍可能只是无操作,或者在逻辑上会转化为更早或更晚的阶段。

,

如果一切正常,那么您要同步的内容如下:
您希望确保在前面的渲染通道完成读取图像之前,图像不会被新数据覆盖。

为了实现这一点,您设置了同步的障碍

Execution:   FRAGMENT_SHADER            ->   TRANSFER
Memory:      SHADER_READ                ->   TRANSFER_WRITE
Layout:      SHADER_READ_ONLY_OPTIMAL   ->   TRANSFER_DST_OPTIMAL

虽然这些同步参数确保了正确性,但它们实际上有点多余。 srcAccessMask 用于需要“使可用”的内存,即~转移到 L2 内存中,以便之后可以访问。

这是你的barrier中不需要的部分,因为内存已经可用(在L2内存中),否则无法正确读取。

即最佳障碍如下:

Execution:   FRAGMENT_SHADER            ->   TRANSFER
Memory:      0                          ->   TRANSFER_WRITE
Layout:      SHADER_READ_ONLY_OPTIMAL   ->   TRANSFER_DST_OPTIMAL

现在是关于

的问题

但是如果 vulkan 在 renderpass 执行完成后执行 vkCmdPipelineBarrier 怎么办?

上面记录的障碍告诉您的 GPU 如下:

  • 在当前队列中,等待具有 FRAGMENT_SHADER 阶段的所有前面的命令完成其 FRAGMENT_SHADER 阶段,然后再继续其 TRANSFER 阶段中的后续命令。

这也意味着:

  • 如果队列中没有先前的命令,则屏障的要求已经满足,后续命令的执行可以立即继续。
  • 如果队列中有可能不会通过 FRAGMENT_SHADER 阶段的命令,我们不会等待它们。
  • 屏障适用于已提交到队列的每个命令。 (但大多数命令将不再处于“执行中”状态,而是已经被删除,因为它们已完成执行。)屏障的 src 依赖项从不指的是可能被提交的东西以后,只针对之前提交过的内容。

如果您对这些事情有困难,您可能想看看 Introduction to Vulkan 讲座,其中涵盖了从 22:28 开始的此类同步主题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?