nor*_*784 6 swift metal swift-package-manager
我一直在使用 Xcode 项目,但现在我正在启动一个我希望将来在其他平台上运行的项目,所以我使用 Swift Package Manager 来生成项目,但我面临一个问题,我的库需要包含一个金属着色器文件(也是一个 openGL 着色器文件),但我对如何实现这一点一无所知。
我的项目有 2 个部分,包含图形内容的库和作为我实际应用程序的可执行文件,所以我想将我的图形库导入我的应用程序,但问题是金属着色器文件不包含在 Xcode 项目中似乎也没有编译/包含在库的捆绑文件中,因此我可以在运行时加载并在需要时使用它。
另外,如果您认为我做错了什么,请指出我。
问候
小智 5
在 Xcode 12 (swift-tools-version:5.3) 中,可以通过使用 Swift 包中的方法使用 .metal 文件MTLDevice.makeDefaultLibrary(bundle:)。
Swift 包的结构应类似于:
-Sources
-MetalShaders
-MetalShaders.metal
-MetalShaders.swift
-Tests
-MetalShadersTests
-MetalShadersTests.swift
Run Code Online (Sandbox Code Playgroud)
该文件MetalShaders.metal应包含 Metal 源代码,并且该文件MetalShaders.swift应包含必要的设置代码。初始内容的一个示例MetalShaders.swift如下:
// A metal device for access to the GPU.
public var metalDevice: MTLDevice!
// A metal library.
public var packageMetalLibrary: MTLLibrary!
// Function to perform the initial setup for Metal processing on the GPU
public func setupMetal() {
// Create metal device for the default GPU:
metalDevice = MTLCreateSystemDefaultDevice()
// Create the library of metal functions
// Note: Need to use makeDefaultLibrary(bundle:) as the "normal"
// call makeDefaultLibrary() returns nil.
packageMetalLibrary = try? metalDevice.makeDefaultLibrary(bundle: Bundle.module)
// List the available Metal shader functions
print(packageMetalLibrary.functionNames)
//
// ... add additional setup code here ...
//
}
Run Code Online (Sandbox Code Playgroud)
通过这种方法,packageMetalLibrary可以通过从 swift 包导入目标(与导入其他框架或包的方式相同),从依赖于 Swift 包的 Xcode 项目访问该变量。
import MetalShaders
Run Code Online (Sandbox Code Playgroud)
可以在早期版本的 Xcode 中使用此方法,因为该方法MTLDevice.makeDefaultLibrary(bundle:)自 iOS 10 / macOS 10.12 起可用,但Bundle.module需要实现扩展,并且尚不清楚这是否有效。
将您的Shaders.metal文件放入Metal目录中。然后将资源添加到您的目标Package.swift
.target(
name: "TargetName",
dependencies: [
.product(name: "AnotherModule", package: "AnotherPackage")
],
resources: [
.copy("Metal/")
]
)
Run Code Online (Sandbox Code Playgroud)
现在您可以访问您的图书馆:
let url = Bundle.module.url(forResource: "Shaders", withExtension: "metal", subdirectory: "Metal")!
let source = try String(contentsOf: url)
let library = try device.makeLibrary(source: source, options: nil)
Run Code Online (Sandbox Code Playgroud)
或者甚至更好(但仅适用于单个着色器文件):
.target(
name: "TargetName",
dependencies: [
.product(name: "AnotherModule", package: "AnotherPackage")
],
resources: [
.process("Metal/Shaders.metal")
]
)
Run Code Online (Sandbox Code Playgroud)
现在您可以访问您的图书馆:
let library = try device.makeDefaultLibrary(bundle: Bundle.module)
Run Code Online (Sandbox Code Playgroud)
看来现在还做不到这一点。当找到解决方法或 Apple 修复此问题时,我会更新此内容。
https://bugs.swift.org/browse/SR-2866
编辑:我发现的一个临时解决方案是创建一个bash 脚本,该脚本编辑工作区设置以更改构建路径,然后将 metallib 文件编译/复制到可执行路径(尚未尝试查看如何通过以下方式分发库) SPM 或类似的东西,现在仅适用于同一文件夹中的代码(即 Sources/MyEngine <-(此文件夹具有金属着色器)、Sources/MyGame)。
| 归档时间: |
|
| 查看次数: |
1430 次 |
| 最近记录: |