子流程依赖

渲染流程的子流程会自动进行图像布局变换。这一变换过程由子流程的依赖所决定。子流程的依赖包括子流程之间的内存和执行的依赖关系。虽然我们现在只使用了一个子流程,但子流程执行之前和子流程执行之后的操作也被算作隐含的子流程。

在渲染流程开始和结束时会自动进行图像布局变换,但在渲染流程开始时进行的自动变换的时机和我们的需求不符,变换发生在管线开始时,但那时我们可能还没有获取到交换链图像。有两种方式可以解决这个问题。一个是设置imageAvailableSemaphore信号量的waitStages为VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,确保渲染流程在我们获取交换链图像之前不会开始。一个是设置渲染流程等待VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT管线阶段。在这里,为了让读者能够了解子流程依赖如何控制图像布局变换,我们使用第二种方式。

配置子流程依赖需要使用VkSubpassDependency结构体。让我们在createRenderPass函数添加下面的代码:

VkSubpassDependency dependency = {};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;

srcSubpass和dstSubpass成员变量用于指定被依赖的子流程的索引和依赖被依赖的子流程的索引。VK_SUBPASS_EXTERNAL用来指定我们之前提到的隐含的子流程,对srcSubpass成员变量使用表示渲染流程开始前的子流程,对dstSubpass成员使用表示渲染流程结束后的子流程。这里使用的索引0是我们之前创建的子流程的索引。为了避免出现循环依赖,我们给dstSubpass设置的值必须始终大于srcSubpass。

dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.srcAccessMask = 0;

srcStageMask和srcAccessMask成员变量用于指定需要等待的管线阶段和子流程将进行的操作类型。我们需要等待交换链结束对图像的读取才能对图像进行访问操作,也就是等待颜色附着输出这一管线阶段。

dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;

dstStageMask和dstAccessMask成员变量用于指定需要等待的管线阶段和子流程将进行的操作类型。在这里,我们的设置为等待颜色附着的输出阶段,子流程将会进行颜色附着的读写操作。这样设置后,图像布局变换直到必要时才会进行:当我们开始写入颜色数据时。

renderPassInfo.dependencyCount = 1;
renderPassInfo.pDependencies = &dependency;

VkRenderPassCreateInfo结构体的dependencyCount和pDependencies成员变量用于指定渲染流程使用的依赖信息。