Graphics 使用子类依赖项的操作顺序命令?

Graphics 使用子类依赖项的操作顺序命令?,graphics,vulkan,Graphics,Vulkan,从我到目前为止所读的内容来看,如果没有显式同步,单个命令缓冲区中的命令可能会出现顺序错误。以下是vulkan规范所说的() 执行操作命令所涉及的工作通常允许重叠或重新排序,但这样做不能改变每个操作命令所使用的状态。通常,操作命令是那些改变帧缓冲区附件、读/写缓冲区或图像内存或写入查询池的命令 编辑:起初,我认为设置状态命令将充当某种屏障,以确保绘图命令有序。我已经被解释过这是错误的。我来看看这个例子,在Vulkan的bloom效应 下面是两个渲染过程使用的2个子过程依赖项 dependenci

从我到目前为止所读的内容来看,如果没有显式同步,单个命令缓冲区中的命令可能会出现顺序错误。以下是vulkan规范所说的()

执行操作命令所涉及的工作通常允许重叠或重新排序,但这样做不能改变每个操作命令所使用的状态。通常,操作命令是那些改变帧缓冲区附件、读/写缓冲区或图像内存或写入查询池的命令

编辑:起初,我认为设置状态命令将充当某种屏障,以确保绘图命令有序。我已经被解释过这是错误的。我来看看这个例子,在Vulkan的bloom效应

下面是两个渲染过程使用的2个子过程依赖项

dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
dependencies[0].dstSubpass = 0;
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;

dependencies[1].srcSubpass = 0;
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;

我的理解是,这两个子类依赖关系负责渲染过程的执行顺序,但我还不确定如何执行,因为我对子类依赖关系还不清楚。如果我的理解是正确的,您能解释一下为什么子类依赖项有助于排序draw命令吗?如果我错了,那么是什么确保了绘图命令的顺序呢?

所以发生的事情是,一些东西被渲染到
img1
(作为颜色附件)。然后 对
img1
进行采样,并将内容写入
img2
(作为颜色附件)。然后对
img2
进行采样并写入交换链图像

dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dependencies[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;

dependencies[0].dstSubpass = 0;
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
对于第一个和第二个渲染过程实例,这可能会阻止资源的某些先前采样。可能是前一帧的。假设后续帧之间没有其他同步

dependencies[1].srcSubpass = 0;
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;

dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
现在,颜色附件是在
VK\u PIPELINE\u STAGE\u color\u attachment\u OUTPUT\u BIT
中编写的,更重要的是(而且更方便),存储操作在颜色附件的同一阶段中进行。无论是
STORE
还是
DONT\u CARE
,它都始终是
VK\u ACCESS\u COLOR\u ATTACHMENT\u WRITE\u BIT

VK\u PIPELINE\u STAGE\u FRAGMENT\u SHADER\u BIT
VK\u ACCESS\u SHADER\u READ\u BIT
同样适合图像采样(在片段着色器中)

因此,这意味着在第二个渲染过程实例对其进行采样之前,将从第一个渲染过程实例完全渲染和存储
img1

它还意味着在第三个渲染过程实例对其进行采样之前,从第二个渲染过程实例完全渲染和存储
img2


这是一个高级示例,您应该已经了解了同步

状态命令不受同步的约束。它们仅在引入后续操作命令后立即更改其上下文,通常持续到命令缓冲区结束或状态再次更改

子类依赖项和屏障以这种方式定义依赖项:
src
同步作用域在
dst
同步作用域开始执行之前完成执行

子类依赖项和障碍实际上是相同的。屏障通常在渲染过程外部使用,而子过程在渲染过程内部使用。子类彼此无序,因此子类依赖项另外具有
*subpass
参数,并且同步范围仅限于所述的子类
VK_SUBPASS\u EXTERNAL
表示
vkCmdBeginRenderPass
\after
vkcmendrenderpass
之前的内容是同步范围的一部分


理解同步系统需要时间,我不能在这里适当地介绍它。我有一个更详细的关于障碍的答案,换句话说,互联网上也有很多资源。

“如果每个绘制和绑定都属于不同的渲染过程,会发生什么?”为什么会有什么变化?没有一个详细的解释,因为它只是相同的解释。@Nicolas我对动作命令和设置状态命令的理解是正确的吗?设定状态命令在命令行动命令时是否像障碍一样起作用?这是两个完全不同的问题。尊重状态设置不会使设置像执行障碍一样。“你能解释一下为什么子类依赖关系有助于排序draw命令吗?”我不明白你的意思。它命令绘制命令,因为这就是依赖项的用途。这就像问为什么一个
if
语句会根据一个条件运行不同的代码段。@Nicolas我想澄清的是我们在stageMask和accessMask中输入的值,以及它们如何帮助排序draw命令。我已经阅读了文档并理解了这些位值代表的含义,但我很难看到这些值并计算出它们所隐含的依赖链。首先,感谢您的详细回复。我想我终于明白这里发生了什么。第一个子类依赖项:您希望写入到image1,但image1可能在前一帧的另一个渲染过程中读取(发生在片段着色器中),因此您需要等待在STAGE\u COLOR\u ATTACHMENT\u输出中完成读取。第二个子类依赖关系:您正在阶段\颜色\附件\输出中写入image1,但第二个渲染类可能已经启动。第二个渲染过程希望在其片段着色器中读取/采样image1,因此您让它等待在其STAGE_fragment_shader_位中读取,直到第一个渲染过程的STAGE_COLOR_ATTACHMENT_输出完成写入。由于image2和image3的关系与image1和image2的关系相同,因此在第二个渲染过程中也会发生同样的情况。我在这一点上的理解正确吗?在第一个子类依赖项中只剩下一点混乱。也就是说,如果图像1不是被读取,而是被写入到另一个的STAGE_COLOR_ATTACHMENT_输出中呢
dependencies[1].srcSubpass = 0;
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;

dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;