我有一个Vulkan渲染器,在每个帧的开始处开始一个新的渲染通道。然后将命令缓冲区传递给几个模块,每个模块提交一些绘制调用和其他命令。在draw调用被提交之前,它检查是否有任何额外的纹理必须被加载,在加载过程结束时,图像布局过渡到VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL被执行。
问题是布局过渡使用vkCmdPipelineBarrier命令,该命令只允许相同的输入和输出格式(VUID-vkCmdPipelineBarrier-oldLayout-01181),这使得过渡对我来说毫无用处。
目前我唯一的解决方案是将布局转换移动到不同的命令缓冲区并将其单独提交给命令队列,然后在继续构建命令缓冲区之前检索结果,但这意味着我必须等待队列中所有先前的命令完成,对吗?
你能想象一个更干净的解决方案来执行不同布局之间的布局转换在一个活动的渲染通道?
对
目前我唯一的解决方案是将布局转换移动到不同的命令缓冲区并将其单独提交给命令队列,然后在继续构建命令缓冲区之前检索结果,但这意味着我必须等待队列中所有先前的命令完成,对吗?
你不是在思考四维空间。
您构建命令缓冲区的顺序是无关的。重要的是你提交的顺序。
构建渲染命令缓冲区的代码也可以构建传输命令缓冲区。假设图像处于正确的布局中,您编写渲染命令,并编写传输命令,在传输完成后将将这些图像放入正确的布局中。你写这些命令的顺序是无关的;唯一重要的顺序是他们的提交顺序。按照这个顺序把一个CB放在另一个之前,(如果有障碍的话)它们就会按照这个顺序正确地执行。
CPU不需要等待任何事情。没有"results"需要检索的;这是GPU的工作。
能够做到这一点,就是为什么你必须告诉Vulkan每个图像的布局是什么,当你试图使用它。