我没有正确理解如何在Vulkan中的单独线程上并行化工作.
要开始发布vkCmd*s,您需要开始渲染通道.开始渲染传递的调用需要对帧缓冲区的引用.但是,不保证vkAcquireNextImageKHR()以循环方式返回图像索引.因此,在三缓冲设置中,如果当前图像索引为0,我不能只绑定帧缓冲区1并开始为下一帧发出绘制调用,因为下一次调用vkAcquireNextImageKHR()可能会返回图像索引2.
记录命令的正确方法是什么,而不必提前指定帧缓冲区?
您有一个或多个要每帧执行的渲染通道。每个通道都有一个或多个子通道,您需要在其中投入工作。因此,您的主渲染线程将为这些子通道生成一个或多个辅助命令缓冲区,并将该辅助 CB 序列传递给提交线程。
提交线程将创建渲染的主 CB。它开始/结束渲染通道,并在每个子通道中执行在渲染线程上为该特定子通道创建的辅助 CB。
因此每个线程都在创建自己的命令缓冲区。提交线程是处理 VkFramebuffer 对象的线程,因为它开始渲染过程。它还获取交换链图像等。渲染线程是生成执行所有实际工作的辅助 CB 的线程。
是的,您仍然会在提交线程上进行一些 CB 构建,但总体来说应该非常简约。这还可以从渲染线程中抽象出渲染目标的详细信息,以便处理交换链的代码可以本地化到提交线程。这为您提供了更大的灵活性。
例如,如果您想要三倍缓冲区,而交换链实际上不允许这样做,那么您的提交线程可以创建自己的额外图像,然后从其内部图像复制到真正的交换链中。渲染线程的代码根本不必受到干扰即可实现此目的。
您可以使用多个线程使用辅助命令缓冲区为同一个renderpass生成绘制命令.并且您可以在同一帧中并行生成不同渲染通道的工作 - 只有最后一遍(通常是后处理通过)取决于特定的交换链图像,所有阴影通道,gbuffer /阴影/光照通道,以及除了最后一个后处理传递没有.这不是必需的,但是在你已经准备好开始生成最终的渲染通道之后,甚至在你已经生成了许多先前的通道之后,甚至不调用vkAcquireNextImageKHR通常是个好主意.