【问题标题】:Problems using Metal and SceneKit simultaneously同时使用 Metal 和 SceneKit 的问题
【发布时间】:2019-01-19 08:22:06
【问题描述】:

我正在开发一个小的 SceneKit 项目,我想使用 Metal Compute 管道以编程方式生成纹理以提高速度。我有一个基本的管道设置,可以生成一个 MTLTexture 并且它可以工作,但是一旦我将 SceneKit 框架添加到项目中,它就无法声明Function <X> was not found in the library。如果我删除对 SceneKit 的所有引用,它会再次起作用。

我必须从正确的 URL 实例化我的库,否则如果没有 SceneKit,它将无法工作。是什么阻碍了它?有没有办法解决这个问题,也许使用 SCNRenderer?

[编辑] 为更清楚起见,以下是我获取 MTLLibrary 引用的方法:

    guard let url = Bundle.main.url(forResource: "MyLibrary", withExtension: "metallib") else {
        throw GeneratorError.metalLibraryNotFound
    }
    library = device.makeLibrary(URL: url)

调用对象(连同MTLDevice)保留一个强引用,它是一个单例,所以它保留在内存中。为了获取内核函数本身,我调用以下函数,它返回适当的管道状态:

    guard let function = library.makeFunction(name: functionName) else {
        throw GeneratorError.functionNotFound(functionName)
    }
    return device.makeComputePipelineState(function: function)

就像我说的那样,在将 SceneKit 添加到项目之前,这工作正常 - 只需将框架添加到链接框架列表就足够了,我不必对它做任何事情 - 因此它根本找不到任何我的功能。

【问题讨论】:

  • 您使用哪个 API 创建您的 MTLLibrary
  • 不止一个?我刚刚将它作为金属库,在新项目菜单中的 iOS / Frameworks & Libraries 下。它有 cikernel 链接器标志,因为它作为过滤器库开始,但我已经尝试删除它,它有点让事情变得更糟。我认为可能缺少链接器标志,但找不到对 SceneKit 链接器的任何引用。我想我可以尝试回到主项目中的一个普通 Metal 文件?
  • 他的意思是在你的应用代码中。您调用了哪些方法来获取对 MTLLibrary 对象的引用?
  • 我已将其添加到票证中。

标签: ios scenekit metal


【解决方案1】:

我已经找到了导致此问题的原因,但我仍然对原因感到非常困惑,因此我非常感谢人们提供任何进一步的意见!

基本上,我已将我的 Metal 库拆分为多个文件,以使其更易于处理。一个有 CIFilter 支持的函数,另一个有 Metal 管道内核。现在,我知道当两者都在主.metal 文件中链接时,两者是不兼容的,所以我暂时注释掉了一个,但保留它以供参考。我还在构建设置中有链接器标志-cikernel

我怀疑链接器标志可能会导致问题,但删除它会使事情变得更糟。最终,我尝试删除链接器标志和我之前只是注释掉的整个文件。这行得通!我猜编译器必须编译所有.metal 文件,无论它们是否包含在主文件中,并且不知何故,在同一个库中拥有 CIFilter 内核和纹理内核是一个很大的禁忌,即使它们不在同一个命名空间中。

如果有人知道这背后的原因,我很想知道!同时,我将简单地移除所有 CIFilter,并使用纯基于 Metal 的计算管道。

【讨论】:

    猜你喜欢
    • 2019-05-08
    • 2018-10-26
    • 2020-04-13
    • 2016-02-17
    • 2021-03-05
    • 1970-01-01
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    相关资源
    最近更新 更多