本系列文章是对 metalkit.org 上面MetalKit内容的全面翻译和学习.
MetalKit系统文章目录
上周在WWDC 2019上宣布了Metal 3,Apple公布了相关数字:
- Metal现在可以比OpenGL多100倍的绘制调用。
- Metal目前在大约14亿台设备上运行。
- Metal可以驱动高达56 TFLOPS的单精度运算。
注意:要获得 56 TFLOPS,您需要具有双 Vega II Duo(4 GPU)的新 Mac Pro。 Radeon Pro Vega II Duo 是目前世界上功能最强大的 GPU,能够提供 28.3 TFLOP 的 FP32 精度。此 GPU 仅适用于 Mac Pro,它使用 Infinity Fabric Link 将双 GPU 之间的内部传输提升至 48 GB /秒。
Metal Shading Language 现在版本是 2.2,而 API 版本是 3。现在可以通过查看 MTLSoftwareVersion 枚举来检查 Xcode 11 中的 Metal 版本,这是一个设备属性:
好吧,让我们看看今年 Metal 框架的一些重要补充。
1. iOS模拟器现在支持 Metal
大多数框架现在都是 Metal 加速的:UIKit,SpriteKit,SceneKit,Core Animation,Core Image,MapKit等。该模拟器适用于A8 GPU 及更高版本。您甚至可以在两个不同的 target 上同时运行两个模拟器:
iOS Metal 指令被转换为 macOS Metal 指令,因此您可以从 Mac 底层 GPU 硬件中受益。从模拟器菜单中,您可以选择要使用的 macOS GPU:
模拟器中的 Metal 性能仍然低于真实设备的性能,因此应该最终在设备上对生产代码进行分析和优化。使用模拟器时要记住的另一件事是模拟器上的纹理存储需要始终处于私有模式。但是,很容易涵盖这两种情况。当纹理在模拟器上时,创建一个临时共享缓冲区,将纹理初始化到该缓冲区,然后将其 blit 到私有纹理:
#if targetEnvironment(simulator)
textureDescriptor.storageMode = .private
#else
textureDescriptor.storageMode = .shared
#endif
let texture = device.makeTexture(descriptor: textureDescriptor)!
if texture.storageMode == .private {
let tmpBuffer = device.makeBuffer(length: textureSize,
options: .storageModeShared)!
initWithTextureData(buffer: tmpBuffer)
blitData(fromBuffer: tmpBuffer, toTexture: texture)
} else {
initWithTextureData(texture: texture)
}
复制代码
2. 简化 GPU 家族系列
新的Metal Feature Set Tables文档也更新到第 3 版,它在新的 GPU 家族系列中替代了旧功能集,如下所示:
- Apple 家族系列是指所有 Apple 设计的GPU(A系列GPU)。
- Mac家族系列是指所有 macOS GPU(Intel,AMD,Nvidia):
- Common 家族系列是指所有设备和平台:
- 适用于 Mac 系列的 iPad 应用程序是指在 macOS 上运行的 iPadOS 应用:
要确定 Mac 2 系列功能是否可用:
if #available(macOS 10.15, iOS 13, tvOS 13, *) {
if self.device.supportsVersion(.version3_0) {
if self.device.supportsFamily(.familyMac2) {
// enable Metal 3 features for the Mac family 2
}
}
else {
// enable Metal 2 features (fallback)
}
} else {
if self.device.supportsFeatureSet(.featureSet_macOS_GPUFamily2_v1) {
// enable Metal 2 features (fallback)
}
}
复制代码
以下是一些最常见的技术及其家族系列的支持性:
特性 | 家族系列 |
---|---|
Deferred shading(延迟着色) | 全部系列 |
Programmable blending(可编程混合) | Apple 1 及更新 |
Tile deferred / forward(分块延迟/前向) | Common 2 及更新 |
Tile shading (分块着色) | Apple 3 及更新 |
Visibility buffer (可见性缓冲) | Mac 1 及更新 |
Argument buffers(参数缓冲) | 全部系列 |
Indirect Command buffers(间接命令缓冲) | Common 2 更新 |
3. 光线跟踪和计算
去年推出了用于光线追踪的 Metal 性能着色器(MPS)API 时,光线三角形交叉点的计算被转移到 GPU 上,使得 Metal 中的光线追踪真正开始吸引人。今年,另外两个昂贵且重要的阶段也转移到 GPU 上:加速结构(acceleration structure)和图像降噪(image denoising)。
加速结构(acceleration structure) 通过称为refitting的过程进行更新,该过程不会从头开始重建加速结构,而是将边界框移动到几何体移动的位置,从而节省宝贵的处理时间。现在全部在GPU上完成:
图像降噪(image denoising) 则巧妙地利用了基于图像处理的降噪滤波器。其背后的思想是,每帧存储法线和深度信息,然后将它们与下一帧进行比较,以查看某些像素是否无效。如果物体移动到不同的位置或另一个物体将其遮挡,则可能会发生这种无效的情况。新的 MPSSVGF 类实现了Spatiotemporal Variance-Guided Filtering降噪算法。现在,GPU 上的降噪速度比CPU上的速度高出 1000 倍。
Metal 去年推出了间接计算缓冲(ICB),这是一种通过重用命令来降低 CPU 开销和简化命令执行的方法。但它只适用于渲染。今年MTLIndirectComputeCommand
加入到MTLIndirectRenderCommand
中,一起成为 ICB 上的编码类型。
4. 调试和分析工具
GPU帧捕获工具现在有一个 Metal Memory Viewer,可以让你检查纹理,缓冲区和堆。该工具提供有关存储模式,类型和大小的详细信息:
至于分析,Instruments 工具现在具有 Metal Resource Allocations 工具,它允许您检查存储位置,并在每个设备,显示器或着色器编译器上提供有关资源利用率和状态的信息:
5. 其他 Metal 3 的新特性
iOS 和 tvOS 新特性:
- 在间接命令缓冲(Indirect Command Buffers)上设置管道状态
- 从缓冲中获取间接命令缓冲(Indirect Command Buffers)范围
- 16位深度纹理
macOS 新特性:
- 无渲染通道附件条件下渲染(Rendering without render pass attachments)
- 命令缓冲时序(Command buffer timing)
- 在 sRGB 和非 sRGB 纹理视图之间进行转换
其他新特性:
- 堆支持开发人员驱动的放置(Heaps support developer driven placement)
- 堆可以跟踪资源
- 放松 macOS blit 对齐规则以匹配 Apple GPU
- 改善资源使用
- 纹理访问的预定义行为(Well-defined behavior for texture access)
- 纹理自定义swizzle
- 跨进程的纹理共享
- iOS纹理绑定数量增加
- iOS变化限制增加
- ASTC 3D支持最新的Apple GPU
- 3D BC 纹理支持所有 Mac GPU
- 可见性缓冲(又称遮挡查询(occlusion query))大小增加到 256K
- MSL新属性
[[primitive_id]]
和[[barycentric_coord]]
有关新功能的完整列表,请参阅Metal API文档网站。新的源代码也可以在Apple网站上找到。
下次见。