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>
(cherry picked from commit 7b09fc98fb)
This commit is contained in:
Danylo Piliaiev 2024-10-15 17:44:34 +02:00 committed by Eric Engestrom
parent bde3e18d65
commit 5b50c4e9a1
2 changed files with 5 additions and 3 deletions

View file

@ -4,7 +4,7 @@
"description": "nir/opt_16b_tex_image: Sign extension should matter for texel buffer txf",
"nominated": true,
"nomination_type": 0,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null,
"notes": null

View file

@ -994,9 +994,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);