C++ 我可以在命令缓冲区中多次记录vkCmdPipelineBarrier吗?

C++ 我可以在命令缓冲区中多次记录vkCmdPipelineBarrier吗?,c++,vulkan,C++,Vulkan,我有一个vkSwapchain中的vkImage。我的目标很简单,就是把一个三角形渲染成这个图像。因此,我创建了一个命令缓冲区,并按以下顺序记录 vkbegincommanndbuffer vkCmdPipelineBarrier(从未定义的布局到颜色(附件) vkCmdBeginRenderPass 画我的三角形 vkCmdEndRenderPass vkCmdPipelineBarrier(从COLOR\u ATTACHMENT\u OPTIMAL到PRESENT\u SRC) vkEndC

我有一个
vkSwapchain
中的
vkImage
。我的目标很简单,就是把一个三角形渲染成这个图像。因此,我创建了一个命令缓冲区,并按以下顺序记录

  • vkbegincommanndbuffer
  • vkCmdPipelineBarrier
    (从
    未定义的布局
    颜色(附件)
  • vkCmdBeginRenderPass
  • 画我的三角形
  • vkCmdEndRenderPass
  • vkCmdPipelineBarrier
    (从
    COLOR\u ATTACHMENT\u OPTIMAL
    PRESENT\u SRC
  • vkEndCommandBuffer
  • 最后,我调用
    vkQueueSubmit
    在屏幕上得到一个三角形。但是当执行第二个vkCmdPipelineBarrier时,验证层会说:

    VUID-VkImageMemoryBarrier-oldLayout-01197:对于图像0x4,当先前已知的布局为
    VK\U图像\U布局存在\u SRC\u KHR
    时,无法将aspect=1 level=0 layer=0的布局从
    VK\U图像\U布局\u颜色\u附件\u优化转换为

    未分配的CoreValidation DrawState InvalidImageLayout:Submitted命令缓冲区期望图像0x4(子资源:aspectMask 0x1数组层0,mip级别0)位于布局
    VK_图像\u布局\u颜色\u附件\u最优
    ——相反,当前布局是
    VK_图像\u布局\u存在\u SRC\u KHR

    但我相信届时图像布局将是最佳的。我不知道你为什么向我抱怨

    我已经搜索了API文档,但找不到
    vkCmdPipelineBarrier
    的任何限制。他们说这个命令执行队列所有权转移(如果需要)和布局转换

    下面是我的代码

    //////////////////////////////////////////////////////
    //第一次布局转换
    //////////////////////////////////////////////////////
    vkGraphicsImageMemoryBarrier vkGraphicsImageMemoryBarrier
    {
    VkStructureType::VK_结构_类型_图像_内存_屏障,
    nullptr,
    0,
    VkAccessFlagBits::VK\访问\颜色\附件\写入\位,
    VkImageLayout::VK_图像_布局_未定义,
    VKIMAGELAYOU::VK_图像_布局_颜色_附件_最佳,
    VK_队列_族_忽略,
    VK_队列_族_忽略,
    此->sSwapchain.vulkanImageList()[nImageIndex],
    VkImageSubresourceRange
    {
    VkImageAspectFlagBits::VK_图像_方面_颜色_位,
    0,
    VK_剩余的MIP_水平,
    0,
    VK_剩余_阵列_层
    }
    };
    VKCmd管线屏障(
    此->sGraphicsCommandBufferList[nImageIndex],
    VkPipelineStageFlagBits::VK\管道\阶段\颜色\附件\输出\位,
    VkPipelineStageFlagBits::VK\管道\阶段\颜色\附件\输出\位,
    0,
    0,空ptr,
    0,空ptr,
    1、&vkgramphicsimagememorybarrier);
    //
    //画一个三角形。
    //
    //////////////////////////////////////////////////////
    //二次布局转换与所有权转移
    //////////////////////////////////////////////////////
    vkGraphicsImageMemoryBarrier vkGraphicsImageMemoryBarrier
    {
    VkStructureType::VK_结构_类型_图像_内存_屏障,
    nullptr,
    VkAccessFlagBits::VK\访问\颜色\附件\写入\位,
    0,
    VKIMAGELAYOU::VK_图像_布局_颜色_附件_最佳,
    VKIMAGELAYOU::VK_图像_布局_呈现_SRC_KHR,
    这个家庭,
    本->N PresentFamily,
    此->sSwapchain.vulkanImageList()[nImageIndex],
    VkImageSubresourceRange
    {
    VkImageAspectFlagBits::VK_图像_方面_颜色_位,
    0,
    VK_剩余的MIP_水平,
    0,
    VK_剩余_阵列_层
    }
    };
    VkImageMemoryBarrier vkPresentImageMemoryBarrier
    {
    VkStructureType::VK_结构_类型_图像_内存_屏障,
    nullptr,
    0,
    0,
    VKIMAGELAYOU::VK_图像_布局_颜色_附件_最佳,
    VKIMAGELAYOU::VK_图像_布局_呈现_SRC_KHR,
    这个家庭,
    本->N PresentFamily,
    此->sSwapchain.vulkanImageList()[nImageIndex],
    VkImageSubresourceRange
    {
    VkImageAspectFlagBits::VK_图像_方面_颜色_位,
    0,
    VK_剩余的MIP_水平,
    0,
    VK_剩余_阵列_层
    }
    };
    //
    //下面的调用生成上面的验证消息。
    //
    VKCmd管线屏障(
    此->sGraphicsCommandBufferList[nImageIndex],
    VkPipelineStageFlagBits::VK\管道\阶段\颜色\附件\输出\位,
    VkPipelineStageFlagBits::VK_管道_阶段_底部_管道_钻头,
    0,
    0,空ptr,
    0,空ptr,
    1、&vkgramphicsimagememorybarrier);
    VKCmd管线屏障(
    此->sPresentCommandBufferList[nImageIndex],
    VkPipelineStageFlagBits::VK_管道_阶段_顶部_管道_位,
    VkPipelineStageFlagBits::VK_管道_阶段_底部_管道_钻头,
    0,
    0,空ptr,
    0,空ptr,
    1、&vkPresentImageMemoryBarrier);
    
    尽管有验证错误消息,我还是得到了一个三角形。这是验证层错误吗


    任何帮助都将不胜感激。

    您可以在命令缓冲区中记录的管道屏障数量没有限制(内存限制除外)

    但是,不需要特定的屏障,因为相同的屏障可以由renderpass隐式完成。验证抱怨图像的布局已经存在,这意味着您已经以这种方式进行了设置。创建renderpass时检查附件的最终显示