Metal 语言介绍
Metal着色语言是一个用来编写3D图形渲染逻辑和并行计算核心逻辑的编程语言,编写Metal框架的APP需要使用Metal着色语言程序.
Metal 着色语言与 Metal 框架配合使用,Metal 框架管理理Metal着色语言的运行和可选编译选项. Metal 着⾊器语言使用Clang和LLVM,编译器器对于在GPU上的代码执行效率有更好的控制.
Metal 与 C++ 11.0
Metal 这⻔门语言是基于C++ 11.0标准设计的.它在C++基础是行多了一些拓拓展和限制.下面我们可以简单介绍介绍Metal着⾊语言与C++11.0 相比之下的修改和限制.
Metal Restrictions 限制
如下的C++11.0的特性在Metal 着色语言中是不支持的.
• Lambda表达式 • 递归函数调用 • 动态转换操作符 • 类型识别
• 对象创建(new
)和释放(delloc
)操作符 •操作符 noexcept
• goto
跳转
• 虚函数修饰符
• 派生类
• 异常处理理
C++的标准库不可以在Metal 着色语言中使用
Metal 着色语言是有对于指针的使用限制. Metal图形和并行计算函数用到的入参如果是指针使用地址空间修饰符 (device ,threadgroup ,constant)
不支持函数指针
Metal函数名不能命名为Main函数
Metal 数据类型

Metal 向量和矩阵数据类型
向量支持如下类型:
booln
charn
shortn
intn
ucharn
ushortn
uintn
halfn
floatn
向量中的n,指的是维度,一般是2、3、4。
矩阵支持如下类型:
halfnxm
floatnxm
nxm分别指的是矩阵的行数和列数
访问向量与矩阵
缓存buffer
在Metal中实现缓存靠的是一个指针.它指向一个在Device 或者 constant 地址空间中的内建或是开发者自定义的数据块.缓存可以被定在程序域中,或是当做函数的参数传递.
纹理Textures
纹理数据类型是一个句柄,它是一个一维/二维/三维纹理数据.而纹理数据对应这个一个纹理的某个level的mipmap的全部或者一部分
enum class access {sample,read,write};
texture1d<T,access a = access::sample>
texture1d_array<T,access a = access::sample>
texture2d<T,access a = access::sample>
texture2d_array<T,access a = access::sample>
texture3d<T,access a = access::sample>
texturecube<T,access a = access::sample>
texture2d_ms<T,access a = access::read>
带有深度的纹理必须被声明为下面纹理数据类型中的一个
//带有深度格式的纹理必须被声明为下面纹理数据类型中的一个
enum class depth_forma {depth_float};
depth2d<T,access a = depth_format::depth_float>
depth2d_array<T,access a = access::sample,depth_format d = depth_format::depth_float>
depthcube<T,access a = access::sample,depth_format d = depth_format::depth_float>
depth2d_ms<T,access a = access::read,depth_format d = depth_format::depth_float>
采样器 Samplers

函数修饰符
Metal 着色器语言支持下列的函数修饰符:
kerne: 表示该函数是一个数据并行计算着色函数,它将被分配在一个一维/二维/三维的线程组网格中执⾏.
vertex: 表示该函数是一个顶点着色函数,它将为顶点数据流中的每个顶点数据执行一次 然后为每个顶点⽣生成数据输出到绘制管线中去.
fragment: 表示该函数是一个片元着色函数,它将片元数据流中的每个片元和其关联的数据执行一次然后为每个⽚元生成数据输出到绘制管线中去.
注意:
kernel修饰的函数,返回类型只能是void
一个被函数符修饰的函数,不能在调用其他函数符修饰的函数!
变量与参数的地址空间修饰符
Metal 着色语言使用"地址空间修饰符号",来表示一个函数变量或是参数被分于那块内存区域. 下面这些修饰符描述了不相交叠地址空间:
device — 设备地址空间
threadgroup — 线程组地址空间
constant — 常量量地址空间
thread — thread地址空间
所有被函数修饰符的函数中的参数,如果是指针/引用都必须带有地址空间修饰符.
图形着色函数(vertex/fragment函数): 必须被device/constant 地址空间修饰
并行计算函数(kernel函数):必须被device/threadgroup/constant 地址空间修饰
所有的指针/引用必须被地址空间修饰.
设备地址空间: 从device内存分配的地址空间,可读/可写
threadgroup:线程组地址空间: 用于为并行计算着色器函数分别内存空间.这些变量会被一个线程组中所有线程共享.所有说在线程组地址空间修饰的变量不能用于图形函数
*threadgroup,用于并行计算函数分配内存空间
*threadgroup,不支持使用与图形函数,顶点/片元函数不支持的
costant 常量地址空间: 被常量地址空间修饰的变量也是从设备内存池来分配,但是它只读!
注意: 常量地址空间的指针能够作为函数的参数,但是声明常量地址空间变量如果没有赋值初始化值,是不可以的!
thread: 指向每个线程准备的地址空间,在这个线程的地址空间变量,其他线程是不可见. (图形函数,并行函数均可使用.)
函数参数和变量
图形绘制或是并行计算着色函数的输入/输出都需要通过参数传递(除了常 量地址空间变量和程序域中定义的采样器以外).参数可以是如下之一:
device buffer — 设备缓存
constant buffer— 常量缓存
texture object — 纹理对象
sample object — 采样器器对象
threadgroup — 线程共享的缓存
用于寻址缓存,纹理,采样器属性修饰符
为每个参数,指定一个属性修饰符. 指定明确的缓冲,纹理位置.
device 和 constant buffers — [[buffer(index)]]
texture — [[texture(index)]]
sampler — [[sampler(index)]]
threadgroup buffer — [[threadgroup(index)]]
网友评论