在Vulkan中有几种处理同步的方法。这是我的理解方式:
就我而言,我有两个命令缓冲区。我希望第二个命令缓冲区在第一个之后执行。
submitInfo.pCommandBuffers = &firstCommandBuffer;
vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);
// wait for first command buffer to finish
submitInfo.pCommandBuffers = &secondCommandBuffer;
vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);
哪种同步最适合此?如果我使用的vkQueueWaitIdle(queue)),
是与使用篱笆相同的东西,还是应该为此使用事件或信号量?
如果我同时将多个命令缓冲区发送到队列:
std::vector<VkCommandBuffer> submitCmdBuffers = {
firstCommandBuffer,
secondCommandBuffer
};
submitInfo.commandBufferCount = submitCmdBuffers.size();
submitInfo.pCommandBuffers = submitCmdBuffers.data();
还有第一种和第二种之间同步的方法吗?
第一个命令缓冲区是在深度测试已打开的情况下渲染对象。第二个命令缓冲区是在深度测试关闭的情况下渲染网格轮廓。因为它必须在其他对象之上。
对于这种情况,您所需要的取决于这些命令缓冲区是什么。
如果这些是在同一渲染过程实例中执行的辅助命令缓冲区,则不需要任何同步化。除非您正在从辅助命令缓冲区中的深度纹理中手动读取,否则不会。为什么?
因为第2.2.1节的API订购可以保护您。渲染通道实例中的深度测试和深度写入将始终按API顺序进行。因此,以后的命令,无论是在同一个CB中还是在另一个CB中,都将针对深度测试/编写进行排序。
但是,如果需要从着色器读取深度缓冲区,或者命令缓冲区位于不同的渲染过程实例中,则需要通过事件进行显式同步。
在这种情况下,vkCmdSetEvent
命令的阶段掩码应为写入深度值的阶段。这可能是EARLY_FRAGMENT_TESTS_BIT
或LATE_FRAGMENT_TESTS_BIT
。为了安全起见,请同时使用两者。但是,由于您可能要更新相同的颜色缓冲区,因此也需要该COLOR_ATTACHMENT_OUTPUT_BIT
阶段。在第一个命令缓冲区的末尾(或在完成所有深度写入之后)插入此命令。
对于vkCmdWaitEvent
,您要等待需要它的管道阶段。在您的情况下,这又是碎片测试和颜色附件。但是,如果着色器阶段要读取深度,则在wait命令中也需要该阶段。
由于涉及内存,因此您vkCmdWaitEvent
还需要对深度和颜色缓冲区使用内存依赖性。
确实,所有这些复杂性就是为什么您应该尽可能将这些命令缓冲区放在同一渲染通道实例中的原因。您无法执行此操作的唯一原因是,您需要从着色器中的深度缓冲区读取数据。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句