brw: fix derivatives on non 32bit floats

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: mesa-stable
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/14600
Meh'd-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>

(cherry picked from commit 081c5bc6a5)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39462>
This commit is contained in:
Lionel Landwerlin 2026-01-09 09:43:21 +02:00 committed by Dylan Baker
parent b4c2042b06
commit 730bbfc804
3 changed files with 31 additions and 13 deletions

View file

@ -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

View file

@ -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:

View file

@ -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).
*