HPP_Graphics_3.7 移动端TB(D)R架构基础

a). 名词解释

System on Chip(Soc)

  • Soc是把CPU、GPU、内存、通信基带、GPS模块等整合在一起的芯片的称呼。常见有A系Soc(苹果),骁龙Soc(高通),麒麟Soc(华为),联发科Soc,猎户座Soc(三星),去年苹果推出的M系Soc,暂用于Mac,但这说明手机、笔记本和PC的通用芯片已经出现了

物理内存

  • 也就是我们常说的手机内存,也叫System Memory。Soc中CPU和GPU共用一块片内LPDDR物理内存。此外CPU和GPU还分别有自己的告诉SRAM的Cache缓存,也叫On-chip Memory。读取System Memory的时间消耗大概是On-chip Memory的几倍到几十倍

On-Chip Buffer

在TB(D)R架构下会存储Tile的颜色、深度和模板缓冲,读写修改都非常快。如果Load/Store指令中缓冲需要被Preserve,将会被写入一份到System Memory中。

Stall

当GPU两次计算结果之间有依赖关系而必须串行时,等待的过程便是Stall

FillRate

像素填充率 = ROP运行的时钟频率 x ROP的个数 x 每个时钟ROP可以处理的像素个数

TBR(Tile-Based (Deferred) Rendering)

TBR(Tile-Based (Deferred) Rendering)是目前主流的移动GPU渲染架构,对应一般PC上的GPU渲染架构则是IMR(Immediate Mode Rendering )。

  • TBR流水线:顶点着色器 - Defer - 光栅化 - 片元着色器
  • TBDR流水线:顶点着色器 - Defer - 光栅化 - Defer - 片元着色器

Deffer

延迟,从渲染数据的角度来看,就是 ”阻塞+批处理“ GPU ”一帧“ 的多个数据,然后一起处理


b). 立即渲染(IMR,Immediate Mode Rendering )

  • IMR是PC上GPU采用的架构

    IMR

    IMR_Pipeline

    IMR_Pipeline2

c). 基于块元渲染的TB(D)R

TB(D)R宏观上总共分为两个阶段:

  1. 分图元: 第一阶段执行所有几何相关的处理,并生成Primitive List(图元列表),并且确定每个Tile上面有哪些Primitive
  2. 第二阶段逐Tile执行 光栅化后 写入Tile Buffer(片上内存),并在完成后将 Frame BUffer 从 Tile Buffer 写回到 System Memory中;

TBR_TBDR_Flow

c.1). TBDR Pipeline

下图为PowerVR的TBDR:

TBDR_Pipeline

  • Tilling后将图元列表和顶点数据传到System Memory,待需要光栅化时从System Memory取出。光栅化后进行HSR(因为是PowerVR的流程图所以是HSR)或Depth Test会将结果写入On-chip Buffer。同样,在逐片元操作后,会将Tile的结果写入Tile Buffer,并在完成Frame Buffer后从Tile Buffer写回到System Memory中

下图为三星提出的流程图:

TBDR_Pipeline2

c.2). TBR和IMR对比

(a)为TBR,(b)为IMR

TBR_IMR

  • TBR的核心目的是降低带宽,减少功耗,但渲染帧率上并不比IMR

  • 图(a)TBR架构

    • 几何处理数据形成了FrameData(放在System Memory上)

    • 这些Frame Data经过片段处理,结果放在了Tile Buffer上(片的内存上)

    • 最后的结果会刷到FrameBuffer中(System Memory上)

  • 图(b)IMR架构

    • 对比TBR有以下两种区别
      • 几何处理数据直接到片段处理,没有中间数据(Frame Data)
      • 直接刷到System Memory上了,没有经过片内存(On-Chip Memory)

TBR优点:

  1. TBR大大减少了Overdraw,PowerVR使用了HSR技术,Mali使用了Forward Pixel Killing技术,目的是为了最大限度减少被遮挡Pixel的Texturing和shading;
  2. TBR是Cache friendly,在cache里读写的速度比全局内存的速度要快得多,以降低帧率为代价,降低带宽,省电;

TBR缺点:

  1. Binning过程在Vertex阶段之后,将输出的集合数据写入到System Memory,然后才被FS读取,集合数据过多的管线,容易在Binning过程产生性能瓶颈;
  2. 如一个三角形同时在多个Tile上,需要多次绘制(和Games101RayTracing中空间划分容易造成同一个Object存在多个叶子节点的原因类似)。这意味着总渲染时间高于IMR;

d). 第一个Defer:Binning

  • 概念:将图元分配到块元的过程

  • 过程:

    Binning

  • 注释:

    • 第二幅图里的红色三角形,只用一个块元就能渲染,所以它只会被分配到一个块元中
    • 第四幅图里的棕色三角形,需要多个块元才能渲染,所以它需要分配到9个块元中一起渲染
  • 如果你的项目中binning过程相比其他耗时长的话,就要考虑一下是不是几何数据过多了

