Metal Shading Language - 数据类型 (2)

原子数据类型 - Atomic Data Type

Metal原子数据类型被限制于只能在Metal着色语言供的原子函数中使用。原子函数是一组C++ 14标准的原子同步函数。Metal原子函数必须操作Metal原子数据类型数据。
Metal支持的原子类型:

atomic_int - All OS: since Metal 1.0
atomic_uint - All OS: since Metal 1.0
atomic_bool - iOS: since Metal 2.0; not supported on macOS
atomic<t style="box-sizing: border-box;"> - iOS: since Metal 2.0; not supported on macOS
atomic<t style="box-sizing: border-box;"> - represents templated types, where T can be int, uint, or bool.</t></t>

原子操作(atomic operation)指的是由多步操作组成的一个操作。如果该操作不能原子地执行,则要么执行完所有步骤,要么一步也不执行,不可能只执行所有步骤的一个子集。
任何要求多于一个函数调用的操作都不是原子操作,因为在两个函数调用之间,内核可能会临时挂起线程,执行其他的操作,当内核切换回当前线程时,之前的数据可能别修改,所以不能保证是原子操作。
在程序中使用这些数据类型的时候,编译器将保证针对原子数据类型的操作都是原子性的。也就是说,编译器保证多个线程访问这个共享资源的正确性。这样,我们在程序中就可以较少锁的使用,提高程序效率。

像素数据类型 - Pixel Data Types

所有操作系统:自Metal 2.0以来支持的像素数据类型。
Metal像素数据类型是一个模板类型,描述像素格式类型及其对应的ALU类型。ALU类型表示加载操作返回的类型和为存储操作指定的输入类型。像素数据类型通常在所有地址空间中可用。(有关地址空间的更多信息,请参见第4节。)
表2.6列出了金属着色语言中支持的像素数据类型,以及它们的大小和对齐方式。

下表为Metal像素数据类型:


image

只允许像素数据类型及其对应的ALU类型之间的赋值和相等/不等比较。

示例:


image

示例:


image

缓存 - Buffers

Metal中实现的缓存是一个指针,它指向一个在device或是constant地址空间中的内建或是用户自定义的数据块。缓 存可以被定义在程序域中,或是当做函数的参数传递。

普通的Metal Buffers包含:

  • 基本类型,如float和int
  • 向量和矩阵类型
  • 缓冲区类型数组
  • 缓冲类型的结构
  • 缓冲类型的联合

下面展示的函数参数中的展示的缓冲区参数


image

其中前两个参数为设备地址空间的缓存(device address space),第三个buffer在常量地址空间(constant address space)

纹理 - Textures

纹理数据类型是一个句柄,它指向一个1维、2维或是3维纹理数据,而纹理数据对应着一个纹理的某个level的mipmap 的全部或是一部分。
下面的模板定义了特定的纹理数据类型:


image

带有深度格式的纹理必须被声明为下面纹理数据类型中的一个:

image

macOS从Metal 2.0开始支持texture2d_ms_array和depth2d_ms_array。自Metal 1.0以来支持的所有其他类型。
iOS从Metal 1.0开始支持除texture2d_ms_array和depth2d_ms_array之外的所有类型。
T设定了从纹理中读取或是向纹理中写入时的颜色类型,纹理数据类型(除了深度纹理类型),T可以是half,float, short,ushort, int 或是uint。对于深度纹理,T必须是float。
注意:如果T是int或是short,纹理相关的数据必须使用有符号整形。如果T是uint或是ushort,纹理相关数据必须使用 无符号整形。如果T是half,和纹理相关数据必须要么是归一化的(整形),要么是half,要么是单精度浮点数。
access修饰符描述了纹理如何被访问。
被支持的access修饰符如下:

  • sample(supported Metal1.0) 纹理对象可以被采样,采样意味着使用或是不使用采样器从纹理中读取数据
  • read (supported Metal1.0) - 不使用采样器,一个图形渲染函数或是一个并行计算函数可以读取纹理对象
  • write(supported Metal1.0) - 一个图形渲染函数或是一个并行计算函数可以向纹理对象写入数据
  • read_write(supported Metal1.2) - 一个图形渲染函数或是一个并行计算函数可以向纹理对象写入数据和写入数据

