【问题标题】:Can I record vkCmdPipelineBarrier multiple times in a command buffer?我可以在命令缓冲区中多次记录 vkCmdPipelineBarrier 吗?
【发布时间】:2019-05-10 22:29:23
【问题描述】:

我有一个来自vkSwapchainvkImage。我的目标很简单,只是在这张图片中渲染一个三角形。所以我创建了一个命令缓冲区并记录为以下命令。

  1. vkBeginCommandBuffer
  2. vkCmdPipelineBarrier(从LAYOUT_UNDEFINEDCOLOR_ATTACHMENT_OPTIMAL
  3. vkCmdBeginRenderPass
  4. 画出我的三角形。
  5. vkCmdEndRenderPass
  6. vkCmdPipelineBarrier(从COLOR_ATTACHMENT_OPTIMALPRESENT_SRC
  7. vkEndCommandBuffer

最后我打电话给vkQueueSubmit 在屏幕上显示一个三角形。但是当 second vkCmdPipelineBarrier 执行时,验证层会说:

VUID-VkImageMemoryBarrier-oldLayout-01197:对于图像 0x4,当先前的已知布局为 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR 时,您无法从 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL 转换 aspect=1 level=0 layer=0 的布局。

UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout:提交的命令缓冲区需要图像 0x4(子资源:aspectMask 0x1 数组第 0 层,mip 级别 0)在布局 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL--相反,当前布局是 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR

但我确定当时的图像布局将是COLOR_ATTACHMENT_OPTIMAL。我不知道为什么验证层向我抱怨。

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

下面是我的代码。

//////////////////////////////////////////////////////
// First layout transition
//////////////////////////////////////////////////////
VkImageMemoryBarrier vkGraphicsImageMemoryBarrier
{
    VkStructureType::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
    nullptr,
    0,
    VkAccessFlagBits::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
    VkImageLayout::VK_IMAGE_LAYOUT_UNDEFINED,
    VkImageLayout::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
    VK_QUEUE_FAMILY_IGNORED,
    VK_QUEUE_FAMILY_IGNORED,
    this->sSwapchain.vulkanImageList()[nImageIndex],
    VkImageSubresourceRange
    {
        VkImageAspectFlagBits::VK_IMAGE_ASPECT_COLOR_BIT,
        0,
        VK_REMAINING_MIP_LEVELS,
        0,
        VK_REMAINING_ARRAY_LAYERS
    }
};

vkCmdPipelineBarrier(
    this->sGraphicsCommandBufferList[nImageIndex],
    VkPipelineStageFlagBits::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
    VkPipelineStageFlagBits::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
    0,
    0, nullptr,
    0, nullptr,
    1, &vkGraphicsImageMemoryBarrier);

//
//  Draws a triangle.
//

//////////////////////////////////////////////////////
// Second layout transition and ownership transfer
//////////////////////////////////////////////////////
VkImageMemoryBarrier vkGraphicsImageMemoryBarrier
{
    VkStructureType::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
    nullptr,
    VkAccessFlagBits::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
    0,
    VkImageLayout::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
    VkImageLayout::VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
    this->nGraphicsFamily,
    this->nPresentFamily,
    this->sSwapchain.vulkanImageList()[nImageIndex],
    VkImageSubresourceRange
    {
        VkImageAspectFlagBits::VK_IMAGE_ASPECT_COLOR_BIT,
        0,
        VK_REMAINING_MIP_LEVELS,
        0,
        VK_REMAINING_ARRAY_LAYERS
    }
};
VkImageMemoryBarrier vkPresentImageMemoryBarrier
{
    VkStructureType::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
    nullptr,
    0,
    0,
    VkImageLayout::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
    VkImageLayout::VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
    this->nGraphicsFamily,
    this->nPresentFamily,
    this->sSwapchain.vulkanImageList()[nImageIndex],
    VkImageSubresourceRange
    {
        VkImageAspectFlagBits::VK_IMAGE_ASPECT_COLOR_BIT,
        0,
        VK_REMAINING_MIP_LEVELS,
        0,
        VK_REMAINING_ARRAY_LAYERS
    }
};

//
//  Below call produces the above validation message.
//
vkCmdPipelineBarrier(
    this->sGraphicsCommandBufferList[nImageIndex],
    VkPipelineStageFlagBits::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
    VkPipelineStageFlagBits::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
    0,
    0, nullptr,
    0, nullptr,
    1, &vkGraphicsImageMemoryBarrier);
vkCmdPipelineBarrier(
    this->sPresentCommandBufferList[nImageIndex],
    VkPipelineStageFlagBits::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
    VkPipelineStageFlagBits::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
    0,
    0, nullptr,
    0, nullptr,
    1, &vkPresentImageMemoryBarrier);

尽管有验证错误消息,我还是渲染了一个三角形。这是验证层的错误吗?

任何帮助将不胜感激。

【问题讨论】:

    标签: c++ vulkan


    【解决方案1】:

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

    但是,不需要特定的屏障,因为渲染通道可以隐式地完成相同的屏障。验证抱怨图像的布局已经存在这一事实意味着您已经以这种方式进行了设置。创建渲染通道时检查附件的finalLayout。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-09
      • 2018-07-31
      • 1970-01-01
      • 2015-07-14
      • 1970-01-01
      • 2020-02-08
      相关资源
      最近更新 更多