1.1本文目的
Metal使您能够开发利用图形和计算GPU处理能力的应用程序。本文档介绍了Metal Shader Language(MSL),您将使用它来编写 着 色器程序, 这是在GPU上运行的图形和数据并行计算代码。着色器程序在GPU的不同可编程单元上运行。MSL是一种单一 的统一语言,可以在图形和计算程序之间进行更紧密的集成。由于MSL是基于C ++的,因此您会发现它熟悉且易于使用。
MSL与Metal框架一起使用,该框架管理Metal程序的执行和(可选)编译。Metal使用clang和LLVM,因此您可以获 得在GPU上提供优化性能的编译器。
1.2 文档索引
本文档分为以下几章:
• 本章“简介”是对该文档的介绍,涵盖了Metal与C ++ 14之间的异同。它还详细介绍了Metal编译器的选项,包括预处理器 指令,数学内在函数的选项以及控制优化的选项。
• “Data Types”列出了Metal数据类型,包括代表vectors,matrices,buffers,textures和samplers的类型。它还讨论了类型对齐和类 型转换。
•“Operators”列出了Metal操作员。
• “Address Spaces”描述了用于分配具有访问限制的内存对象的不相交的地址空间。
• “Function and Variable Declarations”详细介绍了如何声明函数和变量以及具有指定限制的可选属性。
• “Metal Standard Library”定义了内置的Metal功能的集合。
• “Numerical Compliance”描述了表示浮点数的要求,包括数学运算的准确性。
除非另有说明,否则从Metal 1.0开始,iOS和macOS对本文档中描述的功能(函数,枚举,类型,属性或运算符)的支持 就可用。
在本文档的其余部分中,缩写XY代表“Metal版X.Y”。例如, 2.1表示Metal2.1。
1.3参考
C++14
Stroustrup, Bjarne. C++编程语言(第四版)。Harlow: Addison-Wesley, 2013.
Metal
这是apple.com上的Metal文档的链接: https://developer.apple.com/documentation/metal
1.4 Metal和C++14
Metal编程语言是基于C ++ 14的规范,具有扩展和限制。有关语言语法的详细说明,请参阅C ++ 14规范(也称为ISO / IEC JTC1 / SC22 / WG21 N4431语言规范)。
本节及其子节描述了Metal中对C ++ 14语言的修改和限制。 有关Metal预处理指令和编译器选项的更多信息,请参见本文档的第1.5节。
1.4.1 重载
根据C ++ 14规范第13节的定义,Metal支持重载。Metal扩展了函数重载规则,以包括参数的地址空间属性。您不能重载Metalgraphics
和kernel
功能。(有关图形和内核功能的定义,请参阅本文档的第5.1节。)
1.4.2 模板
Metal支持模板,如C ++ 14规范的第14节所定义。
1.4.3 预处理指令
Metal支持C ++ 14规范第16节所定义的预处理指令。
1.4.4 限制条件
下列C ++ 14功能在Metal中不可用(此列表中的部分编号参考C ++ 14规范):
• lambda表达式(第5.1.2节)
• 递归函数调用(第5.2.2节,第9项)
• dynamic_cast运算符(第5.2.7节)
• 类型标识(第5.2.8节)
• new和delete运算符(第5.3.4节和5.3.5节)
• noexcept运算符(第5.3.7节)
• goto声明(第6.6节)
• 寄存器,thread_local存储属性(第7.1.1节)
• 虚拟函数属性(第7.1.2节)
• 派生类(第10节,第11节)
• 异常处理(第15节)
不要在Metal代码中使用C ++标准库。相反,Metal有其自己的标准库,如本文档第5节中所述。
Metal规定了指针的使用限制:
• 对于Metal graphics和kernel函数用到的入参必须是 device
、constant
、threadgroup
、threadgroup_imageblock
这些Metal的地址空间修饰符。(有关Metal地址空间属性的更多信息,请参见本文档的第4节。)
Metal2.3是支持函数指针的。在Metal 2.3之前,不支持函数指针。
• Metal的函数名不能命名为main
1.5编译器和预处理器
你既可以加载线上或者线下的Metal Shader源文件,也可以加载编译成二进制的Metal Shader资源;
本节说明了Metal编译器支持的编译器选项,并将它们分类为
1)、预处理器选项
2)、math intrinsics选项
3)、控制优化选项
4)、其他编译选项和链接。
1.5.1 预处理器编译器选项
以下选项控制在实际编译之前在每个程序源上运行的Metal预处理程序:
-D name
预处理的name
作为一个宏定义,定义为1。
-D name=definition
definition
的内容 被标记和处理,就像它们出现在'#define' 中一样。此选项使您可以编译Metal代码以启用或禁用功能。您可以多次使用此选项,并且预处理程序按照 definitions
的显示顺序对其进行处理。
-I dir
添加目录dir
到头文件目录的搜索路径。此选项仅适用于脱机编译器。
1.5.2 预处理程序定义
METAL_VERSION // 设置Metal语言的版本
METAL_MACOS // 设置是否使用macOS的Metal语言版本编译
METAL_IOS // 设置是否使用iOS的Metal语言版本编译
您可以使用定义有条件地应用仅在更高语言版本上可用的着色语言功能(请参阅控制语言版本的编译器选项)。
版本号是MajorMinorPatch。
例如,
对于Metal 1.2的补丁0,__METAL_VERSION__
为120;
对于Metal 2.1的补丁1,__METAL_VERSION__
为211;
要有条件地包括使用Metal 2.0中引入的功能的代码,可以在代码中使用预处理器定义,如下所示:
#if __METAL_VERSION__ >= 200
// Code that requires features introduced in Metal 2.0.
#endif
1.5.3 数学内部编译器选项
这些选项控制有关浮点算法的编译器行为,在速度和精确性之间进行权衡。
-ffast-math (default)
-fno-fast-math
有关数学函数的更多信息,请参见第6.5节。有关普通和快速数学函数的相对误差的更多信息,请参见第7.4节。
这些选项启用(默认)或禁用可能违反IEEE 754标准的浮点算法优化。它们还为单精度浮点标量和矢量类型启用或禁用数 学函数的高精度变量。
浮点算法的优化包括:
• No NaNs:允许优化假设参数和结果不是NaN(“非数字”)。
• No Infs:允许优化假设参数和结果不是正无穷大或负无穷大。
• No Signed Zeroes:允许优化将零参数或结果的符号视为无关紧要。
• Allow Reciprocal:允许优化使用参数的倒数而不是执行除法。
• Fast:允许进行等效的代数转换,例如重新关联可能会大大改变浮点结果的浮点运算。
1.5.4 不变编译器选项
使用iOS14.0和macOS10.16(支持Metal 2.3的编译器)中的编译器时,需要传递以下选项以支持顶点不变性。
-fpreserve-invariance
保留标记为[[ invariant]] 在顶点着色器中。如果未设置,[[invariant]] 被忽略。
在早期版本的Metal中,[[ invariant]] 是一项尽力而为的分析,以标记哪些操作需要不变并且在某些情况下可能会失败。替换为保 守的不变模型,在该模型中,编译器标记不会进行不变计算的操作。这将确保任何不变的计算都保持不变。此选项可能会降 低性能,因为它可能会阻止某些优化来保留不变性。
1.5.5 编译器选项以启用模块
编译器支持多个选项来控制模块的使用。这些选项仅适用于脱机编译器:
-fmodules
启用模块功能。
-fimplicit-module-maps
启用对名为module.modulemap
或类似名称的模块映射文件的隐式搜索。默认情况下, -fmodules
启用
此选项。(编译器选项-fno-implicit-module-maps
禁用此选项。)
-fno-implicit-module-maps
禁用对名为module.modulemap
模块映射文件的隐式搜索。仅在使用明确指定 -fmodule-map-file
模块映射文件时才加载它们或由另一个模块映射文件可传递地使用。
-fmodules-cache-path=
指定模块缓存的路径。如果未提供,则编译器将选择适合系统的默认值。
-fmodule-map-file=
如果已加载其目录或其子目录之一中的头文件,则加载指定的模块映射文件。
1.5.6编译器选项控制语言版本
以下选项控制编译器接受的统一图形和计算语言的版本:
std=
确定要使用的语言版本。必须提供此选项的值,该值必须是以下之一:
• ios-metal1.0 : 支持适用于iOS 8的统一图形和计算语言修订版1.0程序。
• ios-metal1.1 : 支持适用于iOS 9的统一图形和计算语言修订版1.1程序。
• ios-metal1.2 : 支持适用于iOS 10的统一图形和计算语言修订版1.2程序。
• ios-metal2.0 : 支持iOS 11的统一图形和计算语言修订版2.0程序。
• ios-metal2.1 : 支持适用于iOS 12的统一图形和计算语言修订版2.1程序。
• ios-metal2.2 : 支持适用于iOS 13的统一图形和计算语言修订版2.2程序。
• ios-metal2.3 : 支持适用于iOS 14的统一图形和计算语言修订版2.3程序。
• macos-metal1,1 or osx-metal1.1 : 支持适用于macOS 10.11的统一图形和计算语言修订版1.1程序。
• macos-metal1.2 or osx-metal1.2: 支持适用于macOS 10.12的统一图形和计算语言修订版1.2程序。
• macos-metal2.0 or osx-metal2. : 支持适用于macOS 10.13的统一图形和计算语言修订版2.0程序。
• macos-metal2.1: 支持适用于macOS 10.14的统一图形和计算语言修订版2.1程序。
• macos-metal2.2 : 支持适用于macOS 10.15的统一图形和计算语言修订版2.2程序。
• macos-metal2.3 : 支持适用于macOS 10.16的统一图形和计算语言修订版2.2程序。注意,macOS10.13以及之后的版本中提供了macos- *。
1.5.7 要求或禁止警告的编译器选项
提供以下选项:
-Werror
:使所有警告变为错误。
-w
:禁止所有警告消
1.5.8 Target条件
Metal定义了几个宏,可以使用这些宏来确定着色器在哪个平台上运行。
下面是定义在
中的几个宏:
TARGET_OS_MAC :MAC OS X系列,即Apple任一平台设备
TARGET_OS_OSX :OS X设备上运行
TARGET_OS_IPHONE :iPhone设备以及模拟器
TARGET_OS_IOS :iOS系统
TARGET_OS_TV :Apple TV OS
TARGET_OS_WATCH :Apple Watch
TARGET_OS_MACCATALYST : MacOS
TARGET_OS_SIMULATOR模拟器
注意,这个头文件不是`.`
1.5.9 动态库链接器选项
Metal编译器驱动程序可以将选项传递给链接器。这是其中一些选项的简要说明。请参阅Metal链接器以获取更多信息。
-dynamiclib
:指定输出为动态库。
-install_name
:用于-dynamiclib
说明预期动态库的位置由加载程序安装并找到。与@executable_path
和@loader_path
一起使用。