Matt Bierner
Matt Bierner

Reputation: 65543

How can I use `packed_float3` in a bridging header between Swift and Metal?

I need to pass a struct with a packed_float3 (MTLPackedFloat3) value from Swift into my Metal shader. I am currently sharing types between Swift and metal using a bridging header. Here's the struct I am trying to write:

typedef struct {
    packed_float3 value;
} CustomData;

However when I try using packed_float3, I get the following error:

unknown type name 'packed_float3'

I've tried all sort of type variations including MTLPackedFloat3, packed_simd_float3, metal::packed_float3, vector_packed_float3, packed<float, 3> but none of them work. I've also tried including various other headers such as <metal/metal.h> or <metal/MTLAccelerationStructureTypes.h> but this often produces other compiler errors

How can I use packed values in bridging headers without having to define my own types?

Upvotes: 0

Views: 159

Answers (1)

Matt Bierner
Matt Bierner

Reputation: 65543

There's likely a better way to do this but here's what worked for me:

I believe the root cause is that the bridging header is essentially "built" twice in two different environments: once for Swift and once for Metal. packed_float3 for example is always defined in Metal but isn't defined in Swift. On the other hand, MTLPackedFloat3 works fine in Swift isn't defined in Metal.

As a workaround, we can use preprocessing to vary the types used in the Metal compile vs in the swift compile. A simple way to do this is to check if __METAL_VERSION__ is defined as it will only be defined when the header is included in Metal. Now for Swift, we can alias packed_float3 to the Swift type MTLPackedFloat3:

#ifndef __METAL_VERSION__
#include <metal/metal.h>
typedef MTLPackedFloat3 packed_float3;
#endif

This code will only be active in the Swift compile. It also counts on MTLPackedFloat3 and packed_float3 having the same data layout. Now you can use packed_float3 in the header for both Swift and Metal!

Interested to hear if there's a better approach because this is pretty ugly

Upvotes: 0

Related Questions