问题
VertexFunction and FragmentFunction defined in .metal file worked nicely, but they became nil once I specified Compiler and Linker Options following Apple's doc: -fcikernel flag in the Other Metal Compiler Flags option, and -cikernel flat in MTLLINKER_FLAGS in User-Defined setting.
I need the settings above for cikernel with MSL (metal shading language). Indeed, cikernel with Core Image Kernel Language deprecated in 12.0.
How could I use both vertex/fragment Metal shader and MSL cikernel together?
let library = self.device?.makeDefaultLibrary()!
let pipeLineDescriptor = MTLRenderPipelineDescriptor()
pipeLineDescriptor.vertexFunction=library.makeFunction(name: "myVertexShader")
pipeLineDescriptor.fragmentFunction=library.makeFunction(name: "myFragmentShader")
回答1:
I guess you have to compile your filter kernels separately instead of with your default Metal library.
To do so, you could for instance give them another file extension, like .kernel
and add a custom Build Rule like so:
Then add a custom Build Phase that copies the compiled kernel metallibs into your app bundle:
To initialize the CIKernel
with the correct metal source, you can do something like this:
let url = Bundle(for: type(of: self)).url(forResource: "<#name of your .kernel file#>", withExtension: "metallib")!
let data = try! Data(contentsOf: url)
let kernel = try! CIKernel(functionName: "<#kernel function name#>", fromMetalLibraryData: data)
(Note that you should remove the compiler and liker flags again from your project settings to have your other Metal sources compile properly again.)
回答2:
An update of Frank Schlegel's answer that works in Xcode 11, where, as Giraff Wombat mentions, the metal compiler simply ignores input files that don't end in .metal
. To make sure the CI kernel file stays out of the regular metal pipeline's way, I made the extension ".mcikernel
" and put for the build rule script:
mkdir -p ${DERIVED_FILES_DIR}/kernels
cp ${INPUT_FILE_PATH} ${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.metal
xcrun metal -fcikernel ${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.metal -c -o ${DERIVED_FILES_DIR}/kernels/${INPUT_FILE_BASE}.air
xcrun metallib -cikernel -o ${DERIVED_FILES_DIR}/kernels/${INPUT_FILE_BASE}.metallib ${DERIVED_FILES_DIR}/kernels/${INPUT_FILE_BASE}.air
来源:https://stackoverflow.com/questions/57391441/metal-vertexfunction-defined-in-metal-file-becomes-nil-once-setting-compiler-a