为什么我的渲染过程无法过渡到最终布局

问题描述

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

  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(错误/ SPEC):msgNum:-945112042-验证错误:[VUID-VkPresentInfoKHR-pImageIndices-01296]对象0:句柄= 0x55eeaedf2f90,名称= present_queue,类型= VK_OBJECT; | MessageID = 0xc7aabc16 | vkQueuePresentKHR():传递给当前的图像必须位于布局VK_IMAGE_LAYOUT_PRESENT_SRC_KHR或VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR中,但位于VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL中。 Vulkan规范指出:pImageIndices的每个元素必须是从由pSwapchains数组的相应元素指定的交换链获取的可显示图像的索引,并且在执行操作时,所显示的图像子资源必须位于VK_IMAGE_LAYOUT_PRESENT_SRC_KHR布局中VkDevice(https://github.com/KhronosGroup/Vulkan-Docs/search?q=)VUID-VkPresentInfoKHR-pImageIndices-01296)

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

在我的出席演讲中,我将这两个信号作为等待信号传递。 有人在我的子通道依赖项中看到明显的错误,该错误会导致这种错误的行为吗?如果其他问题可能导致此错误(我在这里没有提到),请告诉我,我将很乐意提供相应的代码节。

解决方法

原来,我在代码的一部分中做的非常愚蠢,没有立即连接到任何渲染通道。

在检索新框架的索引之前,我基本上要求提供当前框架的与ui相关的VkCommandBuffer。这意味着我重新记录并重新提交了VkCommandBuffer,它尚未完成对上一帧的ui渲染。

这还引发了以下验证错误,起初我并没有立即发现该错误(事后看来很愚蠢)

VUID-vkResetCommandPool-commandPool-00040(ERROR / SPEC):msgNum:-1254218959-验证错误:[VUID-vkResetCommandPool-commandPool-00040]对象0:句柄= 0x55f944a47040,名称= ui_cmd_buffer_0,类型= VK_OBJECT_TYPE | MessageID = 0xb53e2331 |尝试使用正在使用的VkCommandBuffer 0x55f944a47040 [ui_cmd_buffer_0]重置命令池。 Vulkan规范指出:从commandPool分配的所有VkCommandBuffer对象都不得处于挂起状态(https://vulkan.lunarg.com/doc/view/1.2.148.0/linux/1.2-extensions/vkspec.html#VUID-vkResetCommandPool-commandPool-00040) 对象:1 [0] 0x55f944a47040,类型:6,名称:ui_cmd_buffer_0

所以我想外卖是: 如果您确定子传递相关性以及渲染传递的initialLayoutfinalLayout的规范很好,请查看与vkQueueSubmit和{{ 1}},这可能会造成麻烦。

在我的情况下,它是重新提交的vkQueuePresentKHR,但是您的栅栏或信号灯中的问题(试图渲染为仍由前一帧呈现/呈现的交换链图像)也可能导致这样的问题。

如果您遇到多个验证错误,那么假设它们之间存在联系,并尝试确定哪个错误可能导致另一个错误,可能不是一个坏主意。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...