nir/opt_16b_tex_image: Sign extension should matter for texel buffer txf

Texel buffer could be arbitrary large, so the assumption being made in
the following comment is wrong:

 "Zero-extension (u16) and sign-extension (i16) have
  the same behavior here - txf returns 0 if bit 15 is set
  because it's out of bounds and the higher bits don't matter."

Sign extension should matter for GLSL_SAMPLER_DIM_BUF.

This fixes the case of doing texelFetch with u16 offset:

  uniform itextureBuffer s1;
  uint16_t offset = some_ssbo.offset;
  value = texelFetch(s1, offset).x;

If the offset is higher than s16 optimization incorrectly
left it as 16b.

In spirv the above glsl is translated into:

  %22 = OpLoad %ushort %21
  %23 = OpUConvert %uint %22
  %24 = OpBitcast %int %23
  %26 = OpImageFetch %v4int %16 %24

Cc: mesa-stable

Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com>
Reviewed-by: Georg Lehmann <dadschoorse@gmail.com>
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
Reviewed-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31664>
This commit is contained in:
Danylo Piliaiev 2024-10-15 17:44:34 +02:00 committed by Marge Bot
parent 5f7f33f323
commit 7b09fc98fb

View file

@ -995,9 +995,11 @@ opt_16bit_tex_srcs(nir_builder *b, nir_tex_instr *tex,
/* Zero-extension (u16) and sign-extension (i16) have
* the same behavior here - txf returns 0 if bit 15 is set
* because it's out of bounds and the higher bits don't
* matter.
* matter. With the exception of a texel buffer, which could
* be arbitrary large.
*/
if (!can_opt_16bit_src(src->ssa, src_type, false))
bool sext_matters = tex->sampler_dim == GLSL_SAMPLER_DIM_BUF;
if (!can_opt_16bit_src(src->ssa, src_type, sext_matters))
return false;
opt_srcs |= (1 << i);