2 Metal數(shù)據(jù)類型

本章詳細(xì)介紹了“Metal”數(shù)據(jù)類型,包括代表矢量和矩陣的類型。本章還討論了原子數(shù)據(jù)類型,緩沖區(qū),紋理,采樣器,數(shù)組 ,用戶定義的結(jié)構(gòu),類型對(duì)齊和類型轉(zhuǎn)換。

2.1標(biāo)量數(shù)據(jù)類型

Metal支持表2.1中列出的標(biāo)量類型。Metal確實(shí)不支持double, long long, unsigned long long, 和 long double類型。

表2.1 Metal常量數(shù)據(jù)類型

類型 描述
bool 條件數(shù)據(jù)類型的值為真否則為假 。

為true可擴(kuò)展為整數(shù)常量1,為false可擴(kuò)展為整數(shù)常量0
char
int8_t
有符號(hào)二進(jìn)制補(bǔ)碼8位整數(shù)。
unsigned char
uchar
uint8_t
一個(gè)無符號(hào)的8位整數(shù)。
short
int16_t
有符號(hào)二進(jìn)制補(bǔ)碼16位整數(shù)。
unsigned short
ushort
uint16_t
一個(gè)無符號(hào)的16位整數(shù)。
int
int32_t
有符號(hào)二進(jìn)制補(bǔ)碼32位整數(shù)。
unsigned int
uint
uint32_t
一個(gè)無符號(hào)的32位整數(shù)。
long
int64_t
All OS: Since Metal 2.2.
有符號(hào)二進(jìn)制補(bǔ)碼64位整數(shù)。
unsigned long
uint64_t
All OS: Since Metal 2.2.
一個(gè)無符號(hào)的64位整數(shù)。
half 16位浮點(diǎn)數(shù)。half數(shù)據(jù)類型必須符合IEEE 754 binary16存儲(chǔ)格式。
float 32位浮點(diǎn)數(shù)。float數(shù)據(jù)類型必須符合IEEE 754 單精度存儲(chǔ)格式。
size_t sizeof操作后的無符號(hào)整數(shù)類型。這是一個(gè)64位無符號(hào)整數(shù)。
ptrdiff_t 有符號(hào)整數(shù)類型,是兩個(gè)指針相減得到的結(jié)果。這是一個(gè)64位帶符號(hào)整數(shù)。
void void類型包括一組空值;它是無法完成的不完整類型。

Metal 支持:
? fF 后綴表示指定單精度浮點(diǎn)字面數(shù)值(例如 0.5f 或 0.5F )。
? hH 后綴表示指定半精度浮點(diǎn)字面數(shù)值(例如 0.5 或 0.5H )。
? uU 后綴表示無符號(hào)整數(shù)字面數(shù)值。
? lL 后綴表示有符號(hào)長(zhǎng)整型字面數(shù)值。

表2.2列出了大多數(shù)標(biāo)量數(shù)據(jù)類型的大小和對(duì)齊。

表2.2 常量數(shù)據(jù)類型的大小和對(duì)齊

類型 大小
(in bytes)
對(duì)齊
(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向量數(shù)據(jù)類型

Metal支持由系統(tǒng)矢量數(shù)學(xué)庫實(shí)現(xiàn)的矢量數(shù)據(jù)類型的子集。Metal支持這些向量類型名稱,其中 n 是 2 ,3 ,4 ,分別表示2-、3-或4-分量向量類型:

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

Metal也支持 vec <T,n> 哪里 T 是有效的標(biāo)量類型,并且n 是 2 ,3,4 , 代表2 ,3或4分量向量類型

表2.3列出了向量數(shù)據(jù)類型的大小和對(duì)齊。

表2.3 向量數(shù)據(jù)類型的大小和對(duì)齊

類型 大小
(in bytes)
對(duì)齊
(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 訪問向量組件

您可以使用數(shù)組索引來訪問矢量分量。數(shù)組索引 0 指向量的第一部分,索引 1個(gè) 到第二個(gè)組件,依此類推。以下示例顯示了 訪問陣列組件的各種方法:

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支持使用句點(diǎn)( . )作為選擇運(yùn)算符來訪問矢量分量,使用可能表示坐標(biāo)或顏色數(shù)據(jù)的字母:

<vector_data_type>.xyzw 
<vector_data_type>.rgba

以下代碼初始化矢量測(cè)試,然后使用 .xyzw 或 .rgba選擇語法以訪問各個(gè)組件:

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

組件選擇語法允許選擇多個(gè)組件:

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);

組件選擇語法還允許組件的排列或復(fù)制:

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)

組件組表示法可以出現(xiàn)在表達(dá)式的左側(cè)(左值)。要形成左值,可以應(yīng)用旋轉(zhuǎn)。得到的左值可以是標(biāo)量類型,也可以是向量類型,具體取決于指定的組件數(shù)。每個(gè)組件必須是受支持的標(biāo)量或向量類型。向量類型的結(jié)果左值不能包含重復(fù)的組件。

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);

