Vulkan:Renderpass LoadOp和StoreOp同步

时间:2018-06-18 11:17:51

标签: vulkan

上下文

在规范中,它讨论了附件的loadOp和storeOp在哪个管道阶段(Here - The 2nd and 3rd paragraph after the bulletpoints),以及他们使用的访问类型(Here):

  

使用深度/模板格式的附件的加载操作在VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT管道阶段执行。

     

使用颜色格式的附件的加载操作在VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT管道阶段执行。

     

VK_ATTACHMENT_LOAD_OP_LOAD指定将保留渲染区域内图像的先前内容。对于具有深度/模板格式的附件,这使用访问类型VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT。对于具有颜色格式的附件,这将使用访问类型VK_ACCESS_COLOR_ATTACHMENT_READ_BIT。

对于其他loadOps和storeOps也是如此。

此外,它还提到子通道中发生的loadOp,storeOp和解析操作如何包含在子通路依赖关系(Here - The 2nd and 3rd paragraph after the bulletpoints)的同步范围中:

  

第一组命令包括作为srcSubpass标识的子通道实例的一部分提交的所有命令,以及对srcSubpass中使用的附件的任何加载,存储或多重采样解析操作

问题

规范的上述部分意味着在某些情况下需要此信息,以便您可以确保这些加载和存储操作与其他访问(在其他子通道中或在renderpass外部)正确同步,就像您需要的那样确保解析操作与对同一附件的其他访问同步。

我的问题是,在将子通道与其他子通道同步时是否需要考虑加载和存储操作,以及具有访问权限的子通道 在renderpass实例之外?在什么情况下需要同步?

我相信我一定会误解一些事情,因为我无法在任何一本粗俗的书籍或任何讨论它的人中找到对此的参考。

其他详细信息

我认识到在大多数情况下,没有必要将此视为管道阶段,附件的loadOp或storeOp的访问类型与子通道实例中记录的命令中使用的管道阶段和访问类型相同那些loadOps或storeOps会出现。但是,有些情况下它们不相同。

例如:

具有一个子通道RP1的renderpass RP。

该子通道使用图像视图IV作为输入附件,其中loadOp = VK_ATTACHMENT_LOAD_OP_LOAD。

IV具有颜色格式,位于VK_IMAGE_LAYOUT_GENERAL。

在RP1开始时,loadOp将在管道阶段VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT中运行,访问类型为VK_ACCESS_COLOR_ATTACHMENT_READ_BIT。 (参见规范。见上下文)。

但是当IV用作输入附件时,子通道将使用管道阶段VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT和访问类型VK_ACCESS_INPUT_ATTACHMENT_READ_BIT来访问它。

让我们说一些写入是在IV之前的RP之前执行的,具有外部子通道依赖性,如下所示:

VkSubpassDependency subpassDependency;

subpassDependency.srcSubpass = VK_SUBPASS_EXTERNAL;
subpassDependency.dstSubpass = 0;

//source
subpassDependency.srcStageMask = /*Whatever the prior write was E.g. VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT*/;
subpassDependency.srcAccessMask = /*Whatever the prior write was E.g. VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT*/;

//destination
subpassDependency.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
subpassDependency.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;

即使它似乎是正确的,也可能允许IV的loadOp与先前写入IV同时运行,显然是无效的。

混叠

最后,除了同步访问这些别名附件本身之外,由于需要同步存储操作和别名附件的loadOps,这似乎也会导致复杂性。

提前谢谢。

1 个答案:

答案 0 :(得分:1)

我对Vulkan的“您是否必须将X与Y同步”的回答是。大约有2-3个例外,过度同步不会立即造成危害。

您确实需要与renderpass的外部进行同步。如果您之前已经写过资源,并且要加载该资源(读或写,如果清除操作则写该资源),则必须有一个障碍(通常是VK_SUBPASS_EXTERNAL依赖项)。同样,如果您存储了(写的)资源并且以后会读取它。

规范说:

  

应用程序必须确保所有对支持在给定renderpass实例中用作附件的图像子资源的内存的访问发生在这些附件的 load操作之前,或者发生-在这些附件的存储操作之后。

子通行证很可能会根据负载而由后续操作同步。例如。颜色附件也会写在VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT中,您自然会为需要该输出的后续子传递提供依赖关系。

在您的示例中,对于感知的子通道自相关性,可以保证负载在首次使用之前发生。同样,存储在最后一次使用后发生。 规格报价:

  

对附件中每个样本的加载操作在任何记录的命令之前发生,该命令将在使用附件的第一个子通道中访问样本。

  

附件中每个样本的存储操作在任何记录的命令之后,该命令将访问使用附件的最后一个子遍中的样本。

因此,按照我的解释,就好像您在使用它的第一个子通道中添加了一个虚构的vkCmdLoadResource命令,并且在该虚构load命令和首次使用之间有一个随后的vkCmdPipelineBarrier相关性该子通道中的资源。