Half a year ago the vulkan validation layer of matching the declaration of gl_PerVertex between shaders (e.g. vertex and geometry). Hence following pair of shaders now throws a validation error:

// shader.vert
#version 450

layout(location = 0) in vec3 inPos;

out gl_PerVertex {
    vec4 gl_Position;

void main()
    gl_Position = vec4(1);

// shader.geom
#version 450

layout(triangles) in;
layout(triangle_strip, max_vertices=3) out;

void main()
    for(int i = 0; i < gl_in.length(); i++) {
        gl_Position = gl_in[i].gl_Position;

I see it's somewhat an artificial example, as nobody really wants the undefined semantics of this code, but still, the code, that had such dangling built-in inouts in GS, appeared to work under two major IHVs and I only figured out a problem here after updating the vulkan validation layers. Hence, I got some questions.

  1. Having read this, I assume it's crucial to have the matching declarations, but then I'm puzzled about how mismatched shaders been working in my code. Just a coincidence, or more?
  2. What is the best practice of using the built-in in-out interfaces? Is it beneficial to reduce the in-out interface to the smallest possible subset? Or can I just set it unspecified and let the compiler decide? Any tips for doing it in Vulkan?
  3. Is using built-in interface gl_PointSize faster than plain attachments (i.e. something like layout (location = 0) out float outX;)?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.