Pono
Pono

Reputation: 11776

Custom Metal Kernel function not found in the default app bundle

I am in the process of writing a command-line MacOS application to play with custom Metal kernels for CoreImage filtering. I have a simple kernel that basically does nothing - returns the same pixel information to the output:

#include <metal_stdlib>
#include <CoreImage/CoreImage.h>

using namespace metal;

extern "C" {
    namespace coreimage {
        float4 foobar(sample_t s, float opacity) {
            return float4(s.rgba);
        }
    }
}

I than initialise CIColorKernel like so:

let url = Bundle.main.url(forResource: "default", withExtension: "metallib")!
let data = try! Data(contentsOf: url)
try kernel = CIColorKernel(functionName: "foobar", fromMetalLibraryData: data)!

This works just fine when testing from within the Xcode itself. However, when I build my command-line application for running and actually run it from the terminal I am getting the following error:

Error Domain=CIKernel Code=1 "(null)" UserInfo={CINonLocalizedDescriptionKey=Function does not exist in library data. }

This implies that my custom function foobar cannot be found in the main (default) metallib. Any ideas how to fix this?

Upvotes: 1

Views: 871

Answers (1)

Anton
Anton

Reputation: 736

As Frank Schlegel correctly pointed out in the comments, you need a special compiler option and a linker flag.

Here is what the documentation says:

To use MSL as the shader language for a CIKernel, you must specify some options in Xcode under the Build Settings tab of your project's target. The first option you need to specify is an -fcikernel flag in the Other Metal Compiler Flags option. The second is to add a user-defined setting with a key called MTLLINKER_FLAGS with a value of -cikernel:

enter image description here

Upvotes: 3

Related Questions