以下是 Metal Shading Language Specification Version 2.2 翻译 第一章
Metal shading language 简称MSL,或直接简称Metal
根据词汇量情况,陌生单词表:
intrinsics 内建函数 | disjoint 不相交的 | specify 指定的 | tighter 使紧密 |
---|---|---|---|
mathematical operations 数学运算 | mathematical operations 数学运算 | preprocessor 预处理器 | miscellaneous 混杂的 |
tokenized 标记 | directive 指令 | enable or disable 启用或禁止 | arithmetic 算数的 |
trading off 权衡 | division 除法 | algebraically 用代数方法 | equivalent transformations 等价变换 |
reassociating 重新分配 | dramatically 极大地 | Enable 启用 | implicit 隐式地 |
explicitly 显式地 | transitively 临时地 | Specify 指定 | directory 目录 |
subdirectories 子目录 | system-appropriat 系统合适的 | system-appropriat 系统合适的 | system-appropriat 系统合适的 |
unified 统一的 | Determine 决定 | Inhibit 禁止 | Suppress 禁止 |
transformed 转化 | A four-dimensional homogenous vector 四维齐次向量 | dimensional 维度 | clip-space 裁剪空间 |
left-handed coordinate system 左手坐标系 | The rasterizer stage 光栅化阶段 | viewport 视口 | integration 集成 |
1 绪论
1.1 该文档的目的
Metal
使你能够利用GPU
的图形和计算处理能力开发app
。本文档介绍了Metal
着色器语言,你将使用它来编写着色程序,这是运行在GPU
上的图形和数据并行计算代码。着色器程序运行在GPU
中的不同的可编程单元上。MSL
是一种单一的、统一的语言,允许更紧密的集成图形和计算程序。因为MSL
是基于C++
的,所以你会发现它很熟悉,也很容易使用。
MSL
与Metal framework
一起工作,Metal framework
管理 Meta
l程序的执行和可选编译。Metal
使用clang
和LLVM
,因此你获得一个在GPU
中提供优化性能的编译器。
1.2 该文档的结构
本文档分为以下几章:
- “本章“绪论”是本文档的导论,介绍
Metal
和C++14
的异同,也详细介绍了Metal
编译选项:包括预处理器指令,数学内联函数选项,以及控制优化选项 - “数据类型”,列举了Metal数据类型,包括:向量、矩阵、缓冲区、纹理、采样器。也描述了类型对齐,类型转换
- “操作符”,列举了
Metal
操作符 - “地址空间”,描述了不相交的地址空间,用于分配具有访问限制的内存对象
- “声明函数和变量”,详细介绍了如何声明函数和变量,以及指定限制的可选属性
- “
Metal 标准库
”,定义了一系列内建在Metal
中的函数 - “数值遵从性”,描述了表示浮点数的要求,包括数学运算的准确性
iOS
和macOS
支持本文档中描述的特性(函数、枚举、类型、属性或操作符),这些从Metal 1.0
开始就提供了,除非另有说明。
对于本文档的其余部分,缩写为X.Y
代表 “Metal version X.Y”
;
例如,2.1
表示Metal 2.1
。
1.3 参考资料
C++14
Stroustrup, Bjarne. The C++ Programming Language (Fourth Edition). Harlow: Addison- Wesley, 2013.
Metal
Here is a link to the Metal documentation on apple.com: https://developer.apple.com/documentation/metal
1.4 Metal and C++14
MSL
基于C++14
规范,并且带有扩展和限制。有关语言语法的详细描述,请参考C++ 14
规范(也称为ISO/IEC JTC1/SC22/WG21 N4431
语言规范)。
这一小节描述了在Meta
中关于C++14
的修改和限制
关于更多Metal
预处理指令和编译选项,参考本文档的1.5小节
1.4.1 重载
根据C++14
规范中的13节定义,Metal
支持重加载。为了包含参数的地址空间属性,Metal
扩展了函数重加载规则。你不能重载Metal
的图像以及核心函数(关于定义图像和核心函数,请参考本文档的5.1节)
函数或者方法有相同的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。
1.4.2 模板
根据C++14
规范中的14节定义,Metal
支持模板
1.4.3 预处理指令
根据C++14
规范中的16节定义,Metal
支持预处理指令
1.4.4限制
以下C++14
的特性在Metal
中是不可获取的(请参考C++14规范中的以下章节)
-
lambda
表达式(第5.1.2节) - 递归函数调用(第5.2.2节,第9项)
-
dynamic_cast
操作符(第5.2.7节) - 类型识别(第5.2.8条)
- 新增和删除操作符(第5.3.4和5.3.5条)
-
noexcept
操作符(第5.3.7条) -
goto
声明(第6.6条) -
register, thread_local
存储属性(第7.1.1节) - 虚函数属性(7.1.2节)
- 派生类(第10、11节)
- 异常处理(第15条)
不要在Metal
代码中使用C++
标准库。相反,Metal有自己的标准库,如本文档第5节所讨论的。
Metal
限制指针的使用:
- 必须向
Metal
图形和内核函数声明参数,这些函数是带有Metal
设备、常量、threadgroup
或threadgroup_imageblock
地址空间属性的指针。(有关金属地址空间属性的更多信息,请参见本文档第4节。) - 不支持函数指针。
Metal
函数不能称为main
函数。
1.5编译器和预处理器
你可以使用在线的Metal
编译器(用合适的API
编译Metal
源码)或者离线的。你可以使用合适的Metal API
加载被离线编译为二进制的Metal
资源。
这节解释了Metal
编译器支持的编译选项,并且把他们分类为:预处理选项、数学内联函数选项、控制优化选项以及混合选项。在线和离线的Metal编译器支持这些选项。
1.5.1 预处理选项
下列选项控制Metal
预处理器,它抓实际的编译之前就运行在每一个程序源中:
-D name
用定义1将name预定义为宏。
-D name=definition
定义的内容被标记并处理,就像它们出现在#define指令中一样。此选项允许您编译Metal代码以启用或禁用特性,您可以多次使用此选项,预处理器将按照定义出现的顺序处理它们。
-I dir
将目录dir添加到头文件目录的搜索路径中。这个选项是仅对脱机编译器可用。
1.5.2 预处理器定义
Metal 编译器默认设置了一系列预处理器定义的数字,如下:
__METAL_VERSION__ //SDK的版本
__METAL_MACOS__//如果构建在macOS SDK 或者macOS 设备上,设置这个
__METAL_IOS__//如果构建在iOS SDK 或者iOS 设备上,设置这个
你可以使用这些定义有条件的应用着色器语言特性,仅在稍后的SDKs(通过比较版本号)或者特殊的平台(macOS或者iOS)。
版本号是MajorMinorPatch,例如:
for Metal 1.2, patch 0, __METAL_VERSION__ is 120;
for Metal 2.1, patch 1, __METAL_VERSION__ is 211.
为了有条件的包含使用有具有Metal2.0特性的代码,你可以在代码中使用如下预处理定义:
#if __METAL_VERSION__ >= 200
// 在大于等于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 编译器选项,以启用模块
编译器支持多个选项去控制模块的使用。这些选项仅仅对于离线编译器是生效的。
-
-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.5 编译选项控制语言版本
以下选项控制编译器接受的统一图形和计算语言的版本:
-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程序。 -
osx-metal1.1
:支持macOS 10.11的统一图形和计算语言版本1.1程序。 -
osx-metal1.2
:支持macOS 10.12的统一图形和计算语言修订1.2程序。 -
osx-metal2.0
:支持macOS 10.13的统一图形和计算语言修订2.0程序。 -
osx-metal2.1
:支持macOS 10.14的统一图形和计算语言修订2.1程序。 -
osx-metal2.2
:支持macOS 10.15的统一图形和计算语言修订2.2程序。
1.5.6请求或禁止警告的编译器选项
以下可供选择:
-Werror
将所有警告变为错误。
-w
禁止所有警告消息。
1.6. Meta 坐标系统
Metal
定义了几个标准坐标系统,用来表示渲染管线在不同阶段转换的图形数据。
一个四维齐次向量(x,y,z,w)在裁剪空间坐标中指定一个三维点。顶点着色器生成裁剪空间坐标中的位置。Metal
将x、y和z值除以w,将裁剪空间坐标转换为规范化的设备坐标。
规范化的设备坐标使用左手坐标系(见图1)并映射到视图中的位置。这些坐标和视口大小无关。左下角是(-1.0,-1.0),右上角是(1.0,1.0),z轴的正方向是大拇指指向的方向(正z值指向远离摄像机的地方),z坐标的可见部分介于0.0到1.0之间。Metal渲染管线将图元裁剪到这个盒子中(从 -1,-1,-1 到 1,1,1).
光栅化阶段将规范化坐标转变为视口坐标(如图2:)。此空间中的(x,y)坐标以像素为单位测量,原点在视图的左上角,向右向下为正。
纹理坐标系使用一个和视图坐标系类似的坐标系统。纹理坐标也可以使用归一化纹理坐标指定。对于2D纹理,正常的纹理坐标在x、y上的取值为0.0到1.0,见图三。(0.0,0.0)指定图片数据的第一个字节的像素(图片的左上角)。(1.0,1.0)指定图片数据的最后一个字节的像素(图片的右下角)。