缺少着色器 C 兼容性是否重要?
Does lack of shader C compatibility matter?
我正在学习 Up and Running with Metal, Part 2,尝试学习使用最佳可用语言功能重写所有代码。这些功能之一是 C++ 构造函数,我很高兴能够在我的着色器中使用它,它们来自 Cg 和 GLSL,它们缺少这个。
此代码在设备上运行良好,但我收到警告:
'vertex_main' has C-linkage specified, but returns user-defined type
'ColoredVertex' which is incompatible with C
这重要吗?不知道为什么要指定C-linkage。我也不知道如何禁用警告,这是我想做的,同时报告一个错误,如果它不重要的话。
using namespace metal;
struct ColoredVertex {
const float4 position [[position]];
const half4 color;
ColoredVertex(const float4 position, const half4 color)
: position(position), color(color) {}
};
vertex ColoredVertex vertex_main(
constant float4 *position [[buffer(0)]],
constant float4 *color [[buffer(1)]],
uint vid [[vertex_id]]
) {return ColoredVertex(position[vid], half4(color[vid]));}
fragment half4 fragment_main(ColoredVertex vert [[stage_in]]) {
return vert.color;
}
让我们为您的 Metal 源代码再添加一项功能:
int myFunction(int x) { return x / 2; }
然后让我们手动 运行 编译器并要求它发出 human-readable 格式:
xcrun -sdk iphoneos metal MyLibrary.metal -S -emit-llvm
输出在MyLibrary.ll
中。这是输出中 vertex_main
的定义:
define %struct.ColoredVertex.packed @vertex_main(<4 x float> addrspace(2)* nocapture readonly, <4 x float> addrspace(2)* nocapture readonly, i32) local_unnamed_addr #1 {
%4 = zext i32 %2 to i64
%5 = getelementptr inbounds <4 x float>, <4 x float> addrspace(2)* %0, i64 %4
%6 = load <4 x float>, <4 x float> addrspace(2)* %5, align 16, !tbaa !22
%7 = getelementptr inbounds <4 x float>, <4 x float> addrspace(2)* %1, i64 %4
%8 = load <4 x float>, <4 x float> addrspace(2)* %7, align 16, !tbaa !22
%9 = tail call fast <4 x half> @air.convert.f.v4f16.f.v4f32(<4 x float> %8)
%10 = insertvalue %struct.ColoredVertex.packed undef, <4 x float> %6, 0
%11 = insertvalue %struct.ColoredVertex.packed %10, <4 x half> %9, 1
ret %struct.ColoredVertex.packed %11
}
这里是 myFunction
的定义:
define i32 @_Z10myFunctioni(i32) local_unnamed_addr #0 {
%2 = sdiv i32 %0, 2
ret i32 %2
}
这里要注意的重要一点是名字 myFunction
被破坏了,这意味着它有 C++ 链接,而名字 vertex_main
没有被破坏,这意味着它有 C-linkage。所以我们可以推断,声明一个函数为 vertex
会自动给它 C-linkage。 (fragment_main
也未损坏。)
它可能是 C-linkage 因为一个完整的名字更容易在 运行 时查找。 (回想一下,我们在 运行 时使用 -[MTLLibrary newFunctionWithName:]
按名称查找着色器函数。)
我猜“与 C 不兼容”警告在您的情况下无关紧要。我认为 ColoredVertex
“与 C 不兼容”,因为它有一个 non-trivial 构造函数,但除此之外它是一个 C-compatible POD(plain-old 数据类型)。
我正在学习 Up and Running with Metal, Part 2,尝试学习使用最佳可用语言功能重写所有代码。这些功能之一是 C++ 构造函数,我很高兴能够在我的着色器中使用它,它们来自 Cg 和 GLSL,它们缺少这个。
此代码在设备上运行良好,但我收到警告:
'vertex_main' has C-linkage specified, but returns user-defined type 'ColoredVertex' which is incompatible with C
这重要吗?不知道为什么要指定C-linkage。我也不知道如何禁用警告,这是我想做的,同时报告一个错误,如果它不重要的话。
using namespace metal;
struct ColoredVertex {
const float4 position [[position]];
const half4 color;
ColoredVertex(const float4 position, const half4 color)
: position(position), color(color) {}
};
vertex ColoredVertex vertex_main(
constant float4 *position [[buffer(0)]],
constant float4 *color [[buffer(1)]],
uint vid [[vertex_id]]
) {return ColoredVertex(position[vid], half4(color[vid]));}
fragment half4 fragment_main(ColoredVertex vert [[stage_in]]) {
return vert.color;
}
让我们为您的 Metal 源代码再添加一项功能:
int myFunction(int x) { return x / 2; }
然后让我们手动 运行 编译器并要求它发出 human-readable 格式:
xcrun -sdk iphoneos metal MyLibrary.metal -S -emit-llvm
输出在MyLibrary.ll
中。这是输出中 vertex_main
的定义:
define %struct.ColoredVertex.packed @vertex_main(<4 x float> addrspace(2)* nocapture readonly, <4 x float> addrspace(2)* nocapture readonly, i32) local_unnamed_addr #1 {
%4 = zext i32 %2 to i64
%5 = getelementptr inbounds <4 x float>, <4 x float> addrspace(2)* %0, i64 %4
%6 = load <4 x float>, <4 x float> addrspace(2)* %5, align 16, !tbaa !22
%7 = getelementptr inbounds <4 x float>, <4 x float> addrspace(2)* %1, i64 %4
%8 = load <4 x float>, <4 x float> addrspace(2)* %7, align 16, !tbaa !22
%9 = tail call fast <4 x half> @air.convert.f.v4f16.f.v4f32(<4 x float> %8)
%10 = insertvalue %struct.ColoredVertex.packed undef, <4 x float> %6, 0
%11 = insertvalue %struct.ColoredVertex.packed %10, <4 x half> %9, 1
ret %struct.ColoredVertex.packed %11
}
这里是 myFunction
的定义:
define i32 @_Z10myFunctioni(i32) local_unnamed_addr #0 {
%2 = sdiv i32 %0, 2
ret i32 %2
}
这里要注意的重要一点是名字 myFunction
被破坏了,这意味着它有 C++ 链接,而名字 vertex_main
没有被破坏,这意味着它有 C-linkage。所以我们可以推断,声明一个函数为 vertex
会自动给它 C-linkage。 (fragment_main
也未损坏。)
它可能是 C-linkage 因为一个完整的名字更容易在 运行 时查找。 (回想一下,我们在 运行 时使用 -[MTLLibrary newFunctionWithName:]
按名称查找着色器函数。)
我猜“与 C 不兼容”警告在您的情况下无关紧要。我认为 ColoredVertex
“与 C 不兼容”,因为它有一个 non-trivial 构造函数,但除此之外它是一个 C-compatible POD(plain-old 数据类型)。