如何停止命令缓冲区之间的清除?

How to stop clearing between command buffers?

我试图让 ImGui 在我的引擎中工作,但在我的立方体网格上遇到了一些问题 "overlaying"。我将两者分开在单独的命令缓冲区中,例如

std::array<VkCommandBuffer, 2> cmdbuffers = { commandBuffers[imageIndex], imguicmdbuffers[imageIndex] };

然后在我的队列提交信息中,我将命令缓冲区计数设置为 2 并像这样将数据传递给它

submitInfo.commandBufferCount = 2;
submitInfo.pCommandBuffers = cmdbuffers.data();

但是现在发生的情况是它只渲染 imgui,或者如果我切换数组中的顺序它只渲染立方体,而不会同时渲染两者。是因为它们共享相同的渲染通道吗?我将 VkRenderPassBeginInfo 清除颜色更改为仔细检查,确实它清除黄色并绘制 imgui 或清除红色并绘制立方体。我试过将 clear alpha 设置为 0,但这不起作用,而且看起来像是 hack。我觉得我对它如何提交和执行命令缓冲区以及它如何与渲染相关联 passes/framebuffers 缺乏了解,所以怎么了?

鉴于以下陈述(即假设它们是准确的):

  • they share the same render pass

  • in my queue submit info I put the command buffer count to 2

  • VkRenderPassBeginInfo clear color

有关渲染性质的某些事情变得显而易见(您没有直接声明或提供代码的事情)。首先,您将两个单独的命令缓冲区直接提交到队列。只有主命令缓冲区可以提交到队列。

其次,根据渲染过程的性质,渲染过程实例不能跨越主命令缓冲区。所以你必须有两个渲染通道实例。

第三,您指定可以在开始渲染过程实例时更改图像的清晰颜色。因此,渲染过程必须指定图像作为其加载操作被清除。

根据所有这些,我得出结论,您开始时是相同的 VkRenderPass 两次。如前所述,渲染通道在渲染通道实例的开头设置为 清除图像。这将尽职尽责地发生两次,第二次将清除事先渲染到该图像的所有内容。

基本上,您有两个渲染操作,使用一个渲染通道,该渲染通道设置为销毁由任何先前渲染操作创建的数据到它使用的图像。那是行不通的。

您有几种解决方法。

我的首选方法是开始使用辅助命令缓冲区。我不知道是否可以给 ImGui 一个 CB 来记录它的数据。但如果可以的话,我建议将其数据记录到辅助 CB 中。然后,您可以将该辅助 CB 执行到渲染通道的适当子通道中。因此,您无需提交两个主要 CB;你只提交一个。

或者,您可以制作一个新的 VkRenderPass,它不会清除之前的图像;它应该加载图像数据。您的第二个渲染操作将使用该渲染通道,而您的初始渲染操作将保留清晰的加载操作。

最坏的情况,您可以让第二个操作渲染到完全不同的图像,然后在第三个渲染操作中将其与主图像合并。