From 6d7f2e3fbd2054bb83d8a82cd245c581af1a5558 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 18 Feb 2026 18:50:35 +0100 Subject: [PATCH] ac/nir: fix writemask for dual source blending on GFX11+ This should definitely be an OR operation if MRT0 and MRT1 don't write the same channels. This also requires to set the writemask manually because when it's 0 (in case a dual-source output is missing), the intrinsic computes the mask itself with the number of components. No fossils-db changes on NAVI33. Fixes: 45d8cd037a8 ("ac/nir: rewrite ac_nir_lower_ps epilog to fix dual src blending with mono PS") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/14878 Signed-off-by: Samuel Pitoiset (cherry picked from commit 2eb9420061334230afbd45861b8d40860f1e4ec1) Part-of: --- .pick_status.json | 2 +- src/amd/common/nir/ac_nir_lower_ps_late.c | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 562ac4b9593..a13175b8b2e 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -384,7 +384,7 @@ "description": "ac/nir: fix writemask for dual source blending on GFX11+", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "45d8cd037a83ae99f99a551be1b565f14cd598ec", "notes": null diff --git a/src/amd/common/nir/ac_nir_lower_ps_late.c b/src/amd/common/nir/ac_nir_lower_ps_late.c index 72754fe160e..a5d7d47f207 100644 --- a/src/amd/common/nir/ac_nir_lower_ps_late.c +++ b/src/amd/common/nir/ac_nir_lower_ps_late.c @@ -443,10 +443,14 @@ emit_ps_color_export(nir_builder *b, lower_ps_state *s, unsigned output_index, u } } - s->exp[s->exp_num++] = nir_export_amd(b, nir_vec(b, outputs, 4), - .base = target, - .write_mask = write_mask, - .flags = flags); + nir_intrinsic_instr *exp = nir_export_amd(b, nir_vec(b, outputs, 4), + .base = target, + .flags = flags); + + /* Set the writemask explicitly because write_mask=0 means full write mask. */ + nir_intrinsic_set_write_mask(exp, write_mask); + + s->exp[s->exp_num++] = exp; return true; } @@ -483,7 +487,7 @@ emit_ps_dual_src_blend_swizzle(nir_builder *b, lower_ps_state *s, unsigned first uint32_t mrt0_write_mask = nir_intrinsic_write_mask(mrt0_exp); uint32_t mrt1_write_mask = nir_intrinsic_write_mask(mrt1_exp); - uint32_t write_mask = mrt0_write_mask & mrt1_write_mask; + uint32_t write_mask = mrt0_write_mask | mrt1_write_mask; nir_def *mrt0_arg = mrt0_exp->src[0].ssa; nir_def *mrt1_arg = mrt1_exp->src[0].ssa;