LeonTheProfessional
LeonTheProfessional

Reputation: 374

Why is my render-pass not transitioning into final layout

I am currently trying to incorporate imgui into my vulkan-application. So i have two render-passes, one for my 3d-scene, and one for imgui. In my 3d-renderpass i set initialLayout to undefined and finalLayout to attachmentOptimal. In the imgui-renderpass i set initialLayout to attachmentOptimal and finalLayout to presentSrcKHR. I also create the following subpass-dependencies: For my 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;

and for the 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;

So i would think that i am correctly defining the dependencies of the render-passes. However, when i submit the two command-buffers, one for the 3d-scene, one for imgui, the validation-layers tell me:

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)

Note that i do submit the command-buffers with two signal-semaphores, with the pipeline-stage-flags of colorAttachmentOutput and BottomOfPipe respectively.

In my call to present, i pass both of these semaphores as wait-semaphores. Does anyone see an obvious error in my subpass-dependencies that would lead to this incorrect behaviour? If other issues could contribute to this error, which i have not mentioned here, let me know and i will happily provide respective code-sections.

Upvotes: 0

Views: 522

Answers (1)

LeonTheProfessional
LeonTheProfessional

Reputation: 374

Turns out I was doing something extremely stupid in a part of the code not immediately connected to any of the render-passes.

I basically asked for the ui-related VkCommandBuffer of the current frame before retrieving the index for the new frame. This meant that I re-recorded, and re-submitted a VkCommandBuffer which had not finished executing the rendering of the ui for the previous frame.

This also triggered the following validation-error, which at first I did not take to be immediately connected to the issue (probably stupid in hindsight)

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

So i guess the takeaway is: If you are sure that the subpass-dependencies, and the specifications of initialLayout and finalLayout of your render-passes are fine, look at other parts of your code related to vkQueueSubmit and vkQueuePresentKHR, which might cause the trouble.

In my case it was a re-submitted VkCommandBuffer, but problems in your fences or semaphores (trying to render to a swapchain-image that is still presented from/ rendered to by a previous frame) may also lead to such problems.

If you get multiple validation-errors it is probably not a bad idea to assume a relation between them, and try to identify which error might cause another one.

Upvotes: 0

Related Questions