Parece que [[stitchable]]
os kernels do Metal Core Image falham ao vincular em tempo de compilação devido ao Core Image sampler.coord()
e sampler.sample(coord)
símbolos não encontrados, OU, falham ao carregar em tempo de execução se eu adicionar outros sinalizadores de vinculador do Metal -fcikernel
(o que não é necessário de qualquer maneira para kernels costuráveis).
Aqui está o link completo do projeto de teste no github . Sinta-se à vontade para baixá-lo e brincar.
Descobri que o principal culpado é esta linha no arquivo Metal que o vinculador não consegue resolver:
float2 srcCoord = inputImage.coord();
Trechos do meu código:
import CoreImage
class FilterTwo: CIFilter {
var inputImage: CIImage?
var inputParam: Float = 0.0
static var kernel: CIKernel = { () -> CIKernel in
let url = Bundle.main.url(forResource: "default",
withExtension: "metallib")!
let data = try! Data(contentsOf: url)
let kernelNames = CIKernel.kernelNames(fromMetalLibraryData: data)
NSLog("Kernels \(kernelNames)")
return try! CIKernel(functionName: "secondFilter", fromMetalLibraryData: data) //<-- This fails!
}()
override var outputImage : CIImage? {
guard let inputImage = inputImage else {
return nil
}
return FilterTwo.kernel.apply(extent: inputImage.extent, roiCallback: { (index, rect) in
return rect }, arguments: [inputImage])
}
}
Aqui está o arquivo Metal:
#include <CoreImage/CoreImage.h> // includes CIKernelMetalLib.h
using namespace metal;
[[ stitchable ]] half4 secondFilter (coreimage::sampler inputImage, coreimage::destination dest)
{
float2 srcCoord = inputImage.coord();
half4 color = half4(inputImage.sample(srcCoord));
return color;
}
E aqui está o uso:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let filter = FilterTwo()
filter.inputImage = CIImage(color: CIColor.red)
let outputImage = filter.outputImage!
NSLog("Output \(outputImage)")
}
}
E a saída:
StitchableKernelsTesting/FilterTwo.swift:15: Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=CIKernel Code=1 "(null)" UserInfo={CINonLocalizedDescriptionKey=Function does not exist in library data. …•∆}
Kernels []
reflect Function 'secondFilter' does not exist.
Embora o processo de construção seja muito mais fácil com
[[ stitchable ]]
kernels de CI, você ainda precisa informar ao vinculador Metal para vincular-se ao Core Image. Isso foi mencionado na sessão WWDC21 sobre o tema .Para fazer isso, você precisa adicionar a
-framework CoreImage
bandeira a Outras bandeiras do Metal Linker conforme abaixo. Observe que você precisa adicioná-lo em duas linhas separadas, caso contrário não funcionará.