790b93843d9dbd05d52cf749252b6cf5
WWDC20 {10602} 使用 Metal 技术驾驭 Apple 图形处理器

前言

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

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

概况

本 Session 主要讲两个部分。

1. TBDR GPUs

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

  1. IMR 模式
  2. TBR 模式
  3. TBDR 模式

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

2. 最新 GPUs

对渲染管线的一些加强。
GPU 的重要性在于:

  1. 它是一系列处理器的核心之一。
  2. 使用量巨大,全世界有 10 亿以上的设备使用了苹果的 GPU 。


苹果处理器的基本特点:

  1. 苹果处理器非常高效
  2. 他们共享统一的内存架构,也就是说 CPU 和 GPU 共享系统内存。而且 GPU 有自己独立的内存,叫贴图内存(显卡内存)
  3. GPU 没有自己的视频内存,所以当视频内容没有被调整的话,带宽就会是一个问题
  4. GPU 特有的 TBDR 架构解决视频内存问题

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

  1. 顶点和片元阶段重叠
  2. 隐面消除
  3. 可编程混合
  4. 低内存渲染目标
  5. MSAA 实现

正文

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

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

  1. 处理几何计算(顶点)的贴图阶段
  2. 处理像素的渲染阶段

贴图阶段

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

  1. 把视图分割成一系列的图块
  2. 然后着色所有的顶点
  3. 并把转换过的图元放到这些图块中

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

渲染阶段

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

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

  1. 加载
  2. 光栅化图元和计算他们的可见度
  3. 着色所有可见的像素
  4. 执行存储操作

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

加载和存储操作

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

隐面消除- HSR

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

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

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

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

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

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

top Created with Sketch.