Tag: 计算机图形学

Metal API简介

Metal是一种低开销,高性能的API,可以在GPU上执行图形和计算工作。 GPU的常见工作是绘制几何图形,而Metal的基本设计原理旨在帮助应用程序极其快速地绘制几何图形。 在GPU上执行绘制调用即可完成绘制几何图形。 绘图调用是图形命令和状态的集合,这些命令和状态在屏幕上产生视觉效果; 每个绘制调用都需要有自己的图形状态向量,这意味着它需要明确指定用于执行绘制的着色器,图形状态,数据缓冲区,纹理和渲染目标。 在所有上一代的硬件图形API(如OpenGL ES)中,更改状态向量都是非常昂贵的操作,因为所有API命令都必须在相应的硬件命令中转换。 这样做的成本通常全部在CPU上,负责执行这种转换的函数和所有API命令必须在GPU开始执行任何工作之前进行转换。 下图显示了典型的绘制调用序列以及从应用程序(CPU端)到GPU的执行流程。 设计原理与架构 金属围绕6个关键设计原则构建: 最薄的API,意味着减少在应用程序和GPU之间执行的代码量。 旨在为所有现代GPU硬件功能提供全面支持 减少昂贵的操作频率。 提供可预测的性能。 提供对命令提交的明确控制。 针对CPU行为进行了优化。 几乎所有现代手机游戏都倾向于以特定帧速率为目标来管理CPU和GPU工作负载,大多数情况下,此目标为60帧每秒(fps),而其他时间为30 fps。 下图显示了一个游戏的常见情况,该游戏试图优化CPU和GPU的工作量以保持稳定的30 fps:CPU为某一帧准备渲染命令,而GPU在下一帧消耗这些命令。 当一切都按预期工作时,此设置可以提供完美且平衡的并行性,但这是一种理想的情况,因为在现实生活中,大多数情况下,CPU生成渲染命令的时间要比GPU消耗它们的时间长得多,因此GPU空闲了一部分帧。 再详细一点看CPU必须执行的工作,我们可以将其分为两部分:CPU执行应用程序逻辑所花费的时间和CPU准备呈现API命令所花费的时间; 通常,后者是占用大部分可用帧时间的时间。 如下图所示,CPU无法在目标帧时间内转换所有API命令,这可能会导致GPU跳过帧。 Metal尝试着重于准备渲染API命令的工作,并提供了支持以最小程度地减少它。 这实际上释放了可用于其他活动的CPU时间,并且大部分时间都将这些额外时间用于生成更多绘图调用。 为了更好地了解Metal API如何达到这种效果,重要的是要了解GPU编程为什么在CPU上如此昂贵。 主要有以下三个原因: 状态验证:应用程序每次调用呈现API时,呈现API实现都必须验证调用是否以正确的方式执行:应用程序使用正确数量和类型的参数,并且硬件上下文将在进入状态后变为有效状态。通话完成。 但是还有更多! 在调用API时,实现还必须将API状态编码为相应的硬件状态,并再次检查其他硬件状态以弄清楚如何将它们组合在一起以将全局上下文移动到新的状态。 着色器编译必须编译所有着色器的源代码才能生成GPU机器代码,这通常在运行时发生。 通常,状态和着色器代码的描述方式与硬件真正期望的不完全相同,因此,当应用程序更改某些状态时,可能会发生,必须重新编译生成的机器代码。 GPU工作提交状态和着色器代码可以请求不在GPU端驻留的资源,因此必须将它们在内存中移动到GPU可以访问它们的位置。 因为所有这些,所有游戏所做的就是将共享相似状态和资源的操作组合在一起,目的是减少工作量并提高效率,因此我们通常将此过程称为批处理命令……但批处理命令需要在服务器上运行更多逻辑CPU创建这些批次。 因此,最终结果是,在为CPU安排适当的工作量以产生可让GPU在整个帧中保持繁忙并在目标帧时间内完成所有这些工作的工作量之间,始终存在一个平衡的工作。 Metal与众不同的原因在于设计原则,因此不经常进行昂贵的操作。 在Metal之前的所有渲染API中,特别是OpenGL ES,状态验证,着色器编译和GPU工作提交,都是在绘制帧期间发生的,这使得帧时间的管理不受事物的直接控制,而不受应用程序的直接控制。 Metal支持在渲染对象创建时进行脱机着色器编译和状态验证,这使应用程序不必担心将工作提交给GPU,仅此而已。 为了更好地理解所有这些,让我们详细研究Metal API的所有对象部分。 让我们来看看所有这些: 设备 ( MTLDevice ):这是物理GPU的抽象,将消耗渲染和计算命令; 这也是在Metal中执行任何操作的首选对象,因为应用程序与之交互的所有对象都来自该对象。 命令队列 ( MTLCommandQueue ):此对象存储所有命令,并允许应用程序控制所有命令的执行顺序。 命令缓冲区 […]