vulkan的文档提到在渲染过程中移动图像布局(请参见VkAttachmentDescription
结构)比使用障碍物(即vkCmdPipelineBarrier
)移动图像布局更为可取。我可以理解,因为后者引入了限制并行执行的同步点。
现在考虑一个典型的示例:从VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
到VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
的过渡。在这种情况下,将在着色器中读取资源,但是为了安全地执行此操作,必须将颜色附件的写入与着色器中的读取同步。换句话说,我们仍然需要使用障碍,并且在渲染过程中移动布局似乎根本没有任何优势。
能否以某种方式详细解释所有这些工作原理?在哪种情况下,真正具有在渲染过程中移动布局的优势?是否有(实际的)布局更改不需要进一步的同步?
答案 0 :(得分:2)
首先,您没有选择的余地。该API会强制您提供finalLayout
和中间VkAttachmentReference::layout
。您可以在渲染过程中有条件地使用vkCmdPipelineBarrier
(又称 subpass自相关性),但是其中一项规则是不允许更改布局附件图片:
如果使用
VkImageMemoryBarrier
,则在屏障中指定的图像和图像子资源范围必须是当前子通道中帧缓冲区使用的图像视图之一的子集。另外,oldLayout
必须等于newLayout
,srcQueueFamilyIndex
和dstQueueFamilyIndex
必须都必须{{1 }}。
因此,在渲染过程中,您只能使用渲染过程机制更改布局,否则您必须不在渲染过程中。剩下的只是“外部渲染过程”案例来讨论:
考虑渲染过程的好方法是,它(可能基于平台)将资源(使用VK_QUEUE_FAMILY_IGNORED
)复制到专用内存中,完成后将其复制回(使用loadOp
)。回到通用存储器。
话虽如此,假设您可以将布局转换为storeOp
的一部分免费转换为finalLayout
是合理的。 (同样,从storeOp
到第一个initialLayout
的过渡是VkAttachmentReference::layout
的一部分。)因此,将布局过渡作为renderpass的一部分是有意义的,如果可能的话\足够方便