RenderPass 依赖和(转换)内存屏障
RenderPass Dependency and (transition) memory barrier
我遇到了一个综合问题。
假设我有一个 TRANSFER_LAYOUT 布局的图像。那样的话,内存已经可用(不可见)。
假设我更新了一个统一缓冲区(通过 vkCmdCopyBuffer)。
现在假设我有一个 renderPass(带有 "empty frameBuffer",因此没有 colorAttachment 使事情更简单),它使用 SHADER_READ_OPTIMAL 布局中的先前图像和我们刚刚更新的统一缓冲区.图像和缓冲区都在片段着色器内部使用。
以下做法是否正确?
将图像转换为 SHADER_READ_LAYOUT
srcAccess = 0; // layers will say error : it must be TRANSFER_READ
dstAccess = 0; // The visibility will be made in the renderpass dependency (hower layers tells that it should be SHADER_READ I think)
srcPipe = TOP_OF_PIPE;
dstPipe = BOTTOM_OF_PIPE;
据我理解,这里使用不同于0的访问是没有意义的,因为TOP_OF_PIPE
和BOTTOM_OF_PIPE
不访问内存。
在 VK_EXTERNAL_SUBPASS 的 renderpass 依赖项中:
srcAccess = TRANSFER_WRITE; // for the uniformBuffer
dstAccess = SHADER_READ; // for the uniform and the image
srcPipeline = TRANSFER; // For the uniformBuffer
dstPipeline = FRAGMENT_SHADER; // They are used here
这样一来,我们确信统一缓冲区不会有任何问题:由于 renderPass,数据既可用又可见。内存也应该对图像可见(也由于依赖性)。然而,这里写的过渡是发生在"not before"底层。因为我用的是FRAGMENT_STAGE里面的图片,是不是搞错了?还是 "end of the renderPass dependency" 表现得像底层?
此代码适用于 NVIDIA 和 AMD,但我不确定它是否真的正确
要完全理解同步,必须简单地阅读规范;特别是 Execution and Memory Dependencies 理论章节。让我们根据规范中写的内容来分析您的情况。
你有(只有)三个同步命令:S1(图像过渡到TRANSFER_LAYOUT
和可用性操作), S2(图像过渡到SHADER_READ_LAYOUT
),以及S3(渲染传递 VK_EXTERNAL
依赖)。
您的命令缓冲区是一个有序列表,例如:[Cmds0, S1 , Cmds1, S2, Cmds2, S3, Cmds3].
For S1 假设您正确地完成了依赖项的第一部分(即 src
部分)。您只是说您将图像 提供给 。
你还说你没有让它对可见,所以我们假设dstAccess
是0
dstStage
可能是 BOTTOM_OF_PIPE
.
S2 没有 执行依赖性 并且它没有 内存依赖性。仅布局过渡。规范中有一个 layout transition synchronization 例外说明布局转换在 提交顺序 中完全执行(即 隐式执行依赖性 是自动的添加)。我个人不太愿意依赖它(而且我不相信驱动程序会在第一次尝试时正确实施它)。但是让我们假设它是有效的,并假设图像将被正确地转换并在 从 可用(而不是 对 可见) S1.
S3是对非附件资源的外部subpass依赖,但the spec reassures us与vkCmdPipelineBarrier
与 VkMemoryBarrier
.
S3 中依赖项的第二部分(即 dst
)似乎符合您的需要。
TL;DR,到目前为止一切顺利。
S3 中依赖项的第一部分(即 dst
)确实是有问题的部分。
非附件资源没有自动布局转换,所以我们不能像上面那样依赖那个拐杖。
一组命令A3是renderpass之前的所有命令。
同步范围A3S只是操作[= =22=] 管道阶段或任何逻辑上更早的阶段(即 TOP_OF_PIPE
到指定的 STAGE_TRANSFER
)。
执行依赖在A3'和之间建立B3'。上面我们同意 B3' 一半的依赖关系是正确的。 A3' 一半是 A3 的交集和 A3S.
S2中的布局过渡是在srcPipe = TOP_OF_PIPE
和dstPipe = BOTTOM_OF_PIPE
之间进行的,所以基本上可以任何地方。它可以晚于 BOTTOM_OF_PIPE
(准确地说,在 S2[=156= 之后记录的命令发生在 BOTTOM_OF_PIPE
之前] 被执行)。
所以布局转换是 A3 的一部分,但不能保证它是 A 的一部分3S;所以 not 可以保证转换是交集 A3'.[=39 的一部分=]
这意味着无法保证到 SHADER_READ_LAYOUT
的布局转换发生在 STAGE_FRAGMENT_SHADER
中第一个子通道中的图像读取之前。
也没有正确的内存依赖性,因为它是根据A3'[=156定义的=] 也是。
编辑:不知何故错过了这个,这可能是问题所在:
Or is the "end of the renderPass dependency" behave like a bottom stage?
渲染过程的开始和结束没有任何表现。它只影响提交顺序。在存在 VK_EXTERNAL
依赖项的情况下,仅适用(当然还有任何其他先前的显式同步命令)。在 VkSubpassDependency 的有效使用部分的规范中描述了没有显式 VK_EXTERNAL
依赖的情况(基本上所有 available before TOP_OF_PIPE
的内存是使 对 整个第一个子通道可见以供附件使用)。
我遇到了一个综合问题。
假设我有一个 TRANSFER_LAYOUT 布局的图像。那样的话,内存已经可用(不可见)。
假设我更新了一个统一缓冲区(通过 vkCmdCopyBuffer)。
现在假设我有一个 renderPass(带有 "empty frameBuffer",因此没有 colorAttachment 使事情更简单),它使用 SHADER_READ_OPTIMAL 布局中的先前图像和我们刚刚更新的统一缓冲区.图像和缓冲区都在片段着色器内部使用。
以下做法是否正确?
将图像转换为 SHADER_READ_LAYOUT
srcAccess = 0; // layers will say error : it must be TRANSFER_READ
dstAccess = 0; // The visibility will be made in the renderpass dependency (hower layers tells that it should be SHADER_READ I think)
srcPipe = TOP_OF_PIPE;
dstPipe = BOTTOM_OF_PIPE;
据我理解,这里使用不同于0的访问是没有意义的,因为TOP_OF_PIPE
和BOTTOM_OF_PIPE
不访问内存。
在 VK_EXTERNAL_SUBPASS 的 renderpass 依赖项中:
srcAccess = TRANSFER_WRITE; // for the uniformBuffer
dstAccess = SHADER_READ; // for the uniform and the image
srcPipeline = TRANSFER; // For the uniformBuffer
dstPipeline = FRAGMENT_SHADER; // They are used here
这样一来,我们确信统一缓冲区不会有任何问题:由于 renderPass,数据既可用又可见。内存也应该对图像可见(也由于依赖性)。然而,这里写的过渡是发生在"not before"底层。因为我用的是FRAGMENT_STAGE里面的图片,是不是搞错了?还是 "end of the renderPass dependency" 表现得像底层?
此代码适用于 NVIDIA 和 AMD,但我不确定它是否真的正确
要完全理解同步,必须简单地阅读规范;特别是 Execution and Memory Dependencies 理论章节。让我们根据规范中写的内容来分析您的情况。
你有(只有)三个同步命令:S1(图像过渡到TRANSFER_LAYOUT
和可用性操作), S2(图像过渡到SHADER_READ_LAYOUT
),以及S3(渲染传递 VK_EXTERNAL
依赖)。
您的命令缓冲区是一个有序列表,例如:[Cmds0, S1 , Cmds1, S2, Cmds2, S3, Cmds3].
For S1 假设您正确地完成了依赖项的第一部分(即 src
部分)。您只是说您将图像 提供给 。
你还说你没有让它对可见,所以我们假设dstAccess
是0
dstStage
可能是 BOTTOM_OF_PIPE
.
S2 没有 执行依赖性 并且它没有 内存依赖性。仅布局过渡。规范中有一个 layout transition synchronization 例外说明布局转换在 提交顺序 中完全执行(即 隐式执行依赖性 是自动的添加)。我个人不太愿意依赖它(而且我不相信驱动程序会在第一次尝试时正确实施它)。但是让我们假设它是有效的,并假设图像将被正确地转换并在 从 可用(而不是 对 可见) S1.
S3是对非附件资源的外部subpass依赖,但the spec reassures us与vkCmdPipelineBarrier
与 VkMemoryBarrier
.
S3 中依赖项的第二部分(即 dst
)似乎符合您的需要。
TL;DR,到目前为止一切顺利。
S3 中依赖项的第一部分(即 dst
)确实是有问题的部分。
非附件资源没有自动布局转换,所以我们不能像上面那样依赖那个拐杖。
一组命令A3是renderpass之前的所有命令。
同步范围A3S只是操作[= =22=] 管道阶段或任何逻辑上更早的阶段(即 TOP_OF_PIPE
到指定的 STAGE_TRANSFER
)。
执行依赖在A3'和之间建立B3'。上面我们同意 B3' 一半的依赖关系是正确的。 A3' 一半是 A3 的交集和 A3S.
S2中的布局过渡是在 这意味着无法保证到 也没有正确的内存依赖性,因为它是根据A3'[=156定义的=] 也是。 编辑:不知何故错过了这个,这可能是问题所在: Or is the "end of the renderPass dependency" behave like a bottom stage? 渲染过程的开始和结束没有任何表现。它只影响提交顺序。在存在 srcPipe = TOP_OF_PIPE
和dstPipe = BOTTOM_OF_PIPE
之间进行的,所以基本上可以任何地方。它可以晚于 BOTTOM_OF_PIPE
(准确地说,在 S2[=156= 之后记录的命令发生在 BOTTOM_OF_PIPE
之前] 被执行)。
所以布局转换是 A3 的一部分,但不能保证它是 A 的一部分3S;所以 not 可以保证转换是交集 A3'.[=39 的一部分=]
SHADER_READ_LAYOUT
的布局转换发生在 STAGE_FRAGMENT_SHADER
中第一个子通道中的图像读取之前。
VK_EXTERNAL
依赖项的情况下,仅适用(当然还有任何其他先前的显式同步命令)。在 VkSubpassDependency 的有效使用部分的规范中描述了没有显式 VK_EXTERNAL
依赖的情况(基本上所有 available before TOP_OF_PIPE
的内存是使 对 整个第一个子通道可见以供附件使用)。