使用 Metal 技术驾驭 Apple 图形处理器

作者:MahomeAlex, iOS 开发工程师

 

Sessions: https://developer.apple.com/videos/play/wwdc2020/10602/

前言

本文内容基于  WWDC 2020 Session 602 Harness Apple GPUs with Metal[1] 整理。

本 Session 主要讲的是 Metal 如何和 Apple 图形处理器特性相结合,为我们呈现完美的高性能 App 和游戏体验。因为讲的是 GPU (硬件),所以我们只谈渲染管线,不涉及代码。

当然希望您有基本的 Metal 和图形渲染知识,以便更好的理解本 Session 的内容。

概况

本 Session 主要讲两个部分。

TBDR GPUs

贴图延迟渲染 TBDR ( Tile Based Deferred Rendering ) 是一种更*的渲染架构,负责基本的管线渲染。移动端 GPU 渲染模式发展是:

  • IMR 模式

  • TBR 模式

  • TBDR 模式

有兴趣的可以另行了解,这里不做展开。

最新 GPUs

对渲染管线的一些加强。

GPU 的重要性在于:

  1. 它是一系列处理器的核心之一。

  2. 使用量巨大,全世界有 10 亿以上的设备使用了苹果的 GPU 。

使用 Metal 技术驾驭 Apple 图形处理器

苹果处理器的基本特点:

  1. 苹果处理器非常高效

  2. 他们共享统一的内存架构,也就是说 CPU 和 GPU 共享系统内存。而且 GPU 有自己独立的内存,叫贴图内存(显卡内存)

  3. GPU 没有自己的视频内存,所以当视频内容没有被调整的话,带宽就会是一个问题

  4. GPU 特有的 TBDR 架构解决视频内存问题

接下来会讲一下渲染管线还有它的一些特性。接下来会讲几个方面:

  1. 顶点和片元阶段重叠

  2. 隐面消除

  3. 可编程混合

  4. 低内存渲染目标

  5. MSAA 实现

正文

首先我们看一下图形管线:

使用 Metal 技术驾驭 Apple 图形处理器

我们的 GPU 是基于 TBDR 框架的,TBDR 有两个主要阶段:

  1. 处理几何计算(顶点)的贴图阶段

  2. 处理像素的渲染阶段

贴图阶段

使用 Metal 技术驾驭 Apple 图形处理器

在对整个渲染通道中,GPU 主要做这几个步骤:

  1. 把视图分割成一系列的图块

  2. 然后着色所有的顶点

  3. 并把转换过的图元放到这些图块中

GPU 并没有很大的专有内存池,所以这些转换后的数据就会放到贴图的顶点缓冲区中:Tiled Vertex Buffer。顶点缓冲区缓存了贴图阶段的输出内容,包括转化后的顶点数据,还有其他的内部数据,他们对我们都是不透明的。但是当数据满了的话会引发一个本地渲染,意思是当 GPU 分割渲染通道从而刷新缓冲区的内容。不过我们只需要知道顶点缓冲区的存在,并不用担心什么。

渲染阶段

GPU 把整个视图切成一块块的图块,接下来就是单独渲染这块图块。

使用 Metal 技术驾驭 Apple 图形处理器

渲染阶段,GPU 在渲染通道里会对每个图块执行如下操作:

  1. 加载

  2. 光栅化图元和计算他们的可见度

  3. 着色所有可见的像素

  4. 执行存储操作

这些对应用都是不透明的,而且执行的很快。每个图块都会被执行加载和存储操作。

加载和存储操作

使用 Metal 技术驾驭 Apple 图形处理器

对加载和存储操作来说,在通道的开始阶段,我们会告诉 GPU 如何初始化图块内存,结束时又会告诉 GPU 如何处理最终渲染,推荐只加载我们需要用到的数据,如果什么都不需要,那就不要加载并且做清除操作,这样可以省下用来上传颜色附件,深度信息和模板缓冲的内存。存储操作也是如此,尽量节约内存开销对渲染非常有用。

