2 Metal数据类型

本章详细介绍了“Metal”数据类型,包括代表矢量和矩阵的类型。本章还讨论了原子数据类型,缓冲区,纹理,采样器,数组 ,用户定义的结构,类型对齐和类型转换。

2.1标量数据类型

Metal支持表2.1中列出的标量类型。Metal确实不支持double, long long, unsigned long long, 和 long double类型。

表2.1 Metal常量数据类型

类型 描述
bool 条件数据类型的值为真否则为假 。

为true可扩展为整数常量1,为false可扩展为整数常量0
char
int8_t
有符号二进制补码8位整数。
unsigned char
uchar
uint8_t
一个无符号的8位整数。
short
int16_t
有符号二进制补码16位整数。
unsigned short
ushort
uint16_t
一个无符号的16位整数。
int
int32_t
有符号二进制补码32位整数。
unsigned int
uint
uint32_t
一个无符号的32位整数。
long
int64_t
All OS: Since Metal 2.2.
有符号二进制补码64位整数。
unsigned long
uint64_t
All OS: Since Metal 2.2.
一个无符号的64位整数。
half 16位浮点数。half数据类型必须符合IEEE 754 binary16存储格式。
float 32位浮点数。float数据类型必须符合IEEE 754 单精度存储格式。
size_t sizeof操作后的无符号整数类型。这是一个64位无符号整数。
ptrdiff_t 有符号整数类型,是两个指针相减得到的结果。这是一个64位带符号整数。
void void类型包括一组空值;它是无法完成的不完整类型。

Metal 支持:
fF 后缀表示指定单精度浮点字面数值(例如 0.5f 或 0.5F )。
hH 后缀表示指定半精度浮点字面数值(例如 0.5 或 0.5H )。
uU 后缀表示无符号整数字面数值。
lL 后缀表示有符号长整型字面数值。

表2.2列出了大多数标量数据类型的大小和对齐。

表2.2 常量数据类型的大小和对齐

类型 大小
(in bytes)
对齐
(in bytes)
bool 1 1
char
int8_t
unsigned char
uchar
uint8_t
1 1
short
int16_t
unsigned short
ushort
uint16_t
2 2
int
int32_t
unsigned int
uint
uint32_t
4 4
long
int64_t
unsigned long
uint64_t
8 8
size_t 8 8
half 2 2
float 4 4

2.2向量数据类型

Metal支持由系统矢量数学库实现的矢量数据类型的子集。Metal支持这些向量类型名称,其中 n 是 2 ,3 ,4 ,分别表示2-、3-或4-分量向量类型:

  • booln
  • charn
  • shortn
  • intn
  • longn
  • ucharn
  • ushortn
  • uintn
  • ulongn
  • halfn
  • floatn

Metal也支持 vec <T,n> 哪里 T 是有效的标量类型,并且n 是 2 ,3,4 , 代表2 ,3或4分量向量类型

表2.3列出了向量数据类型的大小和对齐。

表2.3 向量数据类型的大小和对齐

类型 大小
(in bytes)
对齐
(in bytes)
bool2 2 2
bool3 4 4
bool4 4 4
char2
uchar2
2 2
char3
uchar3
4 4
char4
uchar4
4 4
short2
ushort2
4 4
short3
ushort3
8 8
short4
ushort4
8 8
int2
uint2
8 8
int3
uint3
16 16
int4
uint4
16 16
long2
ulong2
16 16
long3
ulong3
32 32
long4
ulong4
32 32
half2 4 4
half3 8 8
half4 8 8
float2 8 8
float3 16 16
float4 16 16

2.2.1 访问向量组件

您可以使用数组索引来访问矢量分量。数组索引 0 指向量的第一部分,索引 1个 到第二个组件,依此类推。以下示例显示了 访问阵列组件的各种方法:

pos = float4(1.0f, 2.0f, 3.0f, 4.0f);

float x = pos[0];// x = 1.0 
float z = pos[2];// z = 3.0

float4 vA = float4(1.0f, 2.0f, 3.0f, 4.0f);
 float4 vB;

