此信息来自here https://developer.apple.com/library/ios/documentation/Metal/Reference/MetalShadingLanguageGuide/data-types/data-types.html
float4
有一个对齐方式16
字节。这意味着这种类型的内存地址(例如0x12345670
) 将被整除16
(又名最后一个十六进制数字是0
).
packed_float4
另一方面有一个对齐4 bytes
。地址的最后一位数字将是0
, 4
, 8
or c
当您创建自定义结构时,这确实很重要。假设你想要一个具有 2 个法线的结构float
s and 1 float4
/packed_float4
:
struct A{
float x, y;
float4 z;
}
struct B{
float x, y;
packed_float4 z;
}
For A
: 的对齐方式float4
必须16
自从float4
必须在正常之后float
s,将会有8
之间的空白字节数y
and z
。这是什么A
在记忆中看起来像:
Address | 0x200 | 0x204 | 0x208 | 0x20c | 0x210 | 0x214 | 0x218 | 0x21c |
Content | x | y | - | - | z1 | z2 | z3 | z4 |
^Has to be 16 byte aligned
For B
:对齐packed_float4
is 4
,与float
,所以它可以紧随float
无论如何:
Address | 0x200 | 0x204 | 0x208 | 0x20c | 0x210 | 0x214 |
Content | x | y | z1 | z2 | z3 | z4 |
如你看到的,A
占用32
字节而B
只使用24
字节。当你有这些结构的数组时,A
将占用8
每个元素有更多字节。因此,对于传递大量数据,后者是首选。
你需要的理由float4
根本就是因为GPU无法处理4
字节对齐packed_float4
s,你将无法返回packed_float4
在着色器中。这是因为我假设的性能。
最后一件事:当您声明结构体的 Swift 版本时:
struct S {
let x, y: Float
let z : (Float, Float, Float, Float)
}
这个结构将等于B
在金属和not A
。元组就像一个packed_floatN
.
所有这些也适用于其他向量类型,例如packed_float3
, packed_short2
, ect.