【问题标题】:Vulkan: Renderpass LoadOp and StoreOp synchronisationVulkan:Renderpass LoadOp 和 StoreOp 同步
【发布时间】:2018-11-27 05:29:55
【问题描述】:

上下文

在规范中,它讨论了附件的 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 中使用的附件的任何加载、存储或多样本解析操作

问题

规范的上述部分暗示在某些情况下需要此信息,以便您可以确保正确同步这些加载和存储操作与其他访问(在其他子通道中或在该渲染通道之外),以您需要的相同方式以确保解析操作与对同一附件的其他访问同步。

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

我相信我一定是误解了某些东西,因为我在任何 vulkan 书籍或任何讨论它的人中都找不到对此的参考。

其他细节

我认识到,在大多数情况下,不需要考虑这是因为附件的 loadOp 或 storeOp 的管道阶段和访问类型与子通道实例中记录的命令中使用的管道阶段和访问类型相同那些 loadOps 或 storeOps 会发生在其中。但是,在某些情况下它们并不相同。

例如:

具有一个子通道 RP1 的渲染通道 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 的写入同时运行,显然是无效的。

别名

最后,由于需要同步别名附件的 storeOps 和 loadOps 以及同步对这些别名附件本身的访问,这似乎也会导致复杂性。

提前谢谢你。

【问题讨论】:

    标签: vulkan


    【解决方案1】:

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

    您确实需要与渲染通道外部同步。如果您之前已经编写过资源,并且将要加载它(读取,或者如果清除操作则写入),则必须有一个障碍(通常是 VK_SUBPASS_EXTERNAL 依赖项)。同样,如果您存储了一个资源(写入)并且稍后会被读取。

    规范说:

    应用程序必须确保在给定渲染通道实例中支持用作附件的图像子资源的所有内存访问要么发生在这些附件的加载操作之前,要么发生- 在这些附件的存储操作之后。

    子通道可能会被依赖于负载的后续操作同步。例如。颜色附件也写入VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,您自然会为需要该输出的后续子通道提供依赖项。

    至于您的示例中感知到的子通道自依赖,保证负载在第一次使用之前发生。同样的存储发生在最后一次使用后。 规格报价:

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

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

    因此,在我的解释中,就好像您在使用它的第一个子通道中添加了一个假想的 vkCmdLoadResource 命令,并且随后在该假想的加载命令和该资源的第一次使用之间建立了 vkCmdPipelineBarrier 依赖关系。子通道。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-29
      • 2011-10-31
      • 2014-02-09
      相关资源
      最近更新 更多