KhronosGroup / KhronosGroup/glslang

HLSL: loop unrolled constant offsets generate Offset instead of ConstOffset to OpImageFetch

Open
#2,877 8 comments 0 reactions 1 assignee Claimed by @greg-lunarg View on GitHub
bug HLSL SPIR-V
Dominant language
C++
Stars
3.6k
Forks
989
Avg merge
1d 2h
Merged PRs (30d)
31

Description

The following shader will produce a runtime validation error (note: spirv-val does not catch this, but Vulkan validation does):

[VUID-StandaloneSpirv-Offset-04663] Image Operand Offset can only be used with OpImage*Gather operations"

Shader:
```
Texture2D g_inoutColorReadonly;
struct PS_INPUT
{
uint2 vTexCoord : TEXCOORD0;
};

float4 LoadSourceColor( uint2 pixelPos, int2 offset )
{
float4 color = g_inoutColorReadonly.Load( int3( pixelPos, 0 ), offset );
return color;
}
float4 MainPs( PS_INPUT ps_input ) : SV_TARGET0
{
float4 color = float4( 0, 0, 0, 0 );
[unroll]
for ( int i = 0; i < 2; i++ )
{
color += LoadSourceColor( ps_input.vTexCoord.xy, uint2( i, i ) );
}
return color;
}
```

Compiled with: glslangValidator -D -e MainPs -S frag -V test.hlsl -o test.spv

The SPIR-V output contains the following instruction:
```
%138 = OpImageFetch %v4float %124 %130 Lod|Offset %int_0 %110
```

I believe the issue is that the compiler isn't able to figure out that uint( i, i ) in an unrolled loop could be a ConstOffset (if you change it to pass in a hardcoded constant, it will change from Offset to ConstOffset). I tested this shader on dxc and it produces the same output for that instruction. I guess it's a little questionable whether this is something glslang should handle, but it is accepted by fxc.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.