KhronosGroup / KhronosGroup/glslang
nonuniformEXT not working correctly in conditionals
- Dominant language
- C++
- Stars
- 3.6k
- Forks
- 989
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 31
Description
Spirv generated is not valid when nonuniformEXT is used in ternary condition or even if/else condition.
Issue happens when nonuniformEXT is used for the texture index. If nonuniformEXT is used for the sampler, then the spirv is generated correctly.
But according to Vulkan spec https://github.com/KhronosGroup/GLSL/blob/main/extensions/ext/GL_EXT_nonuniform_qualifier.txt nonuniformEXT can be used for local variables as well.
GLSL
```
#version 450
#extension GL_EXT_nonuniform_qualifier : require
layout(constant_id = 0) const uint gCondition = 1u;
layout(set = 0, binding = 2, std430) readonly buffer type_StructuredBuffer_uint
{
uint _m0[];
} sb;
layout(set = 0, binding = 0) uniform texture2D gTextures[];
layout(set = 0, binding = 1) uniform sampler st;
layout(location = 0) in vec2 in_var_TEXCOORD0;
layout(location = 0) out vec4 out_var_SV_TARGET0;
void main()
{
uint _38 = uint(in_var_TEXCOORD0.x);
uint _13 = (sb._m0[_38] * 1000u);
uint _14 = (sb._m0[_38]);
if (gCondition != 0)
{
out_var_SV_TARGET0 = texture((sampler2D(gTextures[nonuniformEXT(_13)], st)), in_var_TEXCOORD0);
}
else
{
out_var_SV_TARGET0 = texture((sampler2D(gTextures[nonuniformEXT(_14)], st)), in_var_TEXCOORD0);
}
}
```
Command line
```
glslangValidator.exe -V a.glsl -S frag
```
Decompile spirv using spirv-cross
```
spirv-cross.exe .\frag.spv --output frag.glsl --vulkan-semantics
```
Resulting GLSL has no nonuniformEXT instructions
```
#version 450
#extension GL_EXT_nonuniform_qualifier : require
layout(constant_id = 0) const uint gCondition = 1u;
layout(set = 0, binding = 2, std430) readonly buffer type_StructuredBuffer_uint
{
uint _RESERVED_IDENTIFIER_FIXUP_m0[];
} sb;
layout(set = 0, binding = 0) uniform texture2D gTextures[];
layout(set = 0, binding = 1) uniform sampler st;
layout(location = 0) in vec2 in_var_TEXCOORD0;
layout(location = 0) out vec4 out_var_SV_TARGET0;
void main()
{
uint _RESERVED_IDENTIFIER_FIXUP_38 = uint(in_var_TEXCOORD0.x);
uint _RESERVED_IDENTIFIER_FIXUP_13 = sb._RESERVED_IDENTIFIER_FIXUP_m0[_RESERVED_IDENTIFIER_FIXUP_38] * 1000u;
uint _RESERVED_IDENTIFIER_FIXUP_14 = sb._RESERVED_IDENTIFIER_FIXUP_m0[_RESERVED_IDENTIFIER_FIXUP_38];
if (_RESERVED_IDENTIFIER_FIXUP_38 != 0u)
{
uint _48 = _RESERVED_IDENTIFIER_FIXUP_13;
out_var_SV_TARGET0 = texture(sampler2D(gTextures[_48], st), in_var_TEXCOORD0);
}
else
{
uint _62 = _RESERVED_IDENTIFIER_FIXUP_14;
out_var_SV_TARGET0 = texture(sampler2D(gTextures[_62], st), in_var_TEXCOORD0);
}
}
```
Contributor guide
Research direction
Start by reproducing the issue with glslangValidator.exe using the provided GLSL and command line, then inspect the generated output with spirv-cross.exe. Trace how nonuniformEXT on texture indices is represented inside conditional branches. Done means the generated SPIR-V preserves the required nonuniform behavior for both ternary and if/else conditions.
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
- 42/100