且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

作为 iOS 框架一部分的 Metal 文件

更新时间:2022-05-09 07:52:47

有很多方法可以为 Metal 着色器提供静态库,所有这些方法都有不同的权衡.我会在这里一一列举.

There are many ways to provide Metal shaders with a static library, all with different tradeoffs. I'll try to enumerate them here.

1) 将您的 .metal 文件转换为静态字符串,这些字符串被烘焙到您的静态库中.

1) Transform your .metal files into static strings that are baked into your static library.

这可能是最糟糕的选择.这个想法是您将 Metal 着色器代码预处理为字符串,这些字符串作为字符串文字包含在您的静态库中.然后,您将使用 newLibraryWithSource:options:error: API(或其异步兄弟)将源转换为 MTLLibrary 并检索函数.这需要您设计一个过程来进行 .metal 到字符串的转换,并且您失去了着色器预编译的好处,使生成的应用程序变慢.

This is probably the worst option. The idea is that you preprocess your Metal shader code into strings which are included as string literals in your static library. You would then use the newLibraryWithSource:options:error: API (or its asynchronous sibling) to turn the source into an MTLLibrary and retrieve the functions. This requires you to devise a process for doing the .metal-to-string conversion, and you lose the benefit of shader pre-compilation, making the resulting application slower.

2) 将 .metal 文件与您的静态库一起发送,并要求库用户将它们添加到他们的应用目标中

2) Ship .metal files alongside your static library and require library users to add them to their app target

考虑到所有因素,这是一个不错的选择,尽管它会给您的用户带来更多负担并暴露您的 Metal 着色器源(如果这是一个问题).静态库中的代码可以使用默认库"(newDefaultLibrary),因为代码将被 Xcode 自动编译到应用程序的 default.metallib 中,该代码嵌入在应用程序包作为资源.

All things considered, this is a decent option, though it places more of a burden on your users and exposes your Metal shader source (if that's a concern). Code in your static library can use the "default library" (newDefaultLibrary), since the code will be compiled automatically by Xcode into the app's default.metallib, which is embedded in the app bundle as a resource.

3) 随静态库一起发送 .metallib 文件

3) Ship a .metallib file alongside your static library

这是易用性、性能和安全性之间的一个很好的中间地带(因为它不会暴露你的着色器源,只暴露它的 IR).基本上,您可以在项目中创建一个Metal Library"目标,将着色器代码放入其中.这将生成一个 .metallib 文件,您可以将它与您的静态库一起提供,并将您的用户作为资源嵌入到他们的应用程序目标中.您的静态库可以在运行时使用 newLibraryWithData:error:newLibraryWithURL:error: API 加载 .metallib.由于您的着色器将被预编译,因此创建库的速度会更快,并且您将保持编译时诊断的优势.

This is a good middle ground between ease-of-use, performance, and security (since it doesn't expose your shader source, only its IR). Basically, you can create a "Metal Library" target in your project, into which you put your shader code. This will produce a .metallib file, which you can ship along with your static library and have your user embed as a resource in their app target. Your static library can load the .metallib at runtime with the newLibraryWithData:error: or newLibraryWithURL:error: API. Since your shaders will be pre-compiled, creating libraries will be faster, and you'll keep the benefit of compile-time diagnostics.