图形软件开发-linux图形界面开发
喂养
随着移动端引擎渲染特性,如HDR、PBR、SSR、完整的后处理管线等不断增加,直接照搬端游方案很容易推翻。 很多时候需要适配移动端。 这时候,只有充分了解移动端的底层硬件,才能得到最优解。 本文将从引擎开发者的角度阐述对移动端GPU架构的理解。
从 IMR 开始
IMR常用于PC、主机、笔记本等设备,最大的特点就是Primitive提交后直接绘制,如下图
这与 RTR 上的 Pipeline 是一致的。
硬件层面的渲染流程如下图所示。
IMR 中的内存访问
首先要确认的是,FrameBuffer一直保存在SystemMemory上,而每个Primitive渲染都会读写DepthStencil,SceneColor,这些都是放在System Memory上,读取System Memory(也叫Main Memory,也叫DDR,也叫DRAM)计算机上的数据经过计算后写入主存。
假设FrameBuffer是存储在主存中的连续内存,那么每一个三角形在绘制的时候其实就是一次随机的内存访问。 这种随机性即使在加入了Cache机制之后,仍然会造成大量的性能消耗。
IMR的优点和缺点
优点 - 简单流畅的流程确保在单个图元渲染过程中没有额外的中间结果存储。
缺点 - 带宽消耗。
假设渲染一张1440p的图片,使用32bit SceneColor,32bit Depth/stencil,那么整体需要的内存大小是30m,如果需要同时随机访问整个FrameBuffer,即使有Cache机制,也会触发大量从机从系统内存读取缓存并从缓存写入系统内存。
移动解决方案 - TBDR
与桌面GPU相比,移动硬件设计的目的只是为了追求更高的帧率。 移动端方案需要同时考虑更低的发热量、更低的功耗和更高的性能,并在其中找到平衡点。 因此,移动硬件设计中最重要的是尽可能减少带宽消耗。 于是就有了TBDR(Tiled Based Deferred Rendering)。
整个FrameBuffer被分成多个块,称为Tile,由Tile渲染。 每渲染一个Tile,就取出当前Tile影响的Primitives,进行相应的三角变换、着色、深度测试。 , 将结果写回主存,
AMD早年分享的时候做过一个实验,比较了用同样的方式渲染两个三角形所产生的带宽消耗
硬件和PC有两个区别:
1.显存和系统内存是共享的,直接和GPU和显存打交道是非常昂贵的。
2、在GPU上封装了一个小型的高速存储空间,称为On-chip memory(也叫Tile Memory,也叫on-chip framebuffer,Tile Buffer等),这个内存在第二阶段渲染这个部分显存会被使用,大小因GPU设计不同而不同,最小可能只能覆盖16×16像素。
当然,有些厂商也做了多级缓存机制,比如最新的苹果芯片,除了每个Shader Core都有自己的L1 Cache外,还增加了GPU Last Level Cache,进一步减少了数据之间的传输GPU 和主存储器。 成本。
详解TBDR渲染过程
完整的流水线可以参考下图
伪代码如下
# Phase one
for draw in renderPass:
for primitive in draw:
for vertex in primitive:
execute_vertex_shader(vertex)
if primitive not culled:
append_tile_list(primitive)
# Phase two
for tile in renderPass:
for primitive in tile:
for fragment in primitive:
execute_fragment_shader(fragment)
上述过程可以分为两个阶段——平铺阶段和渲染阶段。
平铺阶段
绘制瓦片时,只要涉及到当前瓦片的图元,就需要提前计算。 这个计算过程称为 Tilling(也称为 Binning)。
Tilling Phase 做三件事
1.将当前ViewPort分成多个Tile图形软件开发,
2.执行VertexShader,三角形变换到屏幕空间
3. 计算哪些瓦片会受到Primitive的影响,并将结果存入主存。
Tilling计算的结果会存储在主存中,称为Intermediate store(也叫polygon lists,也叫Frame Data图形软件开发,也叫parameter buffer,也叫Geometry Work Set),以后分块渲染的时候从主存中执行加载这个数据,但是代价要小很多,还要注意顶点的数量,不要让这个缓冲区膨胀得太大。
这是一个简单的示意图动画
渲染阶段
Tiling 之后,GPU 依次渲染这些 Tiles。 每个 GPU Core 一次渲染一个 Tile。 Cores 越多,可以同时渲染的 Tiles 就越多。
挑出几个重要的点
硬件级别的 RenderPass
简单的说,就是渲染管线的一次执行。 RenderPass 会将渲染结果存储在 FBO 的 Attachments 中。 每个Attachment都需要在Tile上初始化(Load Action),并且可能需要写回SystemMemory(SaveAction)。
磁贴内存加载存储操作
对于OnChip和System Memory之间的内存拷贝,我们通常称之为Resolve,甚至有Light weight resolve(从OnChip到System Memory)和Heavy weight resolve(从System Memory到OnChip再写回System Memory)。 ,另外,MSAA还有一个关于resoving的声明,所以...
Resolve 的具体含义取决于上下文。
但是现在有另一种方式来表示 Load Action 和 Store Action。 如果内存是从TileMemory写入SysemMemory,说明Store Action是Store。
一共有三个Load Actions,DontCare,Load,Clear。 Store Actions一共有三种,Store、DontCare、storeAndMultisampleResolve、MultisampleResolve。 请参阅 Apple 的文档 Load and Store Actions 以了解每个 Action 的详细说明。
如果要优化管道的性能,必须注意设置每个RenderTarget的Load Action和Store Actions。
比如Depth和Stencil通常只用在Rasterize阶段,所以直接放在Onchip上,Store Actions设置为DontCare这样结果就不用写到主存了,节省了很多带宽。
资源存储方式
StorageMode通常用来表示CPU和GPU对内存中对象的访问方式,通常是Shared、Private、Memoryless,如下图
Shared——CPU和GPU都可以访问,这类资源通常由CPU创建和更新。
Private- 存储在SystemMemory中,只有GPU可以访问,通常用于绘制渲染目标,Compute Shader存储中间结果或纹理流。
Memotyless- 有TileMemory,只能访问当前的Tile,用完会刷新。 比如在iOS memoryless上Depth/Stencil Buffer应该设置为所有不需要解析(或者store action设置为don't care)的rts,比如上面提到的Depth和Stencil。
在 Tiled Base 延迟渲染中延迟
其实这里有两个Deferred。 一种是PS上色不是在VS之后马上进行,所有厂商的手机芯片都是这样。 另一个 Deferred 是 Power VR 和 Apple 芯片独有的。 这个Deferred是指所有像素都通过可见性检测后才进行着色操作。 这种可见性确定操作称为 HSR。 下图是详细的HSR流程。
其实各个厂商都有一些相关的算法来消除Overdraw,比如Mali的Forward Pixel Kill(FPK),比如Qualcomm的A Low Resolution Z(LRZ),具体算法和原理可以参考最后一个链接。
TBDR 的优点和缺点
出色的
1.节省带宽
2、由于OnChip Memory的存在,一些不需要解析的信息只能存储在OnChip中,可以节省System Memory。
3. Tile渲染对Texture Cache更友好
下
1. 屏幕尺寸越大,分块数越多,生成的Geometry WorkSet也越大。
2. Tilling Phase是完全冗余的,打断流水线的执行并引入延迟。
性能调优
主要介绍Profile工具。 之前写过高级图形调试和优化技巧——XCode文章。 感兴趣的可以点击查看。 不过最新版的xcode有很多新功能。 最好去wwdc视频上学一遍。
XCode抓帧后,每个RenderPass单独标注,每个Attachment的Load Action和Save Action)和Memory Type都有标注,还可以看到当前pass的带宽消耗和当前帧的总带宽消耗。
Android下可以使用Renderdoc,但是API需要是Vulkan。 捕获帧后,您可以看到每个通道和相应的加载存储操作。
当然,还有其他厂商如Arm、Qualcomm提供的工具。 一般来说,Xcode 更容易使用。
概括
移动硬件发展至今,大型渲染框架还是TB(D)R。 但随着硬件工艺和技术的迭代,移动硬件所能提供的性能空间也在飞速发展,各种移动渲染技术层出不穷。 ,如何合理地使用和分配这些性能空间是引擎开发者的必备技能。
另一方面,移动端和桌面端的硬件差异也会越来越小。 几年前的Switch掌机不用多说,还是苹果去年发布的arm架构的M1芯片。 一些桌面 GPU 甚至使用 TBR 进行性能优化,称为 partially-tile-based rendering
移动端也有在某些情况下切换IMR渲染的技术,比如高通的FlexRender。
以后我会继续写几篇关于移动端高性能图形开发的文章,敬请期待。
参考
Tile-Based Renderingdeveloper.arm.com/solutPerformance Tuning for Tile-Based Architectures - OpenGL Insights Chapter.23 ARM's
探索马里 Midgard 架构 - anandtech.com/show/8234
下一代基于图块的 GPU - developer.amd.com/wordp
GPU 帧缓冲内存:了解平铺 -developer.samsung.com/g
移动设备的最佳实践
高性能原理 -developer.arm.com/solutA 新的基于软件的 GPU 框架 Evgeny Miretsky 2013
关于 NVIDIA 基于图块的渲染 - techpowerup.com/231129/
Nvidia GPU 中基于图块的光栅化 -realworldtech.com/tile-
了解 GPU 系列 4 - developer.apple.com/doc
GPU 的工作原理 - cs184.eecs.berkeley.edu
虚幻引擎 4 的 PowerVR 性能技巧 - imaginationtech.com/blo
加载和存储操作 -developer.apple.com/lib
Killing Pixels - ARM Mali GPU 着色的新优化 -community.arm.com/devel
可见性处理 - developer.qualcomm.com/
过去精选
免责声明:发表此文是为了传递更多的知识,以供交流学习。 如有来源标注错误或侵犯您的合法权益,请联系我们并提供权属证明,我们将及时更正和删除,谢谢。