Reputation: 11776
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
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 calledMTLLINKER_FLAGS
with a value of-cikernel
:
Upvotes: 3