游戏引擎架构#4 低阶渲染器(2)

已发布在微信公众号上,点击跳转

背景:

作为游戏开发从业者,从业务到语言到框架到引擎,积累了一些知识和经验,特别是在看了几遍《游戏引擎架构》后对引擎架构的理解又深入了些。

近段时间有对引擎剖析的想法,正好借这书本对游戏引擎架构做一个完整分析。

此书用简明、清楚的方式覆盖了游戏引擎架构的庞大领域,巧妙地平衡了广度与深度,并且提供了足够的细节。

借助《游戏引擎架构》这本书、结合引擎源码和自己的经验,深入分析游戏引擎的历史、架构、模块,最后通过实践简单引擎开发来完成对引擎知识的掌握。

游戏引擎知识面深而广,所以对这系列的文章书编写范围做个保护,即不对细节进行过多的阐述,重点剖析的是架构、流程以及模块的运作原理。

同时《游戏引擎架构》中部分知识太过陈旧的部分,会重新深挖后总结出自己的观点。

概述:

本系列文章对引擎中的重要的模块和库进行详细的分析,我挑选了十五个库和模块来分析:

  1. 时间库
  2. 自定义容器库
  3. 字符串散列库
  4. 内存管理框架
  5. RTTI与反射模块
  6. 图形计算库
  7. 资产管理模块
  8. 低阶渲染器
  9. 剔除与合批模块
  10. 动画模块
  11. 物理模块
  12. UI底层框架
  13. 性能剖析器的核心部分
  14. 脚本系统
  15. 视觉效果模块

本篇内容为列表中的第8个部分的第1节。

正文:

简单回顾下前文

前文我们聊了下显卡在计算机硬件主板中的位置与结构,知道了CPU、GPU的通信介质,并简单介绍了手机上的主板结构。本篇开头对上一篇做一些内容补充,PC和手机的不同硬件组织,以及CPU与其他芯片的通信过程。

下面我们开始这篇内容

本次内容会围绕GPU来写,从硬件架构到软件驱动再到引擎架构,目标是帮大家理解GPU硬件的运作原理,理解图形接口的架构,理解引擎低阶渲染器的架构。

目录:

  1. 主板结构中的显卡
  2. GPU功能发展史
  3. GPU与CPU的差异
  4. GPU硬件特点
  5. 图形驱动程序架构
  6. 引擎低阶渲染架构

继续上篇未结束的内容

说硬件结构时,我们常常从台式 PC 开始说起,因为智能手机本质上是袖珍型计算机,具有一些额外的无线电,并且在功耗、热量输出等方面极其受限的条件下运行。PC 主要由主板芯片组组成(通常分为连接处理器和内存“北桥”(例如 Intel 的 P45)和连接各种外围总线(例如 PCI-Express、USB 等)的“南桥”(例如 Intel 的 ICH10R) )、中央处理器(例如 CPU – Intel 的 Core 2 Duo)、随机存储器内存 (RAM)、永久存储器(硬盘或固态硬盘)、图形处理单元(例如 GPU – ATI 的 Radeon HD5890) 、电源和多个连接到 PCI 或 PCI-Express 总线的外围设备(例如,内置声音芯片组或附加 Wi-Fi 卡)。

(三星手机拓扑图:图片来源网络)

(iPhone6p A8 正面图:图片来源网络)

(iPhone6p A8 背面图:图片来源网络)

(苹果A8芯片内部结构:图片来源网络)

智能手机也具有所有这些组件,只是集成度更高而已。一些主要芯片通常可以包含 CPU、GPU、其他专用协处理器、主板总线、内存控制器、LCD 控制器、声音芯片组、CMOS 摄像头接口、板载内存 ,以及一些外围设备(例如 Cell、Wifi 和蓝牙无线电)。 “应用处理器”是负责一般处理的芯片(类似于 CPU + 主板芯片组),并且可能内置了一些其他功能。 “基带处理器”负责蜂窝无线通信。

智能手机与 PC 如此相似,那么为什么我们今天在智能手机中看不到像 Core 2 Duo 这样的 x86 CPU?答案是,Core 2 Duo 消耗的功率和产生的热量远远超出手机的可接受范围。典型的台式机 Core 2 Duo CPU 的功耗最高可达 65W,并且需要一个主动冷却系统来防止过热。即使是英特尔的 Atom 芯片也消耗 4W(峰值 TDP),而整个手机通常必须满足低于 1W 的功率。

