单个子通道的子通道依赖性。如何?
Subpass dependencies for a single subpass. How to?
所以我有一个渲染通道和一个直接绘制到帧缓冲区的子通道。规范不强制我使用依赖项——如果我省略它们,实现会隐式插入它们(尽管我不明白为什么它使用 srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
作为第一个子通道——这个阶段意味着最开始,即不要不要等待任何事情)。
但与 Vulkan 一样 - 最好是明确的。这就是混淆 - 多个来源使用不同的子通道。
Sdk 的立方体示例根本没有使用它们。
Vulkan 教程只使用一个:
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.srcAccessMask = 0;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
这里为什么srcAccessMask
为零?
API 没有秘密使用两个:
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
dependency.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependency.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
和
dependency.srcSubpass = 0;
dependency.dstSubpass = VK_SUBPASS_EXTERNAL;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependency.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
不太清楚为什么 srcStageMask
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
在第一个子通道中 - 不是
这个阶段应该用于执行依赖,但在这里我们
需要内存依赖?关于为什么 dstStageMask
的相同问题
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
在第二个subpass中吗?
Khronos同步实例使用一个:
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.srcAccessMask = 0;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
为什么srcAccessMask
是0?
这是我对两个依赖项的尝试:
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // need to wait until
presentation is finished reading the image
dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // we are writing to
the image in this stage
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
and
dependency.srcSubpass = 0;
dependency.dstSubpass = VK_SUBPASS_EXTERNAL;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // we are writing to
the image in this stage
dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // presentation reads
image in this stage (is it?)
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
这一切都非常令人困惑。如您所见,多个有能力的消息来源有不同的看法。使用哪一个?如何理解这些依赖?
天哪,这是一个大多数人都不太了解的话题。许多错误信息被假定并扩散开来。规范示例的适当位置是 wikipage in the github repo。
可以找到关于交换链图像 acquire/present 的相关部分 here。
这是许多同步细节被正确确定之前的旧示例。
目的是同步信号量使用以等待 vkAcquireNextImage 的结果与渲染。这是一个读后写的危险,信号量将包括内存可见性同步。所以 srcAccessMask 是没有必要的。
同样,障碍是为了与信号量同步。将命令缓冲区提交到队列时,您可以设置哪些阶段等待哪些信号量。在这种情况下,他们使用管道底部而不是 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
与 2 相同的答案,唯一不同的是 dstAccessMask
我在上面链接的 wiki 页面使用了以下内容:
/* Only need a dependency coming in to ensure that the first
layout transition happens at the right time.
Second external dependency is implied by having a different
finalLayout and subpass layout. */
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};
/* Normally, we would need an external dependency at the end as well since we are changing layout in finalLayout,
but since we are signalling a semaphore, we can rely on Vulkan's default behavior,
which injects an external dependency here with
dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
dstAccessMask = 0. */
您混淆了第二个障碍的子通道索引。尽管如评论中所述,在 renderpass 的末尾已经存在一个隐式屏障,它反过来与您用来与当前同步的信号量或栅栏同步。所以不需要显式依赖。
所以我有一个渲染通道和一个直接绘制到帧缓冲区的子通道。规范不强制我使用依赖项——如果我省略它们,实现会隐式插入它们(尽管我不明白为什么它使用 srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
作为第一个子通道——这个阶段意味着最开始,即不要不要等待任何事情)。
但与 Vulkan 一样 - 最好是明确的。这就是混淆 - 多个来源使用不同的子通道。
Sdk 的立方体示例根本没有使用它们。
Vulkan 教程只使用一个:
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.dstSubpass = 0; dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.srcAccessMask = 0; dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
这里为什么
srcAccessMask
为零?API 没有秘密使用两个:
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.dstSubpass = 0; dependency.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; dependency.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
和
dependency.srcSubpass = 0; dependency.dstSubpass = VK_SUBPASS_EXTERNAL; dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; dependency.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; dependency.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
不太清楚为什么
srcStageMask
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
在第一个子通道中 - 不是 这个阶段应该用于执行依赖,但在这里我们 需要内存依赖?关于为什么dstStageMask
的相同问题VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
在第二个subpass中吗?Khronos同步实例使用一个:
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.dstSubpass = 0; dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.srcAccessMask = 0; dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
为什么
srcAccessMask
是0?这是我对两个依赖项的尝试:
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.dstSubpass = 0; dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // need to wait until presentation is finished reading the image dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // we are writing to the image in this stage dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; and dependency.srcSubpass = 0; dependency.dstSubpass = VK_SUBPASS_EXTERNAL; dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // we are writing to the image in this stage dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // presentation reads image in this stage (is it?) dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
这一切都非常令人困惑。如您所见,多个有能力的消息来源有不同的看法。使用哪一个?如何理解这些依赖?
天哪,这是一个大多数人都不太了解的话题。许多错误信息被假定并扩散开来。规范示例的适当位置是 wikipage in the github repo。
可以找到关于交换链图像 acquire/present 的相关部分 here。
这是许多同步细节被正确确定之前的旧示例。
目的是同步信号量使用以等待 vkAcquireNextImage 的结果与渲染。这是一个读后写的危险,信号量将包括内存可见性同步。所以 srcAccessMask 是没有必要的。
同样,障碍是为了与信号量同步。将命令缓冲区提交到队列时,您可以设置哪些阶段等待哪些信号量。在这种情况下,他们使用管道底部而不是
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
与 2 相同的答案,唯一不同的是 dstAccessMask
我在上面链接的 wiki 页面使用了以下内容:
/* Only need a dependency coming in to ensure that the first layout transition happens at the right time. Second external dependency is implied by having a different finalLayout and subpass layout. */ 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}; /* Normally, we would need an external dependency at the end as well since we are changing layout in finalLayout, but since we are signalling a semaphore, we can rely on Vulkan's default behavior, which injects an external dependency here with dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, dstAccessMask = 0. */
您混淆了第二个障碍的子通道索引。尽管如评论中所述,在 renderpass 的末尾已经存在一个隐式屏障,它反过来与您用来与当前同步的信号量或栅栏同步。所以不需要显式依赖。