glslang icon indicating copy to clipboard operation
glslang copied to clipboard

Precision of image is applied to result of imageLoad when generating SPIR-V

Open ShabbyX opened this issue 3 years ago • 1 comments

Take the following code:

#version 320 es

layout(set = 0, binding = 0, rgba8) uniform readonly mediump image2D img;
layout(set = 0, binding = 1) buffer B
{
    vec4 result; 
};

void main()
{
    result = imageLoad(img, ivec2(0));
}

It produces the following SPIR-V:

; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 10
; Bound: 22
; Schema: 0
               OpCapability Shader
          %1 = OpExtInstImport "GLSL.std.450"
               OpMemoryModel Logical GLSL450
               OpEntryPoint GLCompute %main "main"
               OpExecutionMode %main LocalSize 1 1 1
               OpSource ESSL 320
               OpName %main "main"
               OpName %B "B"
               OpMemberName %B 0 "result"
               OpName %_ ""
               OpName %img "img"
               OpMemberDecorate %B 0 Offset 0
               OpDecorate %B BufferBlock
               OpDecorate %_ DescriptorSet 0
               OpDecorate %_ Binding 1
               OpDecorate %img RelaxedPrecision
               OpDecorate %img DescriptorSet 0
               OpDecorate %img Binding 0
               OpDecorate %img NonWritable
               OpDecorate %16 RelaxedPrecision
               OpDecorate %19 RelaxedPrecision
       %void = OpTypeVoid
          %3 = OpTypeFunction %void
      %float = OpTypeFloat 32
    %v4float = OpTypeVector %float 4
          %B = OpTypeStruct %v4float
%_ptr_Uniform_B = OpTypePointer Uniform %B
          %_ = OpVariable %_ptr_Uniform_B Uniform
        %int = OpTypeInt 32 1
      %int_0 = OpConstant %int 0
         %13 = OpTypeImage %float 2D 0 0 0 2 Rgba8
%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
        %img = OpVariable %_ptr_UniformConstant_13 UniformConstant
      %v2int = OpTypeVector %int 2
         %18 = OpConstantComposite %v2int %int_0 %int_0
%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
       %main = OpFunction %void None %3
          %5 = OpLabel
         %16 = OpLoad %13 %img
         %19 = OpImageRead %v4float %16 %18
         %21 = OpAccessChain %_ptr_Uniform_v4float %_ %int_0
               OpStore %21 %19
               OpReturn
               OpFunctionEnd

Note that the image is mediump. Note also that %19 = OpImageRead .. is decorated with RelaxedPrecision. This is incorrect according to the GLSL ES spec which defines imageLoad as returning a highp value:

highp gvec4 imageLoad(readonly IMAGE_PARAMS)

This might be a spec issue too, since it definitely makes sense for the precision of the image to apply to the result of imageLoad.

ShabbyX avatar Aug 26 '21 03:08 ShabbyX

I think that the glslang behaviour does follow the current spec [1], although the spec itself is a bit weird. The GL working group will resolve what the spec should say in internal issue opengl/GLSL#57, so I would hold off making any changes to glslang until that is resolved.

[1] In the introduction to chapter 8 "Built-In Functions" the spec actually says that texture and image functions always use the precision of the image type, and only other functions look at the explicit qualification of the return type. That leaves this case looking a bit ridiculous.

gnl21 avatar Aug 26 '21 10:08 gnl21

In the end the spec issue was resolved by clarifying that the precision of the return value of imageRead is the precision of the image. I think this can be closed, as the current behavior matches the spec.

arcady-lunarg avatar Jan 24 '23 01:01 arcady-lunarg