KhronosGroup / KhronosGroup/glslang

Implicitly-generated `gl_PerVertex` collides with user-defined outputs

Open
#989 6 comments 0 reactions 0 assignees View on GitHub
GLSL/ESSL question SPIR-V
Dominant language
C++
Stars
3.6k
Forks
989
Avg merge
1d 2h
Merged PRs (30d)
31

Description

Given the following GLSL vertex shader as input:

```
#version 450 core

layout(location = 0)
in vec4 foo;

layout(location = 0)
out vec4 bar;

// Acts as if the following were declared:
//
// layout(location = 0)
// out gl_PerVertex
// {
// vec4 gl_Position;
// float gl_PointSize;
// float gl_ClipDistance[1];
// float gl_CullDistance[1];
// };

void main()
{
bar = foo;
gl_Position = foo;
}
```

glslang (at least as I'm driving it through the API) generates output SPIR-V that declares a `gl_PerVertex` block with a location of `0`. In effect, it acts just as if the commented-out `gl_PerVertex` declaration above were included (I have confirmed that I get identical SPIR-V with and without the declaration).

It seems unreasonable for glslang to implicitly generate output declarations with locations that collide with user code. If the implicitly generated `gl_PerVertex` used location `1`, I would see no problems here.

If it is an expectation that Vulkan GLSL users should always explicitly declare `gl_PerVertex`, then I would expect glslang to give an error when I fail to do so. Also, that would be a usability nightmare.

As it is, a shipping Vulkan driver gives an error when presented the glslang-generated SPIR-V for this shader, when it tries to match the VS outputs to a fragment shader with an explicit `layout(location = 0) in vec4 foo;`.

I find it hard to believe this is a useful default behavior, so I hope that this is just a bug.

Contributor guide

Open the contributing guide

Research direction

Reproduce the report using the GLSL vertex shader and inspect the generated SPIR-V, comparing runs with and without the explicit gl_PerVertex declaration. Trace the compiler entry point that creates the implicit block; done means the generated interface no longer collides with the user-defined output and remains valid for the matching fragment shader.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers, computer-graphics
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.