今天我们很多智能手机都使用 ARM 芯片, ARM 的运作方式与Intel截然不同。 Intel 自己设计和构建所有处理器,而 ARM 则创建指令集,任何跟随它们的 CPU 都将能够运行与 ARM 兼容的代码。 它还为适合其指令集的处理器创建参考设计,这使公司能够围绕 ARM 的核心设计轻松生产自己的芯片组。 一些公司,如英伟达、三星和德州仪器,只是简单地许可并采用 ARM CPU 参考设计,而其他公司,如高通和 Marvell,只许可指令集并创建自己的处理器以适应它们。 第一个 ARMv7 参考设计是 Cortex A8,其架构可在今天的智能手机中找到。很久以前低端智能手机倾向于使用实现 ARMv6 指令集的 ARM11 芯片,现在已经不复存在。

这里再补充一下前文的硬件通信过程,每个带有处理程序的硬件都有自己的芯片,CPU是整个电脑的主要计算芯片,GPU则被单独拆分出来作为图像的处理芯片,除了这两个大家熟知的芯片,还有内存芯片,硬盘芯片,声卡芯片,网卡芯片等,这些芯片都通过总线进行数据交互。其中前面我们提到南桥和北桥芯片桥接了快慢不同的芯片之间的通信,让不同种类的设备通信效率更高更有序。

(PC端CPU与GPU通信结构图)

(手机端CPU与GPU通信结构图)

CPU与其他芯片之间的通信步骤,可以简单理解为,CPU通过总线发送指令数据到其他芯片,芯片收到指令并处理后,再通过总线将反馈数据给CPU,中间处理过程也会与内存芯片或其他芯片通信后再反馈给CPU。

(CPU用虚拟地址访问内存拓扑图)

CPU 在访问内存时需要通过 MMU 把虚拟地址转化为物理地址,再通过总线访问内存。MMU 开启后 CPU 看到的所有地址都是虚拟地址,CPU 把这个虚拟地址发给 MMU 后,MMU 会在页表里查出这个虚拟地址对应的物理地址,再通过总线去访问DDR内存芯片。

从这个芯片通信角度看,我们可以明白,总线传输数据的速度,限制了计算机的运行速度。因此我们在优化计算机程序时会常常去减少CPU与GPU之间通信量,原因就是在无法增加带宽上限这个大前提下,尽量减少它们之间通信数据量,从而减少访问消耗时间。

GPU功能发展史

第一篇中我们介绍过一些图形接口的发展历史,现在我们来介绍一下GPU硬件的发展历史。硬件的发展史其实是一个商业的竞争过程,中间夹杂着很多商业战略与决策。尤其是当大家都看到GPU这块高新的技术’蛋糕’,有一系列公司参与进来相互竞争。因此这里不过多的介绍商业上的活动与竞争,而是专注于介绍GPU功能的发展过程。

第一个真正的3D图形卡始于早期的显示控制器,即视频移位器和视频地址生成器(video shifters and video address generators)。它们充当主处理器和显示器之间的直通通道(pass-through)。传入的数据流被转换为串行位图视频输出,例如亮度,颜色以及垂直和水平复合同步,这将像素行保持在显示生成中,并同步每条连续行以及消隐间隔(时间间隔为 结束一条扫描线并开始下一条扫描线)。

(图片来源网络)

1970年代开始这些视频适配器出现了一系列的改进,主要兼容了不同分辨率以及不同的视频信号。

1976年,ANTIC使用直接存储器访问(DMA)处理2D显示指令。

1978年,英特尔82720图形卡芯片,它能够以256x256的分辨率(或以512x512的单色)显示八种颜色数据。其32KB的显示内存足以绘制线,弧,圆,矩形和字符位图。该芯片还提供了缩放,屏幕分区和滚动的功能。

1979年,SGI推出了用于工作站的IRIS图形卡-GR1.x图形卡板,其中提供了用于颜色选项,几何图形卡,Z缓冲区和覆盖/底层的单独的外接(子)板。

从第一块图形卡发明到现在,整个过程可以分为,视频适配器时代,2D时代、3D时代启程、3D时代崛起、3D时代巅峰,这4个部分。

为此我画了一副时序图并标出了重要节点,便于大家理解显卡的发展史,同时以文字形式告知大家图形显卡的发展历史。

(显卡发展史)

2D时代

1981年, IBM推出了个人电脑时,它提供了两种显卡,一种是“单色显卡”(简称 MDA), 一种是 “彩色绘图卡” (简称 CGA), 从名字上就可以看出,MDA是与单色显示器配合运用的, 它可以显示80行x25列的文数字, CGA则可以用在RGB的显示屏上, 它可以绘制的图形和文数字资料。

1982年,IBM又推出了MGA(Monochrome Graphic Adapter), 又称Hercules Card (大力士卡), 除了能显示图形外,还保留了原来 MDA 的功能。

这些显卡均为采纳使用数字方式的,直到MCGA(Multi-Color Graphics Array)的出现,才揭开了采纳使用模拟方式的显卡的序幕。MCGA是整合在 PS/2 Model 25和30上的影像系统。它采纳使用了Analog RGA影像信号, 解析度可高达640x480, 数位RGB和类比RGB不同的的方就像是ON-OFF式切换和微调式切换之间的差别。

