数据类型
标量数据类型
- bool: 布尔类型,true/false
- char: 有符号的8-bit整数
- unsigned char /uchar:无符号8-bit整数
- short:有符号的16-bit整数
- unsigned short /ushort:无符号的16-bit整数
- hlaf:16-bit浮点数
- float:32-bit浮点数
- size_t:64-bit无符号整数
- void:该类型表示一个空的值集合
Metal支持后缀表示字面量类型,如0.5f,0.5F;0.5h,0.5H
纹理Texture类型
枚举值:定义了访问权利,如:
enum class access {sampler, read, write}
sampler:纹理对象可以被采样
read:不适用纹理采样,一个图形渲染函数或者并行计算函数可以读取纹理对象
write:一个图形渲染函数或者并行计算函数可以向纹理对象写入数据
texture1d<T, access a = access::sample>
texture2d<T, access a = access::sample>
texture3d<T, access a = access::sample>
T:数据类型,设定从纹理中读取或者写入时的颜色类型,可以是half,float,short,int等,代码示例
void foo (texture2d<float> imgA [[ texture(0) ]] ,
texture2d<float, access::read> imgB [[ texture(1) ]],
texture2d<float, access::write> imgC [[ texture(2) ]])
{
...
}
采样器类型 Samplers
采样器类型决定了如何对一个纹理采样操作
-
enum class coord {normalized, pixel}:从纹理中采样时,坐标是否需要归一化
-
enum class filter {nearest, linear}:纹理采用的过滤方式,放大(mag_filter)/缩小(min_filter)过滤
-
enum class mip_filter {none, nearest, linear}:设置纹理采样使用mipMap方式,如果是none,则只有一层纹理生效
-
enum class address {clamp_to_zero, clamp_to_edge, repeat, mirrored_repeat}:设置所有纹理坐标的寻址模式
-
enum class s_address {clamp_to_zero, clamp_to_edge, repeat, mirrored_repeat}:设置所有纹理 s 坐标的寻址模式
-
enum class t_address {clamp_to_zero, clamp_to_edge, repeat, mirrored_repeat}:设置所有纹理 t 坐标的寻址模式
-
enum class r_address {clamp_to_zero, clamp_to_edge, repeat, mirrored_repeat}:设置所有纹理 r 坐标的寻址模式
注意:在Metal中初始化采样器必须使用 constexpr 修饰符修饰
函数修饰符
Metal主要有3中函数修饰符
- kernel ,表示函数是一个数据并行计算着色器函数
- vextex,表示该函数是一个顶点着色器函数,它将为顶点数据流中的每个顶点数据执行一次后为每个顶点数据输出到绘制管线
- fragment,表示该函数是一个片元着色器函数,它将为片元数据流中的每个片元和其关联一次执行后将每个片元生成的颜色数据输出到绘制管线
注意:
- 使用kernel修饰函数时,函数的返回类型必须是void
- 使用修饰符修饰的函数,其内部不可调用被这三个函数修饰符修饰的函数
用于变量或者参数的地址修饰符
使用地址修饰符用来表示一个函数变量或者参数变量被分配到哪一片内存区域。所有的着色器函数的参数,如果是指针或者引用,都必须带地址空间修饰符。
-
device,在设备内存池(显存)分配出来的缓存对象,它可读可写。一个缓存对象可以声明为标量、向量、结构体指针或引用
device float4 *color; struct Foo { float a[2]; int b[2];} device Foo *info; -
threadgroup:线程组地址空间,用于并行计算着色函数分配内存变量,这些内存变量在线程组中被所有的线程共享;这些变量不能用于图形绘制着色函数(顶点着色函数、片元着色函数)
-
constant:常量地址空间,它指向的缓存对象也是设备内存池(显存)分配,但是只读的,注意:常量地址空间的指针或者引用可以作为函数的参数;向声明为常量的变量赋值会产生编译错误;声明常量时没有赋值也会产生编译错误,
constant float sample[3] = {1.0, 2.0, 3.0}; //对常量地址空间修饰的变量赋值会导致编译错误 sample[3] = {1.0,3.0,4.0};//编译错误 //定义常量地址空间变量不赋值也会报错 constant float a;//编译错误 -
thread:地址空间指向每个线程准备的地址空间,在图形绘制着色函数或并行计算着色函数中声明的变量用thread地址分配
总结:对于图形着色函数来说,其指针或者引用类型的参数必须用device或者constant地址空间;对于并行计算着色函数,其指针或者引用类型的参数必须用device或者threadgroup或者constant地址空间修饰。
函数参数与变量
- device buffer:设备缓存,一个指向设备地址空间的任意数据类型的指针或引用
- constant buffer:常量缓存区,一个指向常量地址空间的任意数据类型的指针或引用
- texture:纹理对象
- sampler:采样器对象
- threadGroup:在线程组中供各个线程共享的缓存
- thread_position_in_grid:用于表示当前节点在多线程网络中的位置
内键变量属性修饰符
-
[[vertex_id]]:顶点id 标识符
-
[[position]]:顶点信息(float4),(x, y, z, 1/w)
-
[[point_size]]:点的大小(float)
-
[[color(m)]]:颜色,m编译前得确定
-
[[stage_in]]:片元着色器函数使用的单个片元输入数据是 顶点着色器函数输出后经过光栅化生成的,顶点和片元着色函数都只能有一个参数被声明使用"stage_in"修饰符,对于一个使用了"stage_in"修饰符的自定义结构体,其成员变量可以是整形或浮点标量(向量)。