ir3: Schedule (eolm)/(eogm)
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

They have the same rules for placement as (eq).

Blob places them right after the last cat5/cat6 instruction if
possible, we do the same for now.

Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com>
Co-authored-by: Job Noorman <jnoorman@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31885>
This commit is contained in:
Danylo Piliaiev 2026-01-02 14:08:49 +01:00 committed by Job Noorman
parent 29643ac2dd
commit 96d19c250c
3 changed files with 51 additions and 0 deletions

View file

@ -268,6 +268,7 @@ ir3_compiler_create(struct fd_device *dev, const struct fd_dev_id *dev_id,
compiler->has_alias_rt = dev_info->props.has_alias_rt;
compiler->mergedregs = true;
compiler->has_sel_b_fneg = dev_info->props.has_sel_b_fneg;
compiler->has_eolm_eogm = dev_info->props.has_eolm_eogm;
compiler->has_alias_tex = (compiler->gen >= 7);

View file

@ -316,6 +316,8 @@ struct ir3_compiler {
bool has_sel_b_fneg;
bool has_eolm_eogm;
struct {
/* The number of cycles needed for the result of one ALU operation to be
* available to another ALU operation. Only valid when the halfness of the

View file

@ -2052,6 +2052,46 @@ helper_sched(struct ir3_legalize_ctx *ctx, struct ir3 *ir,
}
}
static bool
needs_eolm(struct ir3_instruction *instr)
{
switch (instr->opc) {
case OPC_STL:
case OPC_LDL:
case OPC_STLW:
case OPC_LDLW:
case OPC_ATOMIC_ADD:
case OPC_ATOMIC_SUB:
case OPC_ATOMIC_XCHG:
case OPC_ATOMIC_INC:
case OPC_ATOMIC_DEC:
case OPC_ATOMIC_CMPXCHG:
case OPC_ATOMIC_MIN:
case OPC_ATOMIC_MAX:
case OPC_ATOMIC_AND:
case OPC_ATOMIC_OR:
case OPC_ATOMIC_XOR:
return true;
default:
return false;
}
}
static bool
needs_eogm(struct ir3_instruction *instr)
{
return opc_cat(instr->opc) == 5 || opc_cat(instr->opc) == 6;
}
static bool
is_cheap_for_eolm_eogm(struct ir3_instruction *instr)
{
/* Blob inserts these flags as soon as possible, so consider all instructions
* expensive.
*/
return false;
}
struct ir3_last_block_data {
/* Whether a read will be done on a register at a later point, it is
* considered safe to set (last) when this is false for a particular
@ -2526,6 +2566,14 @@ ir3_legalize(struct ir3 *ir, struct ir3_shader_variant *so, int *max_bary)
if (so->type == MESA_SHADER_FRAGMENT)
kill_sched(ir, so);
if ((so->type == MESA_SHADER_FRAGMENT || so->type == MESA_SHADER_COMPUTE) &&
so->compiler->has_eolm_eogm) {
feature_usage_sched(ctx, ir, so, needs_eolm, is_cheap_for_eolm_eogm,
IR3_INSTR_EOLM);
feature_usage_sched(ctx, ir, so, needs_eogm, is_cheap_for_eolm_eogm,
IR3_INSTR_EOGM);
}
/* TODO: does (eq) exist before a6xx? */
if (so->type == MESA_SHADER_FRAGMENT && so->need_pixlod &&
so->compiler->gen >= 6) {