因此,我有一个渲染通道,其中有一个子通道,可直接绘制到帧缓冲区。该规范不会强迫我使用依赖项-如果我忽略它们,实现会隐式插入它们(尽管我不明白为什么它在第一个子通道中使用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
在第二个子通道中?
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;
所有这些都很令人困惑。如您所见,多个主管资源的看法不同。使用哪一个?如何理解这些依赖性?
答案 0 :(得分:3)
哦,亲爱的,这是一个大多数人不太了解的话题。假定并传播了许多错误信息。规范示例的正确位置是wikipage in the github repo。
有关交换链图像获取/呈现的相关部分可以在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. */
您混合了第二个障碍的子通过索引。尽管如评论中所述,渲染通道的末尾已经存在一个隐式障碍,该障碍又与您用来与当前同步的信号量或栅栏同步。因此,不需要显式依赖。