TL;DR: Metal doesn't seem to detect what my vertex shader returns
I have these two functions written in MSL :
vertex float4 base_image_rect(constant float4 *pos [[buffer(0)]],
uint vid [[vertex_id]]) {
return pos[vid];
}
fragment float4 fragment_image_display(float4 vPos [[stage_in]],
texture2d<float, access::sample> imageToRender [[texture(0)]],
sampler imageSampler [[sampler(0)]]) {
return imageToRender.sample(imageSampler, float2(vPos.x, vPos.y));
}
When I try to create my render pipeline state with those, using this code:
// Make image display render pipeline state
let imageDisplayStateDescriptor = MTLRenderPipelineDescriptor()
imageDisplayStateDescriptor.colorAttachments[0].pixelFormat = view.colorPixelFormat
imageDisplayStateDescriptor.vertexFunction = library.makeFunction(name: "base_image_rect")
imageDisplayStateDescriptor.fragmentFunction = library.makeFunction(name: "fragment_image_display")
displayImagePipelineState = try! device.makeRenderPipelineState(descriptor: imageDisplayStateDescriptor)
There is an error at the creation of the pipeline state:
fatal error: 'try!' expression unexpectedly raised an error: Error Domain=CompilerError Code=1 "Link failed: fragment input vPos was not found in vertex shader outputs" [...]
I checked and rechecked the code and can't understand what's wrong.
Any ideas? Thank you!
Try replacing
stage_in
withposition
. I think thatstage_in
is mostly used withstruct
s where each field is either annotated with a specific attribute qualifier or matched by name. Apparently, when it's used with a non-struct type, it's trying to match by name. For example, if your vertex function were to output a struct one of whose fields wasvPos
, that would find it.