iOS设备使用PowerVR图形架构。PowerVR 架构是一种基于磁贴的延迟渲染模型。此模型的主要优点是它不使用深度缓冲区。
但是,我可以访问iOS设备上的深度缓冲区。具体来说,我可以使用屏幕外的帧缓冲区对象将深度缓冲区转换为颜色纹理并渲染它。
如果PowerVR架构不使用深度缓冲区,我如何能够渲染深度缓冲区?
确实,基于磁贴的渲染器不需要传统的深度缓冲区即可工作。
TBR 将屏幕分割成图块,并使用快速片上存储器完全渲染此图块的内容,以存储临时颜色和深度。然后,当磁贴完成后,最终值将移动到实际的帧缓冲区。但是,深度缓冲区中的深度值传统上是临时的,因为它们仅用作隐藏表面算法。在这种情况下,深度值可以在渲染磁贴后完全丢弃。
这意味着,有效基于磁贴的渲染器实际上不需要在较慢的视频内存中使用全屏深度缓冲区,从而节省带宽和内存。
Metal API 很容易公开此功能,允许您将深度缓冲区的 storeAction 设置为"不关心"值,这意味着它不会将生成的深度值备份到主内存中。
这种情况的例外情况是,在渲染后可能需要深度缓冲区内容(即,对于延迟渲染器或作为某些使用深度值运行的算法的源)。在这种情况下,硬件必须确保深度值存储在帧缓冲中供您使用。
基于磁贴的延迟渲染 - 顾名思义 - 在逐个磁贴的基础上工作。屏幕的每个部分都加载到内部缓存中,进行处理并再次写出。硬件获取与当前磁贴和当前深度值重叠的三角形列表,并从中得出一组新的颜色和深度,然后再次将它们全部写出来。因此,一个完全愚蠢的GPU可能会对每个三角形的每个相关深度缓冲区值进行一次读取和一次写入,而PowerVR将每批几何体进行一次读取和一次写入,其余的则由光线投射风格的算法完成两者之间的其余工作。
实际上不可能在基于"纯"磁贴的延迟渲染器上实现 OpenGL,因为深度缓冲区需要可读。仅仅因为颜色缓冲区随时可读(无论是通过glReadPixels
显式读取还是根据操作系统的机制呈现帧缓冲区时隐式读取),使深度缓冲区写入通常效率也不高,这意味着硬件可能必须绘制一个场景,然后在上面绘制更多内容。
PowerVR确实使用深度缓冲区,但方式与常规(即时模式渲染)GPU不同
基于平铺的不同渲染的不同部分意味着首先处理给定场景的三角形(着色、转换裁剪等)并保存到中间缓冲区中。只有在处理了整个场景后,才会逐个渲染图块。
将所有处理过的三角形放在一个缓冲区中允许硬件执行隐藏的表面去除 - 删除最终将被其他三角形隐藏/过度绘制的三角形。这大大减少了渲染三角形的数量,从而提高了性能并降低了功耗。
隐藏表面移除通常使用称为选项卡缓冲区和深度缓冲区的东西。(两者都是小型片上存储器,因为它们一次存储一个图块)
不知道你为什么说PowerVR不使用深度缓冲区。我的猜测是,这只是一种"营销"方式,即无需从系统内存执行昂贵的写入和读取即可执行深度测试。
附言
补充一下 Tommy 的答案:基于磁贴的不同渲染的主要好处是:
- 由于片段一次处理一个图块,因此所有颜色/深度/模板缓冲区的读取和写入都是从快速片上存储器执行的。虽然颜色缓冲区仍然必须读取/写入每个图块的系统内存缓冲区,但在许多情况下,只有在以后需要时才需要将深度和模板缓冲区写入系统内存(如您的用户案例)。系统内存流量是功耗的重要来源...因此,您可以看到它如何降低功耗。
- 不同的渲染可实现隐藏的表面去除。更少的渲染三角形意味着更少的片段处理,意味着更少的纹理内存访问。