for (int i=0; i<4; i++)
  vB[i] = vA[i] * 2.0f // vB = (2.0, 4.0, 6.0, 8.0);

Metal支持使用句点( . )作为选择运算符来访问矢量分量,使用可能表示坐标或颜色数据的字母:

<vector_data_type>.xyzw 
<vector_data_type>.rgba

以下代码初始化矢量测试,然后使用 .xyzw 或 .rgba选择语法以访问各个组件:

int4 test = int4(0, 1, 2, 3);
inta=test.x; // a=0 
intb=test.y; // b=1 
intc=test.z; // c=2 
intd=test.w; // d=3 
inte=test.r; // e=0 
intf=test.g; // f=1 
intg=test.b; // g=2 
inth=test.a; // h=3

组件选择语法允许选择多个组件:

float4 c;
c.xyzw = float4(1.0f, 2.0f, 3.0f, 4.0f);
c.z = 1.0f;
c.xy = float2(3.0f, 4.0f);
c.xyz = float3(3.0f, 4.0f, 5.0f);

组件选择语法还允许组件的排列或复制:

float4 pos = float4(1.0f, 2.0f, 3.0f, 4.0f);
float4 swiz = pos.wzyx; // swiz = (4.0f, 3.0f, 2.0f, 1.0f) 
float4 dup = pos.xxyy; // dup = (1.0f, 1.0f, 2.0f, 2.0f)

组件组表示法可以出现在表达式的左侧(左值)。要形成左值,可以应用旋转。得到的左值可以是标量类型,也可以是向量类型,具体取决于指定的组件数。每个组件必须是受支持的标量或向量类型。向量类型的结果左值不能包含重复的组件。

float4 pos = float4(1.0f, 2.0f, 3.0f, 4.0f); 
// pos = (5.0, 2.0, 3.0, 6.0)
pos.xw = float2(5.0f, 6.0f);

// pos = (8.0, 2.0, 3.0, 7.0) 
pos.wx = float2(7.0f, 8.0f);

// pos = (3.0, 5.0, 9.0, 7.0) 
pos.xyz = float3(3.0f, 5.0f, 9.0f);

不允许使用以下矢量组件访问方法,这会导致编译时错误:

  • 访问超出声明向量类型会报错。2-component向量数据类型只能访问 .xy 或.rg元素。3-component向量数据类型只能访问.xyz或.rgb。
float2 pos; // This is a 2-component vector.
pos.x = 1.0f; // x is legal and so is y.
pos.z = 1.0f; // z is illegal and so is w. z is the 3rd component.
float3 pos; // This is a 3-component vector.
pos.z = 1.0f; // z is legal for a 3-component vector.
pos.w = 1.0f; // This is illegal. w is the 4th component.

• 在左侧两次访问相同的组件是模棱两可的,并且是错误的:

// This is illegal because 'x' is used twice.
pos.xx = float2(3.0f, 4.0f);

• 访问不同数量的组件是一个错误:

// This is illegal due to a mismatch between float2 and float4. 
pos.xy = float4(1.0f, 2.0f, 3.0f, 4.0f);

• 一次访问中混合.rgba和.xyzw的语法错误:

float4 pos = float4(1.0f, 2.0f, 3.0f, 4.0f); 
pos.x = 1.0f; // OK
pos.g = 2.0f; // OK

// These are illegal due to mixing rgba and xyzw attributes. 
pos.xg = float2(3.0f, 4.0f);
float3 coord = pos.ryz;

带有向量的指针或指向向量的引用是错误的:

float4 pos = float4(1.0f, 2.0f, 3.0f, 4.0f); 
my_func(&pos.xy);  // This is an illegal pointer to a swizzle.

sizeof返回向量类型的大小;以组件的个数乘以每个组件的大小表示。
例如,
sizeof(float4) 返回 16;
sizeof(half4) 返回 8.

2.2.2 向量构造器

您可以使用构造函数从一组标量或向量创建向量。参数签名确定如何构造和初始化向量。例如,如果向量仅使用单个标量参数初始化,则构造的向量的所有分量都将设置为该标量值。
如果从多个标量,一个或多个向量或标量和向量的混合物构造向量,则向量的组成部分将从参数的组成部分中按顺序构造 。参数从左到右使用。在使用下一个参数的任何组件之前,每个参数按顺序消耗其所有组件。

