KhronosGroup / KhronosGroup/glslang
HLSL: loop unrolled constant offsets generate Offset instead of ConstOffset to OpImageFetch
- 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
Assessment
This issue has not been assessed yet.