diff --git a/src/asahi/lib/agx_nir_lower_texture.c b/src/asahi/lib/agx_nir_lower_texture.c index f1b6b696f9f..ee2d29a1036 100644 --- a/src/asahi/lib/agx_nir_lower_texture.c +++ b/src/asahi/lib/agx_nir_lower_texture.c @@ -134,23 +134,21 @@ lower_buffer_texture(nir_builder *b, nir_tex_instr *tex) { nir_def *coord = nir_steal_tex_src(tex, nir_tex_src_coord); - /* The OpenGL ES 3.2 specification says on page 187: - * - * When a buffer texture is accessed in a shader, the results of a texel - * fetch are undefined if the specified texel coordinate is negative, or - * greater than or equal to the clamped number of texels in the texture - * image. - * - * However, faulting would be undesirable for robustness, so clamp. + /* Map out-of-bounds indices to out-of-bounds coordinates for robustness2 + * semantics from the hardware. */ nir_def *size = nir_get_texture_size(b, tex); - coord = nir_umin(b, coord, nir_iadd_imm(b, size, -1)); + nir_def *oob = nir_uge(b, coord, size); + coord = nir_bcsel(b, oob, nir_imm_int(b, -1), coord); nir_def *desc = texture_descriptor_ptr(b, tex); bool is_float = nir_alu_type_get_base_type(tex->dest_type) == nir_type_float; - /* Lower RGB32 reads if the format requires */ - nir_if *nif = nir_push_if(b, libagx_texture_is_rgb32(b, desc)); + /* Lower RGB32 reads if the format requires. If we are out-of-bounds, we use + * the hardware path so we get a zero texel. + */ + nir_if *nif = nir_push_if( + b, nir_iand(b, libagx_texture_is_rgb32(b, desc), nir_inot(b, oob))); nir_def *rgb32 = nir_trim_vector( b, libagx_texture_load_rgb32(b, desc, coord, nir_imm_bool(b, is_float)),