Metalのデータ型

提供: MonoBook
ナビゲーションに移動 検索に移動

スカラー型[編集 | ソースを編集]

概要
bool true or false
char 符号付き8ビット整数
int8_t
unsigned char 符号なし8ビット整数
uchar
uint8_t
short 符号付き16ビット整数
int16_t
unsigned short 符号なし16ビット整数
ushort
uint16_t
int 符号付き32ビット整数
int32_t
unsigned int 符号なし32ビット整数
uint
uint32_t
long 符号付き64ビット整数

Metal 2.2以降

int64_t
unsigned long 符号なし64ビット制す

Metal 2.2以降

uint64_t
half 16ビット浮動小数点

IEEE 754のbinary16形式

float 32ビット浮動小数点

IEEE 754に準拠

size_t sizeof 演算子の結果を表す符号なし整数型。

実態は符号なし64ビット整数。

ptrdiff_t 2つのポインタを引き算した結果の符号付き整数型。

実態は符号付き64ビット整数。

void void

サフィックス [編集 | ソースを編集]

  • f または F = float, 0.5f
  • h または H = half, 0.5h
  • u または U = uint, 2u
  • l または L = long, 2L

ベクトル型[編集 | ソースを編集]

スカラー型名の末尾に数字(ここではnとする)を付けるとベクトル型になる。 n には 2, 3, 4のいづれかの数字が入る。 「float2」や「float3」といった感じだ。 HLSLなどと同じだな。

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

ベクトル型のサイズは必ず2の乗数[編集 | ソースを編集]

Metalのベクトル型は「型のサイズは必ず2の乗数」となっている。

たとえば、

  • int = 4バイト
  • int2 = 8バイト
  • int3 = 16バイト (12バイトではない)
  • int4 = 16バイト

HLSLGLSL定数バッファーなどの構造体を作る際は、その構造体のサイズをGPUが扱いやすいよう「8バイト単位」や「16バイト単位」にする必要があり、シェーダープログラミングの際にはその構造体のサイズを手計算で算出して、バイト数が足りない場合はダミーの変数を追加してサイズ調整が必要である。

一方、Metalでは「必ず2の乗数」になるのでそのような手計算が必要ない。 HLSLGLSLの感覚でサイズ調整すると無駄が発生するので注意すること。

ベクトル成分へのアクセス[編集 | ソースを編集]

インデクサ

ベクトル型の成分へのアクセスには配列のインデックスを使用することができる。

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

float x = pos[0]; // x = 1.0f
float y = pos[2]; // y = 3.0f
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ではピリオド(.)を選択演算子、いわゆるスウィズルswizzle)を利用してベクトルの各成分にアクセスすることができる。

<vector_data_type>.xyzw
<vector_data_type>.rgba

xyzwおよびrgbaの各成分(1文字)が配列インデックスに相当している感じである。

  • x, r = 0
  • y, g = 1
  • z, b = 2
  • w, a = 3
int4 test = int4(0, 1, 2, 3);
int a = test.x; // a = 0
int b = test.y; // b = 1
int c = test.z; // c = 2
int d = test.w; // d = 3
int e = test.r; // e = 0
int f = test.g; // f = 1
int g = test.b; // g = 2
int h = test.a; // h = 3

xyzwおよびrgbaの各成分は組み合わせて利用できる。 xとyの値が欲しい場合は「.xy」などと書ける。

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)
主なエラー

ベクトル型に宣言された成分以外の成分にアクセスするとエラーになる。

float2 pos;
pos.z = 1.0f; // エラー:2成分ベクトル型は.xy または .rg の要素にのみアクセスできる。
float3 pos;
pos.w = 1.0f; // エラー:3成分ベクトル型は.xyz または .rgb 要素にのみアクセスできる。

同じ成分に代入はできない。

pos.xx = float2(3.0f, 4.0f); // エラー:代入に「.xx」などは使用できない。

要素数が違うのもだめ。

pos.xy = float4(1.0f, 2.0f, 3.0f, 4.0f); // エラー:float2にfloat4は代入できない

1回のアクセスで.rgbaと.xyzwの混在はできない。

pos.xg = float2(3.0f, 4.0f); // エラー:xとgは混在できない。

// なお二行に分けた場合は問題ない。
pos.x = 3.0f;
pos.g = 4.0f

スウィズル付きのベクトル型のポインタや参照はエラーとなる。

float4 pos = float4(1.0f, 2.0f, 3.0f, 4.0f);
my_func(&pos.xy); // エラー

ベクトル型のコンストラクタ[編集 | ソースを編集]

コンストラクタを使用すると、スカラーまたはベクトルの集合からベクトルを作成することができます。パラメータシグネチャは、ベクトルの構築と初期化の方法を決定します。例えば、ベクターが単一のスカラーパラメータのみで初期化される場合、構築されたベクターのすべての構成要素はそのスカラー値に設定されます。

複数のスカラー、1つ以上のベクトル、またはスカラーとベクトルの混合物からベクトルを構築する場合、ベクトルの成分は引数の成分から順番に構築されます。引数は左から右の順に消費される。各引数は、次の引数の成分が消費される前に、順番にそのすべての成分が消費されます。

マトリックス型[編集 | ソースを編集]

Metalでは行列を表すマトリックス型をサポートしている。

halfおよびfloatの末尾に「nxm」と付けるとマトリックス型になる。 nmの部分には2から4の数字が入る。

  • halfnxm
  • floatnxm

マトリックス成分へのアクセス[編集 | ソースを編集]

Metalでは基本的にC言語の多次元配列と同じでありインデックスは「ゼロ」から始まる。 プログラミング言語によっては「m11」などと「1始まり」のものもあるので移植の際には注意しよう。

float4x4 m;

// 2列目の全要素(全行)に2.0fを設定する
m[1] = float4(2.0f);

// 1行目1列目に1.0fを設定する
m[0][0] = 1.0f;

マトリックス型のコンストラクタ[編集 | ソースを編集]

引数が浮動点数型1個

浮動点数が1個だと

float4x4( val );

こうなる。

引数が同じサイズのマトリックス型

同じサイズのマトリックス型だと複製が作られる。

float3x4( float3x4 );

バッファー[編集 | ソースを編集]

Metalのバッファーとはいわゆるポインタである。

  • device
  • constant
  • threadgroup