我需要将带有
packed_float3
(MTLPackedFloat3
) 值的结构从 Swift 传递到我的 Metal 着色器中。我目前正在使用桥接头在 Swift 和 Metal 之间共享类型。这是我要写的结构:
typedef struct {
packed_float3 value;
} CustomData;
但是,当我尝试使用
packed_float3
时,我收到以下错误:
unknown type name 'packed_float3'
我尝试过各种类型的变体,包括
MTLPackedFloat3
、packed_simd_float3
、metal::packed_float3
、vector_packed_float3
、packed<float, 3>
,但都不起作用。我还尝试过包含各种其他标头,例如 <metal/metal.h>
或 <metal/MTLAccelerationStructureTypes.h>
,但这通常会产生其他编译器错误
如何在桥接标头中使用打包值而无需定义自己的类型?
可能有更好的方法来做到这一点,但这对我有用:
我认为根本原因是桥接头本质上是在两个不同的环境中“构建”两次:一次用于 Swift,一次用于 Metal。例如,
packed_float3
始终在 Metal 中定义,但在 Swift 中未定义。另一方面, MTLPackedFloat3
在 Swift 中工作正常,但在 Metal 中没有定义。
作为解决方法,我们可以使用预处理来改变 Metal 编译与 swift 编译中使用的类型。一个简单的方法是检查
__METAL_VERSION__
是否已定义,因为只有当 header 包含在 Metal 中时才会定义它。现在对于 Swift,我们可以将 packed_float3
别名为 Swift 类型 MTLPackedFloat3
:
#ifndef __METAL_VERSION__
#include <metal/metal.h>
typedef MTLPackedFloat3 packed_float3;
#endif
此代码仅在 Swift 编译中有效。它还依赖于
MTLPackedFloat3
和 packed_float3
具有相同的数据布局。现在您可以在 Swift 和 Metal 的标题中使用 packed_float3
!
有兴趣听听是否有更好的方法,因为这非常丑陋