隐面消除- HSR

渲染阶段的另一个重要点就是 HSR(隐面消除),这是在渲染之前发生的,归功于芯片的深度缓存信息,也是 TBDR 的一个关键点之一。HSR 通过持续追踪图层每个像素点的可见区域来让 GPU 实现最小绘制区域。HSR 是像素最优和命令提交隔离的。所以像素处理分两个阶段,隐面消除和片元处理。比如,即使你想画两个前后顺序的三角形,HSR 也会确保没有多余绘制。

使用 Metal 技术驾驭 Apple 图形处理器

假设我们要从后往前绘制三个三角形。依次是蓝色,橙色,和一个半透明的紫色三角形。

使用 Metal 技术驾驭 Apple 图形处理器

HSR 会持续追踪可视化信息,而且每个像素都会保留最前面图元的深度信息和图元 ID,这种情况下,以为是背景颜色也会用到,因为我们还没光栅化任何事情。

首先,我们光栅化第一个图元(蓝色那个)。

使用 Metal 技术驾驭 Apple 图形处理器

这个图元会把深度信息记录到覆盖到像素点上,这时候并没有走着色流程,然后光栅化第二个三角形。

使用 Metal 技术驾驭 Apple 图形处理器

因为这个在前面,所以需要更新它所覆盖到的像素的图元信息。GPU 会计算每个像素的可视化情况,但是不会着色。接着第三个三角形。

使用 Metal 技术驾驭 Apple 图形处理器

HSR 只保留每个像素最前面图元的 ID,但是现在有一个图元需要着色。这个时候, HSR 块就会刷新半透明图元覆盖到的所以像素点,GPU 就没办法再延迟渲染了,不过只会刷新被覆盖到的点,然后得到正确的图元信息。因为是最后的图元,所以可见缓冲区内的其他点也会被着色。从而完整着色所有点。这里我们可以发现,有的点只是被着色一次。尽管存在多个片元重叠,但是这些像素点并没有多次重绘。在这种情况下,重绘的只是每个点所涉及到的片元着色器的数量,尽量控制数量。优先处理不透明的材质,然后做 Alpha 测试,丢弃或者深度反馈,最终是那些半透明的材质,避免交叉不透明和半透明材质,或者是有颜色附件的掩图等,最优化  HSR 效率可以降低重绘率。

所以在有半透明材质的场景下,重绘依赖于 HSR 的效率, 所以想尽办法提高效率,根据材质特性调整顺序:

  1. 优先不透明材质

  2. 做 Alpha 测试,丢弃或者深度反馈

  3. 半透明材质

Alpha 混合

回到刚才的例子,这次把半透明三角形放到第二的位置。

使用 Metal 技术驾驭 Apple 图形处理器

如果我们从后往前提交,就会遇到不同的可视化状态,这种情况下,交叉不透明和半透明图元是不高效的,很多像素刚着色完又会被下一个图元遮罩,然后重新着色。为了优化效率,我们先渲染所有不透明几何体,通过先后提交顺序去掉排序环节,然后到片元处理阶段,因为显卡自带帧缓冲,这个过程非常快。

使用 Metal 技术驾驭 Apple 图形处理器

Alpha 混合也是在显卡内存中实现,而且没有混合单元,当我们执行加载和存储行为读写渲染目标的任务就完成了。不过有时候传统的 Alpha 混合并不够,比如像全局迷雾或者延迟光照这种需要自定义混合的全局效果。

大多数的混合都会把附件存储起来,以便下一个通道用到。所以 GPU 开发了可编程混合模式

使用 Metal 技术驾驭 Apple 图形处理器

