3

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!

Pop Flamingo
  • 3,023
  • 2
  • 26
  • 64

1 Answers1

6

Try replacing stage_in with position. I think that stage_in is mostly used with structs 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 was vPos, that would find it.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • Isn't the position label used to get the position on the screen rather than the one relative to the rectangle ? – Pop Flamingo Jan 10 '17 at 00:20
  • thank you for your answer, I'll check that tomorrow – Pop Flamingo Jan 10 '17 at 00:21
  • It's "window-relative", but that really means relative to the viewport, which specifies a portion of the color or depth attachment(s). For a vertex shader like yours, which just returns a `float4`, the return value is the `position`. Since that's what you want as input to your fragment function, you want to annotate that input as `position`, too. – Ken Thomases Jan 10 '17 at 01:13