问题描述
我目前正在尝试将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)
请注意,我确实提交了带有两个信号量的命令缓冲区,分别带有colorAttachmentOutput
和BottomOfPipe
的流水线阶段标志。
在我的出席演讲中,我将这两个信号作为等待信号传递。 有人在我的子通道依赖项中看到明显的错误,该错误会导致这种错误的行为吗?如果其他问题可能导致此错误(我在这里没有提到),请告诉我,我将很乐意提供相应的代码节。
解决方法
原来,我在代码的一部分中做的非常愚蠢,没有立即连接到任何渲染通道。
在检索新框架的索引之前,我基本上要求提供当前框架的与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
所以我想外卖是:
如果您确定子传递相关性以及渲染传递的initialLayout
和finalLayout
的规范很好,请查看与vkQueueSubmit
和{{ 1}},这可能会造成麻烦。
在我的情况下,它是重新提交的vkQueuePresentKHR
,但是您的栅栏或信号灯中的问题(试图渲染为仍由前一帧呈现/呈现的交换链图像)也可能导致这样的问题。
如果您遇到多个验证错误,那么假设它们之间存在联系,并尝试确定哪个错误可能导致另一个错误,可能不是一个坏主意。