vulkan pipeline barrier在GPU或其驱动方面是如何实现的?
How vulkan pipeline barrier is implemented in terms of GPU or its driver?
我认为管道障碍是内核模式驱动程序中命令的一种重新排序,但它似乎不是真的。我还认为它可能类似于驱动程序端 GPU 调度程序的提示,但它似乎仍然不是真的。它只是构建 KMD 主命令缓冲区的提示,还是管道屏障代表了 GPU 命令处理器的某种指令?
编辑:如何实施管道障碍?
正如 Nicol 所说,细节将根据具体实施和障碍而定。但总的原理是相似的。
GPU 是流水线处理器,这意味着每个命令都要经过多个执行阶段。 运行 并发阶段,在绘制调用内部和绘制调用之间。例如,绘制命令 N 的片段处理可能与绘制命令 N+1 的顶点处理同时执行。屏障命令可防止后续命令的工作在先前命令完成 srcStageMask
中的所有阶段之前开始执行 dstStageMask
中的任何阶段。除了这个 执行屏障 之外,管道屏障还可以包括一个 内存屏障 ,它确保前面的命令完成的内存访问是正确排序的与后面命令的内存访问。
所以 none 这与重新排序有关,它只与新命令在先前命令完成之前开始这一事实有关,有时您需要防止这种情况发生。最明显的例子是渲染到纹理:您希望在对纹理进行任何读取之前完成对纹理的所有写入。没有管道障碍,没有什么能阻止它们重叠。
通常 GPU 会有一个(内部)命令,在先前的命令全部通过命令执行的点后“发出信号”一些标记,另一个命令在允许任何后续命令之前“等待”一些标记发出信号继续工作。标记可能只是一个内存位置(信号:写入特定值,等待:旋转直到该位置包含特定值)。或者它可能是某种特殊用途的片上资源。障碍将只是一个信号命令,后跟一个等待命令。这会在部分 GPU 闲置的管道中产生“气泡”。为了尽量减少这种情况,一些 GPU 将能够在管道中的多个点发出信号并等待。通常能够在颜色写入完成后发出信号,并在光栅化之前等待,例如,允许在绘制 N+1 的片段工作发生时进行绘制 N+1 的顶点工作,但停止 N+1 片段工作。 srcStageMask
和 dstStageMask
允许实现准确地知道依赖项是什么,但大多数实际上不能利用这种精细的粒度,并且会产生更粗糙的保守气泡。
内存屏障对应于缓存清理(将脏行写入内存)和缓存无效(删除缓存数据)操作。 “可见性”意味着清理本地缓存,将数据写回内存,以便以后从内存中读取的任何内容都将看到新值。 “可用性”意味着使本地缓存失效,这样任何新的读取都将在缓存中丢失(而不是看到旧数据)并从内存中获取。 GPU 通常针对这些针对不同本地缓存(例如纹理缓存、depth/stencil 缓存等)的特定操作具有特殊命令。
因此在渲染到纹理的情况下,您将在纹理渲染命令和从纹理读取的任何命令之间插入管道屏障。驱动程序会为 GPU 生成一个命令(或多个命令),等待先前的命令完成混合阶段的执行,然后清理颜色附件缓存,然后向某个标记发出信号。然后它会生成 GPU 命令以等待标记发出信号并使纹理缓存无效,然后再允许任何未来的绘制调用开始片段着色。
正如我之前所说,GPU 提供的实际命令可能比这更粗糙,例如它可能是“等待所有先前的绘制命令完全完成,然后清理并使所有不具有自动一致性的缓存无效,然后允许后续绘制命令开始顶点获取和顶点着色。”
我认为管道障碍是内核模式驱动程序中命令的一种重新排序,但它似乎不是真的。我还认为它可能类似于驱动程序端 GPU 调度程序的提示,但它似乎仍然不是真的。它只是构建 KMD 主命令缓冲区的提示,还是管道屏障代表了 GPU 命令处理器的某种指令?
编辑:如何实施管道障碍?
正如 Nicol 所说,细节将根据具体实施和障碍而定。但总的原理是相似的。
GPU 是流水线处理器,这意味着每个命令都要经过多个执行阶段。 运行 并发阶段,在绘制调用内部和绘制调用之间。例如,绘制命令 N 的片段处理可能与绘制命令 N+1 的顶点处理同时执行。屏障命令可防止后续命令的工作在先前命令完成 srcStageMask
中的所有阶段之前开始执行 dstStageMask
中的任何阶段。除了这个 执行屏障 之外,管道屏障还可以包括一个 内存屏障 ,它确保前面的命令完成的内存访问是正确排序的与后面命令的内存访问。
所以 none 这与重新排序有关,它只与新命令在先前命令完成之前开始这一事实有关,有时您需要防止这种情况发生。最明显的例子是渲染到纹理:您希望在对纹理进行任何读取之前完成对纹理的所有写入。没有管道障碍,没有什么能阻止它们重叠。
通常 GPU 会有一个(内部)命令,在先前的命令全部通过命令执行的点后“发出信号”一些标记,另一个命令在允许任何后续命令之前“等待”一些标记发出信号继续工作。标记可能只是一个内存位置(信号:写入特定值,等待:旋转直到该位置包含特定值)。或者它可能是某种特殊用途的片上资源。障碍将只是一个信号命令,后跟一个等待命令。这会在部分 GPU 闲置的管道中产生“气泡”。为了尽量减少这种情况,一些 GPU 将能够在管道中的多个点发出信号并等待。通常能够在颜色写入完成后发出信号,并在光栅化之前等待,例如,允许在绘制 N+1 的片段工作发生时进行绘制 N+1 的顶点工作,但停止 N+1 片段工作。 srcStageMask
和 dstStageMask
允许实现准确地知道依赖项是什么,但大多数实际上不能利用这种精细的粒度,并且会产生更粗糙的保守气泡。
内存屏障对应于缓存清理(将脏行写入内存)和缓存无效(删除缓存数据)操作。 “可见性”意味着清理本地缓存,将数据写回内存,以便以后从内存中读取的任何内容都将看到新值。 “可用性”意味着使本地缓存失效,这样任何新的读取都将在缓存中丢失(而不是看到旧数据)并从内存中获取。 GPU 通常针对这些针对不同本地缓存(例如纹理缓存、depth/stencil 缓存等)的特定操作具有特殊命令。
因此在渲染到纹理的情况下,您将在纹理渲染命令和从纹理读取的任何命令之间插入管道屏障。驱动程序会为 GPU 生成一个命令(或多个命令),等待先前的命令完成混合阶段的执行,然后清理颜色附件缓存,然后向某个标记发出信号。然后它会生成 GPU 命令以等待标记发出信号并使纹理缓存无效,然后再允许任何未来的绘制调用开始片段着色。
正如我之前所说,GPU 提供的实际命令可能比这更粗糙,例如它可能是“等待所有先前的绘制命令完全完成,然后清理并使所有不具有自动一致性的缓存无效,然后允许后续绘制命令开始顶点获取和顶点着色。”