mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-06 21:50:11 +01:00
ir3/legalize: fix (eq) scheduling for sam.s2en
sam.s2en uses the first src for its samp/tex while the coordinates (for
which derivatives need to be calculated) are in the second src. We used
to unconditionally track needed helpers for the first src causing (eq)
to potentially get scheduled too early for sam.s2en. Fix this by using
the second src for sam.s2en.
Fixes frame instability in Metro Exodus.
Signed-off-by: Job Noorman <jnoorman@igalia.com>
Fixes: 29f8277952 ("ir3/legalize: schedule (eq) more accurately")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38992>
This commit is contained in:
parent
3584bac0b2
commit
2ed37033a0
2 changed files with 28 additions and 4 deletions
|
|
@ -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) \
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue