From fe38fb858c7ed31be89ea60decd049c9919b3fbd Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Mon, 12 May 2025 08:44:28 +0300 Subject: [PATCH] brw: workaround broken indirect RT messages on Gfx11 Unfortunately we cannot use the indirect descriptor on Gfx11, it appears to just drop writes. Other platforms appear to be fine. Signed-off-by: Lionel Landwerlin Cc: mesa-stable Reviewed-by: Caio Oliveira Part-of: --- src/intel/compiler/brw_compile_fs.cpp | 31 +++++++++----- src/intel/compiler/brw_inst.h | 3 ++ .../compiler/brw_lower_logical_sends.cpp | 41 +++++++++++++++---- 3 files changed, 55 insertions(+), 20 deletions(-) diff --git a/src/intel/compiler/brw_compile_fs.cpp b/src/intel/compiler/brw_compile_fs.cpp index 9bbe63566ef..ebf2b544c85 100644 --- a/src/intel/compiler/brw_compile_fs.cpp +++ b/src/intel/compiler/brw_compile_fs.cpp @@ -58,9 +58,13 @@ brw_emit_single_fb_write(brw_shader &s, const brw_builder &bld, static void brw_do_emit_fb_writes(brw_shader &s, int nr_color_regions, bool replicate_alpha) { + struct brw_wm_prog_data *prog_data = brw_wm_prog_data(s.prog_data); const brw_builder bld = brw_builder(&s); - brw_inst *inst = NULL; + const bool double_rt_writes = s.devinfo->ver == 11 && + prog_data->coarse_pixel_dispatch == INTEL_SOMETIMES; + + brw_inst *inst = NULL; for (int target = 0; target < nr_color_regions; target++) { /* Skip over outputs that weren't written. */ if (s.outputs[target].file == BAD_FILE) @@ -74,13 +78,18 @@ brw_do_emit_fb_writes(brw_shader &s, int nr_color_regions, bool replicate_alpha) src0_alpha = offset(s.outputs[0], bld, 3); inst = brw_emit_single_fb_write(s, abld, s.outputs[target], - s.dual_src_output, src0_alpha, target, 4, - false); + s.dual_src_output, src0_alpha, + target, 4, false); + } + + bool flag_dummy_message = inst && double_rt_writes; + if (inst) { + inst->src[FB_WRITE_LOGICAL_SRC_LAST_RT] = brw_imm_ud(true); + inst->eot = true; } if (inst == NULL) { struct brw_wm_prog_key *key = (brw_wm_prog_key*) s.key; - struct brw_wm_prog_data *prog_data = brw_wm_prog_data(s.prog_data); /* Disable null_rt if any non color output is written or if * alpha_to_coverage can be enabled. Since the alpha_to_coverage bit is * coming from the BLEND_STATE structure and the HW will avoid reading @@ -90,24 +99,24 @@ brw_do_emit_fb_writes(brw_shader &s, int nr_color_regions, bool replicate_alpha) key->alpha_to_coverage == INTEL_NEVER && !prog_data->uses_omask; - /* Even if there's no color buffers enabled, we still need to send - * alpha out the pipeline to our null renderbuffer to support - * alpha-testing, alpha-to-coverage, and so on. + /* Even if there's no color buffers enabled, we still need to send alpha + * out the pipeline to our null renderbuffer to support alpha-testing, + * alpha-to-coverage, and so on. */ /* FINISHME: Factor out this frequently recurring pattern into a * helper function. */ const brw_reg srcs[] = { reg_undef, reg_undef, - reg_undef, offset(s.outputs[0], bld, 3) }; + reg_undef, offset(s.outputs[0], bld, 3) }; const brw_reg tmp = bld.vgrf(BRW_TYPE_UD, 4); bld.LOAD_PAYLOAD(tmp, srcs, 4, 0); inst = brw_emit_single_fb_write(s, bld, tmp, reg_undef, reg_undef, 0, 4, use_null_rt); + inst->src[FB_WRITE_LOGICAL_SRC_LAST_RT] = brw_imm_ud(true); + inst->has_no_mask_send_params = flag_dummy_message; + inst->eot = true; } - - inst->src[FB_WRITE_LOGICAL_SRC_LAST_RT] = brw_imm_ud(true); - inst->eot = true; } static void diff --git a/src/intel/compiler/brw_inst.h b/src/intel/compiler/brw_inst.h index 2240929eddd..39001bbac3a 100644 --- a/src/intel/compiler/brw_inst.h +++ b/src/intel/compiler/brw_inst.h @@ -222,6 +222,9 @@ public: * Whether the parameters of the SEND instructions are build with * NoMask (for A32 messages this covers only the surface handle, for * A64 messages this covers the load address). + * + * Also used to signal a dummy render target SEND message that is + * never executed. */ bool has_no_mask_send_params:1; }; diff --git a/src/intel/compiler/brw_lower_logical_sends.cpp b/src/intel/compiler/brw_lower_logical_sends.cpp index 16a5f0311c0..0d0bf7f9313 100644 --- a/src/intel/compiler/brw_lower_logical_sends.cpp +++ b/src/intel/compiler/brw_lower_logical_sends.cpp @@ -469,15 +469,19 @@ lower_fb_write_logical_send(const brw_builder &bld, brw_inst *inst, 0 /* coarse_rt_write */); brw_reg desc = brw_imm_ud(0); - if (prog_data->coarse_pixel_dispatch == INTEL_ALWAYS) { - inst->desc |= (1 << 18); - } else if (prog_data->coarse_pixel_dispatch == INTEL_SOMETIMES) { - STATIC_ASSERT(INTEL_MSAA_FLAG_COARSE_RT_WRITES == (1 << 18)); - const brw_builder &ubld = bld.exec_all().group(8, 0); - desc = ubld.vgrf(BRW_TYPE_UD); - ubld.AND(desc, brw_dynamic_msaa_flags(prog_data), - brw_imm_ud(INTEL_MSAA_FLAG_COARSE_RT_WRITES)); - desc = component(desc, 0); + if (prog_data->coarse_pixel_dispatch == INTEL_SOMETIMES && + !inst->has_no_mask_send_params) { + assert(devinfo->ver >= 11); + if (devinfo->ver != 11) { + const brw_builder &ubld = + bld.scalar_group().annotate("Coarse bit"); + brw_reg coarse_bit = + ubld.AND(brw_dynamic_msaa_flags(prog_data), + brw_imm_ud(INTEL_MSAA_FLAG_COARSE_RT_WRITES)); + desc = component(coarse_bit, 0); + } + } else { + inst->desc |= prog_data->coarse_pixel_dispatch == INTEL_ALWAYS ? (1 << 18) : 0; } uint32_t ex_desc = 0; @@ -510,6 +514,25 @@ lower_fb_write_logical_send(const brw_builder &bld, brw_inst *inst, inst->header_size = header_size; inst->check_tdr = true; inst->send_has_side_effects = true; + + const bool double_rt_writes = devinfo->ver == 11 && + prog_data->coarse_pixel_dispatch == INTEL_SOMETIMES; + if (double_rt_writes) { + brw_check_dynamic_msaa_flag(bld, prog_data, + INTEL_MSAA_FLAG_COARSE_RT_WRITES); + bld.IF(BRW_PREDICATE_NORMAL); + { + brw_inst *coarse_inst = bld.emit(*inst); + coarse_inst->desc |= brw_fb_write_desc(devinfo, target, msg_ctl, last_rt, + true); + } + bld.ELSE(); + { + bld.emit(*inst); + } + bld.ENDIF(); + inst->remove(); + } } static void