Metal: vertexFunction defined in .metal file becomes nil once setting Compiler and Linker Options for MSL cikernel

亡梦爱人 提交于 2020-02-23 07:14:48

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!