Writing Custom CIFilter in iOS 11, Metal Linker

558 Views Asked by At

I'm trying to compile custom filters using MSL as discussed in this 2017 WWDC and in this part of the CIFilter Documentation. Without the MTLLINKER_FLAGS my program runs smoothly, but with the flags turned on (value set to -cifilter), my program's metal device.defaultLibrary fails to return vertex and fragment funcations. In fact, when I print out the library's function names they are all empty.

guard let library = device.newDefaultLibrary() else { return }
let pipelineDescriptor = MTLRenderPipelineDescriptor()
pipelineDescriptor.sampleCount = 1
pipelineDescriptor.colorAttachments[0].pixelFormat = .bgra8Unorm
pipelineDescriptor.depthAttachmentPixelFormat = .invalid

NSLog("%@", library.functionNames)
pipelineDescriptor.vertexFunction = library.makeFunction(name: "mapTexture")
pipelineDescriptor.fragmentFunction = library.makeFunction(name: "displayTexture")

do {
    try renderPipelineState = device.makeRenderPipelineState(descriptor: pipelineDescriptor)
}
catch {
    NSLog("%@", error.localizedDescription)
    assertionFailure("Failed creating a render state pipeline. Can't render the texture without one.")
    return
}

Metal Code:

    #include <metal_stdlib>
using namespace metal;

typedef struct {
    float4 renderedCoordinate [[position]];
    float2 textureCoordinate;
} TextureMappingVertex;

vertex TextureMappingVertex mapTexture(unsigned int vertex_id [[ vertex_id ]]) {
    float4x4 renderedCoordinates = float4x4(float4(-1.0, -1.0, 0.0, 1.0),
                                            float4( 1.0, -1.0, 0.0, 1.0),
                                            float4(-1.0,  1.0, 0.0, 1.0),
                                            float4( 1.0,  1.0, 0.0, 1.0));
    float4x2 textureCoordinates = float4x2(float2( 0.0, 1.0),
                                           float2( 1.0, 1.0),
                                           float2( 0.0, 0.0),
                                           float2( 1.0, 0.0));
    TextureMappingVertex outVertex;
    outVertex.renderedCoordinate = renderedCoordinates[vertex_id];
    outVertex.textureCoordinate = textureCoordinates[vertex_id];

    return outVertex;
}

fragment half4 displayTexture(TextureMappingVertex mappingVertex [[ stage_in ]],
                              texture2d<float, access::sample> texture [[ texture(0) ]]) {
    constexpr sampler s(address::clamp_to_edge, filter::linear);

    return half4(texture.sample(s, mappingVertex.textureCoordinate));
}
0

There are 0 best solutions below