diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index b22229deccb..875d77052fe 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -1923,6 +1923,18 @@ ir3_src_is_first_in_group(struct ir3_register *src) #define foreach_src_in_alias_group(__alias, __instr, __start) \ foreach_src_in_alias_group_n (__alias, __alias_n, __instr, __start) +static inline unsigned +ir3_alias_group_size(struct ir3_instruction *instr, unsigned src_n) +{ + unsigned size = 0; + + foreach_src_in_alias_group (src, instr, src_n) { + size++; + } + + return size; +} + /* iterator for an instructions's destinations (reg), also returns dst #: */ #define foreach_dst_n(__dstreg, __n, __instr) \ if ((__instr)->dsts_count) \ diff --git a/src/freedreno/ir3/ir3_legalize.c b/src/freedreno/ir3/ir3_legalize.c index e05de9df672..696d9e0ff30 100644 --- a/src/freedreno/ir3/ir3_legalize.c +++ b/src/freedreno/ir3/ir3_legalize.c @@ -1653,10 +1653,21 @@ instr_mark_helpers(struct ir3_mark_helpers_data *bd, * that we can keep them enabled until it is written. */ unsigned nsrcs; + unsigned first_src_n = 0; if (instr->opc == OPC_SAM || instr->opc == OPC_SAMB || instr->opc == OPC_GETLOD) { nsrcs = (instr->flags & IR3_INSTR_3D) ? 3 : 2; + + /* sam.s2en has the samp/tex in the first src; skip over it. */ + if (instr->flags & IR3_INSTR_S2EN) { + if (instr->srcs[0]->flags & IR3_REG_FIRST_ALIAS) { + assert(ir3_alias_group_size(instr, 0) == 2); + first_src_n = 2; + } else { + first_src_n = 1; + } + } } else { /* dsx/dsy: derive the number of sources from the dst wrmask since the * src itself may use aliases. @@ -1664,10 +1675,10 @@ instr_mark_helpers(struct ir3_mark_helpers_data *bd, nsrcs = util_last_bit(instr->dsts[0]->wrmask); } - if (instr->srcs[0]->flags & IR3_REG_FIRST_ALIAS) { - assert(nsrcs <= instr->srcs_count); + if (instr->srcs[first_src_n]->flags & IR3_REG_FIRST_ALIAS) { + assert(first_src_n + nsrcs <= instr->srcs_count); - for (unsigned i = 0; i < nsrcs; i++) { + for (unsigned i = first_src_n; i < first_src_n + nsrcs; i++) { struct ir3_register *src = instr->srcs[i]; if (is_reg_gpr(src)) { @@ -1675,7 +1686,8 @@ instr_mark_helpers(struct ir3_mark_helpers_data *bd, } } } else { - regmask_set_masked(&bd->needs_helpers, instr->srcs[0], MASK(nsrcs)); + regmask_set_masked(&bd->needs_helpers, instr->srcs[first_src_n], + MASK(nsrcs)); } break;