对于多重采样纹理,只有read修饰符是支持的。对于深度纹理,只有sample和read修饰符是支持的。纹理指针或是引用是不支持的,将会导致编译错误。
下面的例子,纹理对象参数使用了access修饰符


image

您可以使用纹理类型作为函数中声明的任何变量的变量类型。函数中声明的纹理类型变量的access属性必须是access::readaccess:sample
示例:

image

纹理缓冲区 - Texture Buffers

所有系统: Texture buffers supported since Metal 2.1.
纹理缓冲区是一种纹理类型,它可以访问一个大的一维像素数据数组,并在该数据上执行像素格式之间的动态类型转换,具有优化的性能。纹理缓冲区比其他技术更有效地处理类型转换,允许访问更大的元素计数,并处理越界读取访问。类似的类型转换可以在没有纹理缓冲区的情况下实现,方法有:

  • 从纹理对象读取像素数据(就像其他数组一样),并将像素转换为所需的格式。
  • 在缓冲区对象的数据周围包装一个纹理对象,然后通过纹理访问共享的缓冲区数据。这种包装技术提供了像素转换,但需要额外的处理步骤,而且纹理的大小是有限的。

下面的模板定义了texture_buffer类型,您可以像使用任何纹理一样使用它:

texture_buffer

access可以是readwriteread_write之一。
T指定从纹理缓冲区读取时返回组件的类型,或写入纹理缓冲区时指定的组件类型。对于纹理缓冲区,T可以是halffloatshortushortintuint之一。
对于没有alpha通道的格式(如R、RG或RGB),越界读取返回(0,0,0,1)。对于带有alpha通道的格式(如RGBA),越界读取返回(0,0,0,0)。对于某些设备,越界读取可能会导致性能损失。
越界写入将被忽略。
纹理缓冲区可以支持比一般一维纹理(最大宽度为16384)更多的纹理数据。但是,您不能对纹理缓冲区进行采样。
纹理缓冲区还转换数据,以请求的纹理格式交付数据,而不管源文件的格式如何。创建纹理缓冲区时,可以指定缓冲区中数据的格式(例如,RGBA8Unorm),然后着色器函数可以将其读取为
转换类型(如float4)。因此,单个管道状态对象可以访问以不同像素格式存储的数据,而无需重新编译。
纹理缓冲区与纹理类型类似,可以声明为着色器函数的局部变量的类型。

采样器 - Samplers

在Metal着色语言中,采样器类型决定了如何对一个纹理进行采样操作。Metal框架代码中可以创建一个对应着色语言中的采样器的对象MTLSamplerState,这个对象作为图形渲染着色函数参数或是并行计算着色函数的参数传递。除了 在Metal框架代码中定义描述,一个采样器对象也可以在Metal着色语言程序中定义描述。如果是这种情况,那么只允许设定部分的采样器状态:寻址模式,过滤模式,归一化坐标,比较函数。

下表描述了Metal支持的采样器状态和关联数值(默认值)。在Metal着色语言程序中,这些状态可以在一个采样器 初始化时设定。

image
image

macOS:从Metal 1.2开始支持clamp_to_border地址模式和border_color
iOS:不支持clamp_to_border地址模式或border_color
使用clamp_to_border,纹理外部的采样只使用纹理坐标的边框颜色(不使用纹理边缘的任何颜色)。如果地址模式为clamp_to_border,则border_color是有效的。
clamp_to_zero等价于clamp_to_border,其边框颜色为transparent t_black(0.0, 0.0, 0.0),带有纹理中的alpha组件值。如果clamp_to_zero是一个或多个纹理坐标的地址模式,那么如果边框颜色为transparent t_black,其他纹理坐标可以使用clamp_to_border的地址模式。否则,行为是未定义的。
如果coord被设置为pixel, min_filtermag_filter值必须相同,mip_filter值必须为none,地址模式必须为clamp_to_zeroclamp_to_borderclamp_to_edge
除了枚举类型外,还可以指定采样器的最大各向异性滤波和LOD(详细级别)范围:
max_anisotropy(int value)
lod_clamp(float min, float max)

注意,在程序源代码中声明的采样器或常量缓冲区不需要这些属性限定符。必须使用constexpr声明在Metal着色语言源中初始化的采样器。

image

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容