这是float4构造函数的列表 :

float4(float x);
float4(float x, float y, float z, float w); 
float4(float2 a, float2 b);
float4(float2 a, float b, float c);
float4(float a, float b, float2 c);
float4(float a, float2 b, float c);
float4(float3 a, float b);
float4(float a, float3 b);
float4(float4 x);

这是float3 构造函数的列表:

float3(float x);
float3(float x, float y, float z);
float3(float a, float2 b);
float3(float2 a, float b);
float3(float3 x);

这是float2 构造函数的列表:

float2(float x);
float2(float x, float y);
float2(float2 x);

以下示例说明了上述构造函数的用法:

float x = 1.0f, y = 2.0f, z = 3.0f, w = 4.0f; 
float4 a = float4(0.0f);
float4 b = float4(x, y, z, w);
float2 c = float2(5.0f, 6.0f);

float2 a = float2(x, y); 
float2 b = float2(z, w); 
float4 x = float4(a.xy, b.xy);

向量构造器初始化不足会导致编译时错误。

2.2.3 向量类型打包
必须将第2.2节中描述的向量数据类型与向量的大小对齐。您还可以要求将其向量数据紧密打包;例如,一个顶点结构可能包含位置,法线,切线向量和纹理坐标,它们紧密包装并作为缓冲区传递给顶点函数。

支持的打包向量类型名称为:

• packed_charn
• packed_shortn 
• packed_intn
• packed_ucharn 
• packed_ushortn 
• packed_uintn
• packed_halfn
• packed_floatn

n指的是2、3或4,分别代表2、3或4分量向量类型。(packed_booln 向量类型名称保留。)

表2.4列出了打包矢量数据类型的大小和对齐方式。


image.png

打包的矢量数据类型通常用作数据存储格式。Metal支持打包矢量数据类型的赋值,算术,逻辑,关系和复制构造函数。 Metal还支持从打包的矢量数据类型到对齐的矢量数据类型的加载和存储,反之亦然。

例如,

device float4 *buffer;
device packed_float4 *packed_buffer;
int i;
packed_float4 f ( buffer[i] ); 
pack_buffer[i] = buffer[i]; // An operator used to convert from packed_float4 to float4. 
buffer[i] = float4( packed_buffer[i] );

您可以使用数组索引来访问打包矢量数据类型的组件。但是,您不能使用.xyzw.rgba选择语法以访问打包矢量数据类型的组件。

例如,

packed_float4 f;
f[0] = 1.0f; // OK
f.x = 1.0f; // This is illegal and results in a compilation error.

2.3矩阵数据类型

Metal支持由system math库实现的矩阵数据类型的子集。支持的矩阵类型名称为:

• halfnxm
• floatnxm

Where n and m are numbers of columns and rows. n and m must be 2, 3, or 4
n和m指的是列和行,必须是2、3、4。一个矩阵类型floatnxm是由n个floatm向量类型组成。同样的halfnxm是由n个halfm组成。

表2.5列出了矩阵数据类型的大小和对齐方式。


16096785306442.png

2.3.1 访问矩阵组件

您可以使用数组下标语法来访问矩阵的组件。将单个下标应用于矩阵会将矩阵视为列向量的数组。两个下标选择一列,然后选择一行。最上面的列是列0。然后,第二个下标对所得的矢量进行运算,如先前为矢量所定义的。

float4x4 m;

// This sets the 2nd column to all 2.0.
m[1] = float4(2.0f);
// This sets the 1st element of the 1st column to 1.0. 
m[0][0] = 1.0f;
// This sets the 4th element of the 3rd column to 3.0. 
m[2][3] = 3.0f;

您可以访问 floatnxmHalfnxm 矩阵作为n floatmn halfm输入的数组。
使用非恒定表达式访问矩阵范围之外的组件将导致不确定的行为。使用常量表达式访问位于矩阵范围之外的矩阵组件会产 生编译时错误。

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

推荐阅读更多精彩内容