KhronosGroup / KhronosGroup/glslang

nonuniformEXT not working correctly in conditionals

Open
#3,561 3 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.