KhronosGroup / KhronosGroup/glslang

uniform structures and invalid locations

Open
#2,279 4 comments 0 reactions 0 assignees View on GitHub
GLSL/ESSL Missing Functionality
Dominant language
C++
Stars
3.6k
Forks
989
Avg merge
1d 2h
Merged PRs (30d)
31

Description

This example shader:

```
#version 430

struct B0 { mat4 M1; mat4 M2; };
layout(location=0) uniform B0 Var0;

struct B1 { vec4 E1; };
layout(location=1) uniform B1 Var1;

layout(location=0) in vec4 vs_Position;

void main( )
{
gl_Position = Var0.M2 * vs_Position;
}
```

should not compile, since uniform location 1 is overlapped by `Var0` and `Var1`. However it compiles just fine, and even worse - if you use `spirv-opt` (with -Os flag) on the generated binary, then decompose it you can clearly see that the main function uses the matrix at location 0 instead of location 1.

Result as generated by `spirv-cross` after passing the bytecode through `spirv-opt`:
```
#version 430
struct B0 { mat4 M2; };
layout(location = 0) uniform B0 Var0;
layout(location = 0) in vec4 vs_Position;
void main()
{
gl_Position = Var0.M2 * vs_Position;
}
```

If I modify the source shader code to use arrays instead of structures, however, the tool properly identifies the overlay and yield error:
```
#version 430
layout(location=0) uniform mat4 Var0[2];
layout(location=1) uniform vec4 Var1[5];
layout(location=0) in vec4 vs_Position;
void main( )
{
gl_Position = Var0[1] * vs_Position;
}
```
Results in:
```
ERROR: test.glsl:4: 'location' : overlapping use of location 1
ERROR: 1 compilation errors. No code generated.
```

Also if I fix the locations so that the arrays don't overlap, the code produced by `spirv-cross`, after optimizing the bytecode is perfectly fine - the matrix used in the multiplication is the one at location 1 as expected.

Contributor guide

Open the contributing guide

Research direction

Start by compiling the reported struct-based shader and compare it with the array-based shader that correctly reports overlapping locations. Check the generated binary through spirv-opt with -Os and spirv-cross; done means the struct case rejects the overlapping locations and valid non-overlapping locations preserve the referenced matrix.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.