From 730bbfc804bba4cc1637073acc5f2879d9860bb4 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Fri, 9 Jan 2026 09:43:21 +0200 Subject: [PATCH] brw: fix derivatives on non 32bit floats Signed-off-by: Lionel Landwerlin Cc: mesa-stable Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/14600 Meh'd-by: Alyssa Rosenzweig (cherry picked from commit 081c5bc6a565c2bbc9cdd19a1b1584c574fabcbd) Part-of: --- .pick_status.json | 2 +- src/intel/compiler/brw/brw_from_nir.cpp | 32 +++++++++++++++---------- src/intel/compiler/brw/brw_reg_type.h | 10 ++++++++ 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index a9432e3be75..b24a4cc3379 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -4004,7 +4004,7 @@ "description": "brw: fix derivatives on non 32bit floats", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/intel/compiler/brw/brw_from_nir.cpp b/src/intel/compiler/brw/brw_from_nir.cpp index 4e583685235..d6ab1841d3d 100644 --- a/src/intel/compiler/brw/brw_from_nir.cpp +++ b/src/intel/compiler/brw/brw_from_nir.cpp @@ -6532,24 +6532,32 @@ brw_from_nir_emit_intrinsic(nir_to_brw_state &ntb, case nir_intrinsic_load_subgroup_lt_mask: UNREACHABLE("not reached"); - case nir_intrinsic_ddx_fine: - bld.emit(FS_OPCODE_DDX_FINE, retype(dest, BRW_TYPE_F), - retype(get_nir_src(ntb, instr->src[0], 0), BRW_TYPE_F)); + case nir_intrinsic_ddx_fine: { + enum brw_reg_type type = brw_float_type_for_reg_type(dest.type); + bld.emit(FS_OPCODE_DDX_FINE, retype(dest, type), + retype(get_nir_src(ntb, instr->src[0], 0), type)); break; + } case nir_intrinsic_ddx: - case nir_intrinsic_ddx_coarse: - bld.emit(FS_OPCODE_DDX_COARSE, retype(dest, BRW_TYPE_F), - retype(get_nir_src(ntb, instr->src[0], 0), BRW_TYPE_F)); + case nir_intrinsic_ddx_coarse: { + enum brw_reg_type type = brw_float_type_for_reg_type(dest.type); + bld.emit(FS_OPCODE_DDX_COARSE, retype(dest, type), + retype(get_nir_src(ntb, instr->src[0], 0), type)); break; - case nir_intrinsic_ddy_fine: - bld.emit(FS_OPCODE_DDY_FINE, retype(dest, BRW_TYPE_F), - retype(get_nir_src(ntb, instr->src[0], 0), BRW_TYPE_F)); + } + case nir_intrinsic_ddy_fine: { + enum brw_reg_type type = brw_float_type_for_reg_type(dest.type); + bld.emit(FS_OPCODE_DDY_FINE, retype(dest, type), + retype(get_nir_src(ntb, instr->src[0], 0), type)); break; + } case nir_intrinsic_ddy: - case nir_intrinsic_ddy_coarse: - bld.emit(FS_OPCODE_DDY_COARSE, retype(dest, BRW_TYPE_F), - retype(get_nir_src(ntb, instr->src[0], 0), BRW_TYPE_F)); + case nir_intrinsic_ddy_coarse: { + enum brw_reg_type type = brw_float_type_for_reg_type(dest.type); + bld.emit(FS_OPCODE_DDY_COARSE, retype(dest, type), + retype(get_nir_src(ntb, instr->src[0], 0), type)); break; + } case nir_intrinsic_vote_any: case nir_intrinsic_vote_all: diff --git a/src/intel/compiler/brw/brw_reg_type.h b/src/intel/compiler/brw/brw_reg_type.h index 71c83b0c929..82c71a7b8e6 100644 --- a/src/intel/compiler/brw/brw_reg_type.h +++ b/src/intel/compiler/brw/brw_reg_type.h @@ -167,6 +167,16 @@ brw_type_with_size(enum brw_reg_type ref_type, unsigned bit_size) return (enum brw_reg_type)(base_field | size_field); } +static inline enum brw_reg_type +brw_float_type_for_reg_type(enum brw_reg_type ref_type) +{ + unsigned bit_size = brw_type_size_bits(ref_type); + assert(bit_size == 16 || bit_size == 32 || bit_size == 64); + unsigned base_field = BRW_TYPE_F & BRW_TYPE_BASE_MASK; + unsigned size_field = ffs(bit_size) - 4; + return (enum brw_reg_type)(base_field | size_field); +} + /** * Returns the larger of two types (i.e. W and D -> D). *