为什么我的渲染过程没有过渡到最终布局

Why is my render-pass not transitioning into final layout

我目前正在尝试将 imgui 合并到我的 vulkan 应用程序中。 所以我有两个渲染通道,一个用于我的 3d 场景,一个用于 imgui。 在我的 3d-renderpass 中,我将 initialLayout 设置为 undefined,将 finalLayout 设置为 attachmentOptimal。 在 imgui-renderpass 中,我将 initialLayout 设置为 attachmentOptimal,将 finalLayout 设置为 presentSrcKHR。 我还创建了以下子通道依赖项: 对于我的 3d-renderpass:

  auto dependency = vk::SubpassDependency{};
  dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
  dependency.srcAccessMask = (vk::AccessFlags)0;
  dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
  dependency.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
  dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
  dependency.dstSubpass = 0;

  auto ui_dependency = vk::SubpassDependency{};
  ui_dependency.srcStageMask =
    vk::PipelineStageFlagBits::eColorAttachmentOutput;
  ui_dependency.srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
  ui_dependency.srcSubpass = 0;
  ui_dependency.dstStageMask =
    vk::PipelineStageFlagBits::eColorAttachmentOutput;
  ui_dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite |
                                vk::AccessFlagBits::eColorAttachmentRead;
  ui_dependency.dstSubpass = VK_SUBPASS_EXTERNAL;

对于 imgui-renderPass:

  auto dependency = vk::SubpassDependency();

  dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
  dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
  dependency.srcAccessMask = vk::AccessFlagBits::eColorAttachmentRead |
                               vk::AccessFlagBits::eColorAttachmentWrite;

  dependency.dstSubpass = 0;
  dependency.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
  dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;

  auto extern_dependeny = vk::SubpassDependency{};

  extern_dependeny.srcSubpass = 0;
  extern_dependeny.srcStageMask =
  vk::PipelineStageFlagBits::eColorAttachmentOutput;
  extern_dependeny.srcAccessMask = vk::AccessFlagBits::eColorAttachmentRead |
                                     vk::AccessFlagBits::eColorAttachmentWrite;

  extern_dependeny.dstSubpass = VK_SUBPASS_EXTERNAL;
  extern_dependeny.dstStageMask =
  vk::PipelineStageFlagBits::eColorAttachmentOutput;

  extern_dependeny.dstAccessMask = vk::AccessFlagBits::eMemoryRead;

所以我认为我正确定义了渲染通道的依赖关系。 但是,当我提交两个命令缓冲区时,一个用于 3d 场景,一个用于 imgui,验证层告诉我:

VUID-VkPresentInfoKHR-pImageIndices-01296(ERROR / SPEC): msgNum: -945112042 - Validation Error: [ VUID-VkPresentInfoKHR-pImageIndices-01296 ] Object 0: handle = 0x55eeaedf2f90, name = present_queue, type = VK_OBJECT_TYPE_QUEUE; | MessageID = 0xc7aabc16 | vkQueuePresentKHR(): Images passed to present must be in layout VK_IMAGE_LAYOUT_PRESENT_SRC_KHR or VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR but is in VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL. The Vulkan spec states: Each element of pImageIndices must be the index of a presentable image acquired from the swapchain specified by the corresponding element of the pSwapchains array, and the presented image subresource must be in the VK_IMAGE_LAYOUT_PRESENT_SRC_KHR layout at the time the operation is executed on a VkDevice (https://github.com/KhronosGroup/Vulkan-Docs/search?q=)VUID-VkPresentInfoKHR-pImageIndices-01296)

请注意,我确实提交了带有两个信号量的命令缓冲区,管道阶段标志分别为 colorAttachmentOutputBottomOfPipe

在我的演讲中,我将这两个信号量作为等待信号量传递。 有没有人在我的 subpass-dependencies 中看到会导致这种不正确行为的明显错误?如果其他问题可能导致此错误(我在此未提及),请告诉我,我将很乐意提供相应的代码部分。

原来我在代码的一部分做了一些非常愚蠢的事情,没有立即连接到任何render-passes。

我基本上是在检索新帧的索引之前询问当前帧的 ui-related VkCommandBuffer。这意味着我 re-recorded 和 re-submitted 一个 VkCommandBuffer 尚未完成前一帧 ui 的渲染。

这也触发了以下 validation-error,起初我没有立即将其与问题联系起来(事后看来可能很愚蠢)

VUID-vkResetCommandPool-commandPool-00040(ERROR / SPEC): msgNum: -1254218959 - Validation Error: [ VUID-vkResetCommandPool-commandPool-00040 ] Object 0: handle = 0x55f944a47040, name = ui_cmd_buffer_0, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0xb53e2331 | Attempt to reset command pool with VkCommandBuffer 0x55f944a47040[ui_cmd_buffer_0] which is in use. The Vulkan spec states: All VkCommandBuffer objects allocated from commandPool must not be in the pending state (https://vulkan.lunarg.com/doc/view/1.2.148.0/linux/1.2-extensions/vkspec.html#VUID-vkResetCommandPool-commandPool-00040) Objects: 1 [0] 0x55f944a47040, type: 6, name: ui_cmd_buffer_0

所以我想要点是: 如果您确定 subpass-dependencies 以及 render-passes 的 initialLayoutfinalLayout 的规格没问题,请查看与 [=14= 相关的代码的其他部分] 和 vkQueuePresentKHR,这可能会导致问题。

在我的例子中,它是一个 re-submitted VkCommandBuffer,但是你的围栏或信号量有问题(试图渲染到一个 swapchain-image,它仍然由一个前一帧)也可能导致此类问题。

如果您得到多个 validation-errors,假设它们之间存在某种关系并尝试确定哪个错误可能导致另一个错误可能是个不错的主意。