允许片元着色器直接操作贴图内存,这样就可以把多个通道融合成一个从而大幅降低带宽。在这里例子中,我们不需要加载或者存储任何中间渲染目标, 不过还是有些浪费的地方。比如有些渲染目标并没有加载和存储,只是在贴图内存中使用了。而且他们是非常大的纹理内存。针对这点,TDBR 提出了低内存渲染目标概念,意思是极低内存占用的纹理。

低内存渲染目标

使用 Metal 技术驾驭 Apple 图形处理器

这里先讲一下锯齿问题。

使用 Metal 技术驾驭 Apple 图形处理器

我们经常在游戏等场景中见到那种锯齿类型或性质的纹理样式,GPU 会采样中间像素,并且只着色交叉的相同点的图元。

使用 Metal 技术驾驭 Apple 图形处理器

抗锯齿就是一种非常常见用于光栅化多采样每个像素点的技术,以更优的像素处理解决方法,从而获得更好的 UI 效果。主要体现在:

  1. 着色器会对渲染三角形覆盖到的每个像素,然后混合其他的采样点。从而让图元的边角变得平滑。

  2. 检测图元的边缘,非边缘像素是整个像素混合,边缘的做采样着色。

  3. 多采样的数据还会存储到芯片的内存中,并且在图元被刷新的时候删除,使得存储行为非常高效。

这种低内存模式还可以省下足迹内存开销,比如像这样的纹理,在通道最后,我们只存储了多采样的数据,从而节省了大量的存储多采样纹理的带宽,因为他们存储在贴图内存中。这样的纹理就非常短暂,根部不需要加载和存储,从而实现真正的低内存开销。TBDR 还有一个特性是图块和渲染在渲染通道中是不同阶段的,这样就允许贴图可以混合上一个通道的渲染结果。

使用 Metal 技术驾驭 Apple 图形处理器

在优秀的 TBDR 架构下,苹果设计的 Metal 可以快速的调用框架,两者相得益彰。Metal 开发了一个特有的图形和计算机框架和一些 TBDR 功能,比如可编程渲染,低内存渲染目标,明确的提交模型和多线程,这些深度的软硬件优化使得算法优化非常容易,比如:

延迟渲染

使用 Metal 技术驾驭 Apple 图形处理器

延迟渲染是多通道算法,可以在实际的呈现过程中解耦渲染的场景特性。一般情况下,我们可以认为每一个算法阶段都是一个渲染通道,这样需要着色出结果然后采样很多数据从而最终渲染,非常耗带宽,而且会有很多临时内存去存储纹理和缓存数据。所以在前面几个优化特性下,我们可以让算法非常高效运行。

Modern Apple GPUs

使用 Metal 技术驾驭 Apple 图形处理器

苹果自 A11 开始就重新设计和平衡了 GPU,从而支持更现代化的渲染算法,管理复杂的数据结果和更高的数据精度,并且做了几个非常稀有的优化。下图是 TBDR 管线。

使用 Metal 技术驾驭 Apple 图形处理器

大部分的改动都在这里。苹果新增了一个芯片图块和可编程图块计算。

图块

使用 Metal 技术驾驭 Apple 图形处理器

图块是 2D 数据结构,有宽高和深度信息,存在贴图内存中,可以被片元函数和内存函数访问,明确使用这种数据结构可以获得很高的收益。

使用 Metal 技术驾驭 Apple 图形处理器

在图块之前,我们可能得把纹理一点点的移到线程池的内存中,但是 CPU 不知道你在操作图片数据,所以只能把数据存储起来。有了图块之后,我们可以一次性加载和存储。

图块着色

使用 Metal 技术驾驭 Apple 图形处理器

图块着色是系统内核函数,我们可以进行分发,从而在渲染通道中去改变图块信息,分发行为是和绘制操作交错的。而且他们是跟前后绘制操作隔离的,所以不需要关心同步问题。贴图着色和图块都会应用 MSAA 技术,而且可以灵活开关。

使用 Metal 技术驾驭 Apple 图形处理器

