From 32cce2f39755a5c42ea9f6398a77e3fb4e0eb0d6 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Mon, 5 Aug 2024 14:57:37 -0700 Subject: [PATCH] intel/brw: Set appropriate types for 16-bit sampler trailing components 16-bit SIMD8 sampler writeback messages come with a bit of padding in them, requiring us to emit a LOAD_PAYLOAD to reorganize the data into the padding-free format expected by NIR. Additionally, we may reduce the response length on the sampler messages based on which components of the (always vec4) NIR destination are actually in use. When we do that, dest_size > read_size, and the trailing components are all empty BAD_FILE registers, indicating the contents are undefined. Unfortunately, we can't ignore those trailing components entirely. In the past, we left them default-initialized, giving us a BAD_FILE register with UD type (which didn't matter, since all sampler returns were 32-bit). But with 16-bit, this was confusing the LOAD_PAYLOAD. For example, writing RGB and skipping A (without sparse) would produce read_size = 3 and dest_size = 4 and nir_dest[5] containing: nir_dest[] = We'd then call LOAD_PAYLOAD on the first 4 sources, causing it to see 3 HF's and a UD, and try to copy the full 32-bit value at the end, instead of 16-bits of pad like we intended. This meant it would overflow the destination register's size, triggering validation errors. Thanks to Ian Romanick for noticing this, writing a test, and also coming up with a nearly identical fix. Fixes: 0116430d394 ("intel/brw: Handle 16-bit sampler return payloads") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11617 References: https://gitlab.freedesktop.org/mesa/crucible/-/merge_requests/152 Reviewed-by: Ian Romanick Reviewed-by: Sushma Venkatesh Reddy Part-of: --- src/intel/compiler/brw_fs_nir.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/intel/compiler/brw_fs_nir.cpp b/src/intel/compiler/brw_fs_nir.cpp index d40414a4e51..74c062fbc98 100644 --- a/src/intel/compiler/brw_fs_nir.cpp +++ b/src/intel/compiler/brw_fs_nir.cpp @@ -8710,6 +8710,9 @@ fs_nir_emit_texture(nir_to_brw_state &ntb, for (unsigned i = 0; i < read_size; i++) nir_dest[i] = offset(dst, bld, (is_simd8_16bit ? 2 : 1) * i); + for (unsigned i = read_size; i < dest_size; i++) + nir_dest[i].type = dst.type; + if (instr->op == nir_texop_query_levels) { /* # levels is in .w */ if (devinfo->ver == 9) {