From 7b09fc98fb60becde7435b2303f7dd329937f6cb Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Tue, 15 Oct 2024 17:44:34 +0200 Subject: [PATCH] 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 Reviewed-by: Georg Lehmann Reviewed-by: Connor Abbott Reviewed-by: Rob Clark Part-of: --- src/compiler/nir/nir_lower_mediump.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/compiler/nir/nir_lower_mediump.c b/src/compiler/nir/nir_lower_mediump.c index 7d51a6d7e48..1c8df13dd0d 100644 --- a/src/compiler/nir/nir_lower_mediump.c +++ b/src/compiler/nir/nir_lower_mediump.c @@ -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);