不允許使用以下矢量組件訪問方法,這會(huì)導(dǎo)致編譯時(shí)錯(cuò)誤:

  • 訪問超出聲明向量類型會(huì)報(bào)錯(cuò)。2-component向量數(shù)據(jù)類型只能訪問 .xy 或.rg元素。3-component向量數(shù)據(jù)類型只能訪問.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.

? 在左側(cè)兩次訪問相同的組件是模棱兩可的,并且是錯(cuò)誤的:

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

? 訪問不同數(shù)量的組件是一個(gè)錯(cuò)誤:

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

? 一次訪問中混合.rgba和.xyzw的語法錯(cuò)誤:

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;

帶有向量的指針或指向向量的引用是錯(cuò)誤的:

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

sizeof返回向量類型的大?。灰越M件的個(gè)數(shù)乘以每個(gè)組件的大小表示。
例如,
sizeof(float4) 返回 16;
sizeof(half4) 返回 8.

2.2.2 向量構(gòu)造器

您可以使用構(gòu)造函數(shù)從一組標(biāo)量或向量創(chuàng)建向量。參數(shù)簽名確定如何構(gòu)造和初始化向量。例如,如果向量?jī)H使用單個(gè)標(biāo)量參數(shù)初始化,則構(gòu)造的向量的所有分量都將設(shè)置為該標(biāo)量值。
如果從多個(gè)標(biāo)量,一個(gè)或多個(gè)向量或標(biāo)量和向量的混合物構(gòu)造向量,則向量的組成部分將從參數(shù)的組成部分中按順序構(gòu)造 。參數(shù)從左到右使用。在使用下一個(gè)參數(shù)的任何組件之前,每個(gè)參數(shù)按順序消耗其所有組件。

這是float4構(gòu)造函數(shù)的列表 :

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 構(gòu)造函數(shù)的列表:

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

這是float2 構(gòu)造函數(shù)的列表:

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

以下示例說明了上述構(gòu)造函數(shù)的用法:

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);

向量構(gòu)造器初始化不足會(huì)導(dǎo)致編譯時(shí)錯(cuò)誤。

2.2.3 向量類型打包
必須將第2.2節(jié)中描述的向量數(shù)據(jù)類型與向量的大小對(duì)齊。您還可以要求將其向量數(shù)據(jù)緊密打包;例如,一個(gè)頂點(diǎn)結(jié)構(gòu)可能包含位置,法線,切線向量和紋理坐標(biāo),它們緊密包裝并作為緩沖區(qū)傳遞給頂點(diǎn)函數(shù)。

支持的打包向量類型名稱為:

? 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列出了打包矢量數(shù)據(jù)類型的大小和對(duì)齊方式。


image.png

打包的矢量數(shù)據(jù)類型通常用作數(shù)據(jù)存儲(chǔ)格式。Metal支持打包矢量數(shù)據(jù)類型的賦值,算術(shù),邏輯,關(guān)系和復(fù)制構(gòu)造函數(shù)。 Metal還支持從打包的矢量數(shù)據(jù)類型到對(duì)齊的矢量數(shù)據(jù)類型的加載和存儲(chǔ),反之亦然。

例如,

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] );

您可以使用數(shù)組索引來訪問打包矢量數(shù)據(jù)類型的組件。但是,您不能使用.xyzw.rgba選擇語法以訪問打包矢量數(shù)據(jù)類型的組件。

例如,

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

2.3矩陣數(shù)據(jù)類型

Metal支持由system math庫實(shí)現(xiàn)的矩陣數(shù)據(jù)類型的子集。支持的矩陣類型名稱為:

? 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。一個(gè)矩陣類型floatnxm是由n個(gè)floatm向量類型組成。同樣的halfnxm是由n個(gè)halfm組成。

表2.5列出了矩陣數(shù)據(jù)類型的大小和對(duì)齊方式。


16096785306442.png

2.3.1 訪問矩陣組件

您可以使用數(shù)組下標(biāo)語法來訪問矩陣的組件。將單個(gè)下標(biāo)應(yīng)用于矩陣會(huì)將矩陣視為列向量的數(shù)組。兩個(gè)下標(biāo)選擇一列,然后選擇一行。最上面的列是列0。然后,第二個(gè)下標(biāo)對(duì)所得的矢量進(jìn)行運(yùn)算,如先前為矢量所定義的。

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輸入的數(shù)組。
使用非恒定表達(dá)式訪問矩陣范圍之外的組件將導(dǎo)致不確定的行為。使用常量表達(dá)式訪問位于矩陣范圍之外的矩陣組件會(huì)產(chǎn) 生編譯時(shí)錯(cuò)誤。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容