e). 第二个Defer:不同GPU 的 Early-Depth-Test

Forward Pixel Kill

Forward Pixel Kill

  • Arm Mali
    • 采用Forward Pixel Kill技术
  • 位于管线的位置:

    • 发生在Early-z之后
  • 数据结构:

    • 先进先出的队列
  • 简单概括一下:

    • 队列中有4个Quad(可以理解为2×2像素的平面),每个Quad有屏幕上位置的数据和Z数据

    • Z越大代表离摄像机越远

    • 根据屏幕上相同位置(pos)的不同z,对不透明的像素进行替换(有近的就不渲染远的),这个过程叫作killed

HSR

HSR

  • PowerVR的HSR

    • HSR = Hide Surface Removal隐形面剔除
  • 大体实现原理:

    • 虚拟出一个射线,当它遇到第一个不透明的物体时就会停下来,这样就会打断后面三角形的后续ps处理

f). 优化建议

  1. 记得在不使用FrameBuffer的时候clear或discard

    • 这样做主要是为了清空积存在tile buffer上的中间数据(前边提到的Frame Data),

    • 所以对Unity里的rt(render texture)的使用也特别说明一下:

    • 当我们不再使用这个rt的时候,尽量调用一次Discard

    • 在OpenGl ES上,要善用glclear,glInvalidateFrameBuffer,避免不必要的Resolve(tile buff刷新到system memory)行为

  2. 不要在一帧里频繁的切换FrameBuffer的绑定

    • 本质:减少tile buffer和system memory之间的stall(同步)操作
  1. 对于移动平台,建议使用Alpha混合,而非Alpha测试。
    • 是一个经验性的结论
    • 在实际使用的过程中应该使用比较两者的表现
    • 通常情况下,移动端应该避免使用Alpha混合来实现透明,如果确实要用,尝试缩小混合区域的覆盖范围
  1. 手机上必须用Alpha Test时,先做一遍Depth Prepass(参考Alpha Test 的双pass优化思路)
  2. 图片尽量压缩
    • 例如ASTC 、ETC2
  1. 图片尽量走mipmap

  2. 尽量使用从vertex shader传来的Varying变量uv值采样贴图(连续的),不要在Fragment shader里动态计算贴图的uv值(非连续的),否则CacheMiss

  3. 在延迟渲染中,尽量利用Tile Buffer(参考传统延迟渲染和TBDR)

  4. 如果在Unity中调整ProjectSetting—-Quality—-Rendering—-Texture Quality的不同设置,或者不同分辨率下,帧率有很大的变化,大概率是带宽出问题了

  5. MASS在TBDR下反而是非常快速的

    • MSAA是硬件上的,发生在片上的

      TBDR_Pipeline

      • 可以看到Tilling后的几何数据存到System Memory后,在Texture and Shade时仍然可以调用,这也为MSAA提供了便利
    • 相比FSAA,MSAA在手机上是非常快的

  1. 少在Fragment shader中使用discard函数,调用gl_FragDepth从而打断Early-DT的过程

    • (hlsl中为Clip,glsl中为discard)
  2. 在shader使用浮点数精度值时,有目的的区分使用float,half

    • 优点
      • 带宽减少
      • GPU中用的周期数减少,因为着色器编译器可以优化你的代码来提高并行化程度
      • 要求的统一变量寄存器的数量减少,这样反而又降低了寄存器数量溢出风险。
      • 具体参考:熊大的优化建议、shader数学计算优化技巧
  3. 在移动端的TBDR架构中,顶点处理部分(Binning过程)容易成为瓶颈

    • 避免使用曲面细分shader,置换贴图等负操作
    • 提倡使用模型LOD,(本质上减少Frame Data的压力)

    • Unity中尽早的在应用阶段做umbra(Unity内置)遮挡剔除、gpu的occlusion cull


【补充链接】

GPU性能指标 _

三星的GPU-FrameBuff指导

英伟达的TBR教学文章

ARM的TBR教学文章

苹果OpenGL程序开发指南

OpenGL Insights

知乎文章:Tile-based 和 Full-screen 方式的 Rasterization 相比有什么优劣

移动图形芯片的故事

移动设备GPU架构知识汇总

再议移动平台的AlphaTest效率问题

移动平台GPU硬件学习与理解

PowerVR开发者指南

Performance Tunning for Tile-Based Architecture Tile-Based架构下的性能调校

TBDR的HSR流程细节和使用AlphaBlend的效率提升程度

当我们谈优化时,我们谈些什么

https://edu.uwa4d.com/course-intro/1/179 虽然是收费的 但是很值得买,推荐

Alpha Test的双pass 优化思路

个人收藏

Adreno Hardware Tutorial 3: Tile Based Rendering

Mali GPU的独有特性

Mali-T880

《Unity3D内建着色器源码剖析》

作者熊大的优化建议

GPU画像素的顺序是什么

Tile-based Rasterization in Nvidia GPUs with David Kanter of Real World Tech