可以在没有信号量或栅栏的情况下同步获取和写入交换链图像吗?
Can acquire and write to swap chain image be synchronized without a semaphore or fence?
通常,使用交换链映像的 VkRenderPass
在执行 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
之前等待来自 vkAcquireNextImageKHR
的信号量。同样VkRenderPass
还定义了一个subpass依赖,在同一个pipeline阶段的开始处transition图像:
VkSubpassDependency dependency = {
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = 0,
// .srcStageMask needs to be a part of pWaitDstStageMask in the WSI semaphore.
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.dependencyFlags = 0};
//source: https://github.com/KhronosGroup/Vulkan-Docs/wiki/Synchronization-Examples#combined-graphicspresent-queue
根据 Vulkan 标准:
7: Subpass dependencies describe execution and memory dependencies between subpasses.
那么,这个子通道依赖性是否单独强制 VkRenderPass
颜色输出发生在表示引擎 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
之后?来自 vkAcquireNextImageKHR
的信号量在等待什么,而依赖性却没有?
我无法有效地测试信号量的缺失。在我的 Mesa Linux 上,即使没有两种同步方法,渲染也会成功。
Vulkan 7.1.
If srcSubpass is equal to VK_SUBPASS_EXTERNAL, the first synchronization scope includes commands that occur earlier in submission order than the vkCmdBeginRenderPass used to begin the render pass instance.
vkAcquireNextImageKHR
不在subpass依赖的第一个同步范围内,因为它不是提交到队列的命令。
信号量同步阶段。由于图像转换发生在颜色输出阶段的开始,因此它发生在信号量发出信号之后。由于两者都等待 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
,信号量之前此阶段的操作被链接到转换依赖项。只有通过这条链,subpass 依赖关系才能知道何时获取图像以执行转换。 output阶段的写实际上是依赖transition then,而不是直接依赖semaphore
执行依赖关系建立两个范围之间的依赖关系:源范围和目标范围。源外部子通道依赖项定义如下:
If srcSubpass
is equal to VK_SUBPASS_EXTERNAL
, the first synchronization scope includes commands that occur earlier in submission order than the vkCmdBeginRenderPass
used to begin the render pass instance.
注意关键词“较早提交顺序”。 Submission order 是根据提交到队列的命令定义的。
您可能已经注意到,vkAcquireNextImageKHR
不将队列作为参数。它的名字也不以“Cmd”开头。这些是操作未提交到任何队列的线索;这是 设备 级别的操作。
由于获取图像不是任何队列“提交顺序”的一部分,因此它不能(除非采用其他同步)成为外部子通道依赖项的“第一同步范围”的一部分。因此,这样的依赖对acquire操作没有影响。
因此,如果您需要对已获取图像的使用执行依赖,则必须通过信号量或栅栏。
通常,使用交换链映像的 VkRenderPass
在执行 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
之前等待来自 vkAcquireNextImageKHR
的信号量。同样VkRenderPass
还定义了一个subpass依赖,在同一个pipeline阶段的开始处transition图像:
VkSubpassDependency dependency = {
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = 0,
// .srcStageMask needs to be a part of pWaitDstStageMask in the WSI semaphore.
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.dependencyFlags = 0};
//source: https://github.com/KhronosGroup/Vulkan-Docs/wiki/Synchronization-Examples#combined-graphicspresent-queue
根据 Vulkan 标准:
7: Subpass dependencies describe execution and memory dependencies between subpasses.
那么,这个子通道依赖性是否单独强制 VkRenderPass
颜色输出发生在表示引擎 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
之后?来自 vkAcquireNextImageKHR
的信号量在等待什么,而依赖性却没有?
我无法有效地测试信号量的缺失。在我的 Mesa Linux 上,即使没有两种同步方法,渲染也会成功。
Vulkan 7.1.
If srcSubpass is equal to VK_SUBPASS_EXTERNAL, the first synchronization scope includes commands that occur earlier in submission order than the vkCmdBeginRenderPass used to begin the render pass instance.
vkAcquireNextImageKHR
不在subpass依赖的第一个同步范围内,因为它不是提交到队列的命令。
信号量同步阶段。由于图像转换发生在颜色输出阶段的开始,因此它发生在信号量发出信号之后。由于两者都等待 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
,信号量之前此阶段的操作被链接到转换依赖项。只有通过这条链,subpass 依赖关系才能知道何时获取图像以执行转换。 output阶段的写实际上是依赖transition then,而不是直接依赖semaphore
执行依赖关系建立两个范围之间的依赖关系:源范围和目标范围。源外部子通道依赖项定义如下:
If
srcSubpass
is equal toVK_SUBPASS_EXTERNAL
, the first synchronization scope includes commands that occur earlier in submission order than thevkCmdBeginRenderPass
used to begin the render pass instance.
注意关键词“较早提交顺序”。 Submission order 是根据提交到队列的命令定义的。
您可能已经注意到,vkAcquireNextImageKHR
不将队列作为参数。它的名字也不以“Cmd”开头。这些是操作未提交到任何队列的线索;这是 设备 级别的操作。
由于获取图像不是任何队列“提交顺序”的一部分,因此它不能(除非采用其他同步)成为外部子通道依赖项的“第一同步范围”的一部分。因此,这样的依赖对acquire操作没有影响。
因此,如果您需要对已获取图像的使用执行依赖,则必须通过信号量或栅栏。