brw: enable register allocation to deal with multiple EOTs

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Caio Oliveira <caio.oliveira@intel.com>
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36883>
This commit is contained in:
Lionel Landwerlin 2025-05-12 12:38:35 +03:00 committed by Marge Bot
parent 325de7fe7e
commit c4c7ff3f8f

View file

@ -276,6 +276,8 @@ public:
spill_vgrf_ip = NULL; spill_vgrf_ip = NULL;
spill_vgrf_ip_alloc = 0; spill_vgrf_ip_alloc = 0;
spill_node_count = 0; spill_node_count = 0;
eot_reg = -1;
} }
~brw_reg_alloc() ~brw_reg_alloc()
@ -319,6 +321,8 @@ private:
set *spill_insts; set *spill_insts;
int eot_reg;
ra_graph *g; ra_graph *g;
bool have_spill_costs; bool have_spill_costs;
@ -634,26 +638,43 @@ brw_reg_alloc::setup_inst_interference(const brw_inst *inst)
*/ */
if (inst->eot && devinfo->ver < 30) { if (inst->eot && devinfo->ver < 30) {
assert(inst->opcode == SHADER_OPCODE_SEND); assert(inst->opcode == SHADER_OPCODE_SEND);
const int vgrf = inst->src[SEND_SRC_PAYLOAD1].nr; const brw_reg srcs[2] = {
const int size = DIV_ROUND_UP(fs->alloc.sizes[vgrf], reg_unit(devinfo)); inst->src[SEND_SRC_PAYLOAD1],
int reg = BRW_MAX_GRF - size; inst->ex_mlen > 0 ? inst->src[SEND_SRC_PAYLOAD2] : brw_reg(),
};
const unsigned sizes[2] = {
DIV_ROUND_UP(fs->alloc.sizes[srcs[0].nr], reg_unit(devinfo)),
DIV_ROUND_UP(srcs[1].file != BAD_FILE ?
fs->alloc.sizes[srcs[1].nr] : 0, reg_unit(devinfo)),
};
int regs[2] = { BRW_MAX_GRF, BRW_MAX_GRF };
/* If we haven´t yet allocated a register for the EOT sources, allocate
* one large enough. Otherwise the assumption is that the backend
* generates EOT messages that consummes the same amount of source
* register so we can reuse the existing allocation.
*/
regs[0] = BRW_MAX_GRF - sizes[0];
if (grf127_send_hack_node >= 0) { if (grf127_send_hack_node >= 0) {
/* Avoid r127 which might be unusable if the node was previously /* Avoid r127 which might be unusable if the node was previously
* written by a SIMD8 SEND message with source/destination overlap. * written by a SIMD8 SEND message with source/destination overlap.
*/ */
reg--; regs[0]--;
}
assert(regs[0] >= 112);
ra_set_node_reg(g, first_vgrf_node + srcs[0].nr, regs[0]);
if (sizes[1] > 0) {
regs[1] = regs[0] - sizes[1];
assert(regs[1] >= 112);
ra_set_node_reg(g, first_vgrf_node + srcs[1].nr, regs[1]);
} }
assert(reg >= 112); /* All the EOT messages should have the same amount of payload as we
ra_set_node_reg(g, first_vgrf_node + vgrf, reg); * only use this for last render target write on Gfx11.
*/
if (inst->ex_mlen > 0) { assert(eot_reg == -1 || eot_reg == MIN2(regs[0], regs[1]));
const int vgrf = inst->src[SEND_SRC_PAYLOAD2].nr; eot_reg = MIN2(regs[0], regs[1]);
reg -= DIV_ROUND_UP(fs->alloc.sizes[vgrf], reg_unit(devinfo));
assert(reg >= 112);
ra_set_node_reg(g, first_vgrf_node + vgrf, reg);
}
} }
} }