为了更好地扩展图块和图块着色能力,图块采样覆盖控制可以控制到每个像素采样覆盖的数据,甚至于多采样通道,从而可以深度的发挥 MSAA 效果。在一些有很多不透明或者半透明几何体的复杂场景,比如粒子效果下,大量的小半透明三角形需要每个像素点都有很多采样,这种情况就需要在渲染前用图块把用贴图管线把采样数据处理下,而这个能力就可以通过图块管线处理采样数据,通过渲染这些不透明材质,确保所有的像素点都有单一的颜色,而且这也是可编程的。支持对每中类型的渲染目标定制通道,比如 HDR 颜色或者线性深度。总之,贴图着色和图块给 GPU 提供了很多灵活性,帮助我们去优化 TBDR 架构。

Metal

Metal 使得优化 GPU 的能力成为可能,主要体现在精确地控制贴图内存和 GPU 驱动型渲染。Metal 允许通过贴图着色器,图块,和持有线程池内存直接使用贴图内存,从而优化一些复杂算法的效率,比如图块延迟渲染。我们可以认为这是一个更高级版本的延迟渲染,在大型的着色场景下效果更明显。

使用 Metal 技术驾驭 Apple 图形处理器

这个算法增加了一个额外的步骤,把光线切成小图块,这些图块通过后面的计算通道用来渲染场景。所以,如果要用延迟渲染,就需要添加额外的计算步骤去切割光线。我们也可以用估算来做光线卷积计算,但是会阻止 GPU 整合管线,因为可编程渲染只允许一次处理单一像素,导致光线切割成本太高昂。好在图块着色允许整块处理,这样就能交叉渲染计算,从而把三个渲染通道整合成一个,效率可想而知。

Metal 还通过 GPU 驱动渲染模式更大的发挥能力,因为 Metal 独有的自变量缓冲和间接命令缓冲,当然整个渲染流程是 CPU 驱动的。因为数据集和传送数据过程是很复杂的,需要几个结构来定义整个场景。

使用 Metal 技术驾驭 Apple 图形处理器

在这个例子中包含你了一些网格,材质和模型,每个模型包含标记父网格和对镜材质。主要问题是当我们要开始渲染时,我们不能每帧都全部渲染。

使用 Metal 技术驾驭 Apple 图形处理器

这时 CPU 会基于上一帧和视景的遮罩决定哪个图形需要渲染,还需要选择适当的细节。这个就需要一些同步点,CPU 需要读取 GPU 写入的遮罩数据,从而发出绘制命令。所以这里就有两个问题需要解决,遍历场景描述和编码绘制命令。

使用 Metal 技术驾驭 Apple 图形处理器

Metal 提供了几点帮助:

  1. 自变量缓冲,使得场景数据在 GPU 上可用, 而且可以定义复杂数据结构

  2. 间接命令缓冲,允许 GPU 编码绘图指令。

所以这种场景就可以通过一个自变量缓冲数据来解决,而且 GPU 可以很方便地传输。

使用 Metal 技术驾驭 Apple 图形处理器

所以 GPU 管理渲染回路的步骤是:

  1. 遍历场景渲染遮罩。

  2. 再遍历场景剔除不可见像素和细节选择。

  3. 最终渲染场景。

这些都不需要做 CPU 和 GPU 同步流程。

使用 Metal 技术驾驭 Apple 图形处理器

通过 Modern Rendering with Metal[2] 的代码可以学习如那个何实现这些算法,包括了一个完全的 GPU 驱动渲染循环。这些是用新的结构,比如自定义缓存或间接命令缓存写的,还利用了 GPU 的那些能力,包括图块着色,图块,低内存纹理和可变的光栅化率。这些只是概要,具体需要深入去学习。今天的 Session 就到此。

来源 中华文学

使用 Metal 技术驾驭 Apple 图形处理器

上一篇:【java每日一学】Applet类详解


下一篇:create-react-app添加对TypeScript支持