Search code examples
swiftsimdmetal

How to deal with the lack of `simd_packed_float3` in Swift


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?


Solution

  • I'm answering this following the answers I received on the Swift forum.

    Turns out that someone in the Metal team at Apple has already thought of this problem and created the MTLPacked types exactly for the types that would have irregular sizes: