gadirom
(Roman Gaditskii)
1
Hey!
I stumbled upon this issue.
There is no simd_packed_float3 type in Swift.
Why it's a problem?
Consider this Metal struct:
struct Test{
packed_float3 x;
float y;
};
First of all, you can't calculate a buffer pointer to address the memory of y, since you can't do this:
MemoryLayout<simd_packed_float3>.size
(Not sure if stride makes sense with packed types, but anyway with simd types it always gives the same length as size on my devices)
You can't use MemoryLayout<simd_float3>.size either, since it will return 16 and not 12 like in architectures available to me for testing.
Second, if you need to write a packed_float3 value of x to the buffer you will need to write the three consecutive floats, but not a single simd type. Again, simd_float3 is not usable since it will write 0 into the forth word corrupting the memory of the next property in the struct (y).
So I've done this:
struct Float_3{
var x: Float
var y: Float
var z: Float
}
typealias simd_packed_float3 = Float_3
It seems to be a functioning solution, but I'm not sure it's not a nasty thing to do...
What problems may I encounter with this approach, and how could I be sure that it won't break on some device that I don't have?
1 Like
This is not guaranteed to work and may break in the future. Swift does not make any guarantees about the layout of stored properties in a structure.
Is MTLPackedFloat3 what you're looking for? If not, I'd recommend defining your own packed float3 type in a C header and using Swift bridging, since C does make guarantees about the layout of a structure.
2 Likes
scanon
(Steve Canon)
3
There's no simd_packed_float3 in C or C++ either; the type cannot be defined in clang. This is why it doesn't exist in Swift.
You should use a tuple-of-three-floats in your CPU-side struct, or the MTLPackedFloat3 convenience; this is guaranteed to have the correct layout for packed_float3 on the GPU.
6 Likes
gadirom
(Roman Gaditskii)
4
Thank you guys! This is exactly what I needed!
2 Likes