【问题标题】:iOS framework: MTLLibrary newFunctionWithName fails when cikernel flag is set on client codeiOS 框架:在客户端代码上设置 cikernel 标志时 MTLLibrary newFunctionWithName 失败
【发布时间】:2020-12-11 20:05:24
【问题描述】:

我有一个使用 Metal 的 iOS 框架;它设置管道描述符如下:

...
_metalVars.mtlLibrary = [_metalVars.mtlDevice newLibraryWithFile:libraryPath error:&error];

id <MTLFunction> vertexFunction = [_metalVars.mtlLibrary newFunctionWithName:@"vertexShader"];
id <MTLFunction> fragmentFunction = [_metalVars.mtlLibrary newFunctionWithName:@"fragmentShader"];

MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init];

MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
pipelineStateDescriptor.label = @"MyPipeline";
pipelineStateDescriptor.vertexFunction = vertexFunction;
pipelineStateDescriptor.fragmentFunction = fragmentFunction;
pipelineStateDescriptor.vertexDescriptor = mtlVertexDescriptor;
pipelineStateDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatRGBA8Unorm; 

_metalVars.mtlPipelineState = [_metalVars.mtlDevice newRenderPipelineStateWithDescriptor:pipelineStateDescriptor error:&error];
...

这个框架被一个iOS应用程序使用,并且在flag之前一直运行良好

-fcikernel

在其他金属编译器标志下设置,并且

-cikernel

在其他金属链接器标志下,在客户端应用程序的构建设置中。 (在客户端上设置的标志,每个 https://developer.apple.com/documentation/coreimage/cikernel/2880194-kernelwithfunctionname.)

随着客户端应用程序中的这些更改,上述框架代码 sn-p 现在在上述代码 sn-p 的最后一行失败,在调用 newRenderPipelineStateWithDescriptor 时出现错误

validateWithDevice:2556: failed assertion `Render Pipeline Descriptor Validation
vertexFunction must not be nil

我已经验证框架现在为顶点函数返回 nil

id <MTLFunction> vertexFunction = [_metalVars.mtlLibrary newFunctionWithName:@"vertexShader"];

但如果我删除客户端应用程序上的标志,效果很好。

问题: 1.) 我知道金属着色器是预编译的;为什么更改 client 代码上的构建设置会导致 unchanged 框架中的运行时失败? 2.) 如何解决?

【问题讨论】:

    标签: ios metal


    【解决方案1】:

    这些标志是在编译用 Metal 编写的 Core Image 内核时使用的。它们以与“常规”金属着色器代码不兼容的方式更改代码的翻译方式。

    在项目级别设置 Core Image 标志的问题是所有 .metal 文件都会受到影响——无论它们是否包含 Core Image 内核或常规着色器代码。

    解决此问题的最佳方法是对包含 Core Image Metal 内核的文件使用不同的文件扩展名,例如 .ci.metal。然后可以使用自定义构建规则将这些内核与 Metal 代码库的其余部分分开编译。 我推荐来自 WWDC 2020 的 this session,它详细描述了该过程。

    【讨论】:

    • 完美 - 修复了它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2011-10-19
    • 2015-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多