1986年ATI推出了第一款产品,即OEM颜色仿真卡。它用于通过9针DE-9连接器将黑色背景的单色绿色,琥珀色或白色磷光体文本输出到TTL监视器,该卡至少配备了16KB的内存。

1987年,ATI在其OEM产品线中增加了Graphics Solution Plus系列,该产品线将IBM PC / XT ISA 8位总线用于基于Intel 8086/8088的IBM PC。该芯片通过DIP开关支持MDA,CGA和EGA图形卡模式。ATI EGA 800:16色VGA仿真,支持800x600。

VGA(Video Graphic Array)即显示绘图阵列,它IBM是在其 PS/2 的Model 50, 60和80内建的影像系统。它的数字模式可以达到720x400色, 绘图模式则可以达到640x480x16色, 以及320x200x256色,这是显卡首次可以相应情况下最大限度显示256种色彩,而这些模式更成为其后所有显卡的共同标准。

1988年,带有游戏控制器端口和复合输出选项的Small Wonder Graphics解决方案问世(用于CGA和MDA仿真),以及具有扩展EGA和16位VGA支持的EGA Wonder 480和800+,以及VGA 新增了VGA和SVGA支持的Wonder和Wonder 16。

1988年,Trident 8900/9000显卡,它第一次使显卡成为一个独立的配件出现在电脑里,而不再是集成的一块芯片。而后其推出的Trident 9685更是第一代3D显卡的代表。不过真正称得上开启3D显卡大门的却应该是1996年的GLINT 300SX,虽然当时其3D功能非常简单,却具有里程碑的意义。

1989年推出了更新的VGA Wonder / Wonder 16系列,其中包括降低成本的VGA Edge 16(Wonder 1024系列)。新功能包括一个总线鼠标端口,并支持VESA功能连接器。这是一个金手指连接器,类似于缩短的数据总线插槽连接器,它通过带状电缆链接到另一个视频控制器,以绕过拥挤的数据总线。

1991年,Wonder系列的更新继续向前发展。WonderXL卡增加了VESA 32K颜色兼容性和Sierra RAMDAC,从而将最大显示分辨率提高到640x480 @ 72Hz 或 800x600 @ 60Hz。

1991年5月,ATI的Mach系列与Mach8一同推出。它以芯片或电路板的形式出售,可以通过编程接口(AI)卸载有限的2D绘图操作,例如线条画,颜色填充和位图组合(Bit BLIT).ATI添加了Wonder的一种变体 XL在扩展PCB上集成了Creative Sound Blaster 1.5芯片。它被称为VGA Stereo-F / X,它能够模拟Sound Blaster单声道文件中的立体声,并且其质量接近FM广播质量。ATI图形卡Ultra ISA(Mach8 + VGA),将Mach8与VGA Wonder +的图形卡核心(28800-2)结合在一起以实现其3D功能。

1992年1月,Silicon Graphics Inc(SGI)发布了OpenGL 1.0,这是一个针对2D和3D图形卡的多平台供应商不可知的应用程序编程接口(API)。OpenGL是从SGI专有的API(称为IRIS GL(集成的栅格成像系统图形卡库))演变而来的。最初,OpenGL瞄准的是基于UNIX的专业市场,但是由于开发人员对扩展实施的友好支持,很快将其用于3D游戏。同时微软正在开发自己的竞争对手Direct3D API,并没有确保OpenGL在Windows下也能正常运行。

1993年11月,ATI宣布68890 PC电视解码器芯片的发布,该芯片首次在Video-It卡里面亮相。借助板载Intel i750PD VCP(视频压缩处理器),该芯片能够以320x240 @ 15 fps或160x120 @ 30 fps捕获视频,并能够实时压缩/解压缩。它还能够通过数据总线与图形卡板通信,从而无需使用加密狗或端口和带状电缆。

1995年,ATI的Mach8发布,创造了许多著名的首创。它成为第一个以Xclaim形式在PC和Mac计算机上使用的图形卡适配器,并且与S3的Trio一起提供了全动态视频播放加速功能。

3D时代开启

1995年5月,nVidia推出了他们的第一款图形卡芯片NV1,并成为首款能够进行3D渲染,视频加速和集成GUI加速的商业图形卡处理器。供应商发布显卡支持规格的主板(Diamond Edge 3D),D3D(Diamond Edge 3D)图形卡API确认依赖于渲染三角形多边形,而NV1则使用四边形纹理映射。nVidia通过驱动程序添加了有限的D3D兼容性,以将三角形包装为二次曲面,但是市面上仍然很少针对NV1量身定制的游戏。

1995年11月,ATI宣布了他们的首个3D加