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 <lionel.g.landwerlin@intel.com>
Cc: mesa-stable
Reviewed-by: Caio Oliveira <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36883>
This commit is contained in:
Lionel Landwerlin 2025-05-12 08:44:28 +03:00 committed by Marge Bot
parent a0844458b8
commit fe38fb858c
3 changed files with 55 additions and 20 deletions

View file

@ -58,9 +58,13 @@ brw_emit_single_fb_write(brw_shader &s, const brw_builder &bld,
static void static void
brw_do_emit_fb_writes(brw_shader &s, int nr_color_regions, bool replicate_alpha) 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); 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++) { for (int target = 0; target < nr_color_regions; target++) {
/* Skip over outputs that weren't written. */ /* Skip over outputs that weren't written. */
if (s.outputs[target].file == BAD_FILE) 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); src0_alpha = offset(s.outputs[0], bld, 3);
inst = brw_emit_single_fb_write(s, abld, s.outputs[target], inst = brw_emit_single_fb_write(s, abld, s.outputs[target],
s.dual_src_output, src0_alpha, target, 4, s.dual_src_output, src0_alpha,
false); 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) { if (inst == NULL) {
struct brw_wm_prog_key *key = (brw_wm_prog_key*) s.key; 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 /* 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 * 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 * coming from the BLEND_STATE structure and the HW will avoid reading
@ -90,9 +99,9 @@ brw_do_emit_fb_writes(brw_shader &s, int nr_color_regions, bool replicate_alpha)
key->alpha_to_coverage == INTEL_NEVER && key->alpha_to_coverage == INTEL_NEVER &&
!prog_data->uses_omask; !prog_data->uses_omask;
/* Even if there's no color buffers enabled, we still need to send /* Even if there's no color buffers enabled, we still need to send alpha
* alpha out the pipeline to our null renderbuffer to support * out the pipeline to our null renderbuffer to support alpha-testing,
* alpha-testing, alpha-to-coverage, and so on. * alpha-to-coverage, and so on.
*/ */
/* FINISHME: Factor out this frequently recurring pattern into a /* FINISHME: Factor out this frequently recurring pattern into a
* helper function. * helper function.
@ -104,10 +113,10 @@ brw_do_emit_fb_writes(brw_shader &s, int nr_color_regions, bool replicate_alpha)
inst = brw_emit_single_fb_write(s, bld, tmp, reg_undef, reg_undef, inst = brw_emit_single_fb_write(s, bld, tmp, reg_undef, reg_undef,
0, 4, use_null_rt); 0, 4, use_null_rt);
}
inst->src[FB_WRITE_LOGICAL_SRC_LAST_RT] = brw_imm_ud(true); 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->eot = true;
}
} }
static void static void

View file

@ -222,6 +222,9 @@ public:
* Whether the parameters of the SEND instructions are build with * Whether the parameters of the SEND instructions are build with
* NoMask (for A32 messages this covers only the surface handle, for * NoMask (for A32 messages this covers only the surface handle, for
* A64 messages this covers the load address). * 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; bool has_no_mask_send_params:1;
}; };

View file

@ -469,15 +469,19 @@ lower_fb_write_logical_send(const brw_builder &bld, brw_inst *inst,
0 /* coarse_rt_write */); 0 /* coarse_rt_write */);
brw_reg desc = brw_imm_ud(0); brw_reg desc = brw_imm_ud(0);
if (prog_data->coarse_pixel_dispatch == INTEL_ALWAYS) { if (prog_data->coarse_pixel_dispatch == INTEL_SOMETIMES &&
inst->desc |= (1 << 18); !inst->has_no_mask_send_params) {
} else if (prog_data->coarse_pixel_dispatch == INTEL_SOMETIMES) { assert(devinfo->ver >= 11);
STATIC_ASSERT(INTEL_MSAA_FLAG_COARSE_RT_WRITES == (1 << 18)); if (devinfo->ver != 11) {
const brw_builder &ubld = bld.exec_all().group(8, 0); const brw_builder &ubld =
desc = ubld.vgrf(BRW_TYPE_UD); bld.scalar_group().annotate("Coarse bit");
ubld.AND(desc, brw_dynamic_msaa_flags(prog_data), brw_reg coarse_bit =
ubld.AND(brw_dynamic_msaa_flags(prog_data),
brw_imm_ud(INTEL_MSAA_FLAG_COARSE_RT_WRITES)); brw_imm_ud(INTEL_MSAA_FLAG_COARSE_RT_WRITES));
desc = component(desc, 0); desc = component(coarse_bit, 0);
}
} else {
inst->desc |= prog_data->coarse_pixel_dispatch == INTEL_ALWAYS ? (1 << 18) : 0;
} }
uint32_t ex_desc = 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->header_size = header_size;
inst->check_tdr = true; inst->check_tdr = true;
inst->send_has_side_effects = 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 static void