radeonsi: fix a nasty bug in si_pm4.c

If you did:
  si_pm4_set_reg(pm4, reg, val0);
  si_pm4_cmd_add(pm4, val1);
  si_pm4 set_reg(pm4, reg + 4, val1);

it wrote val0 to reg, val1 to reg + 4, and val2 to reg + 8.

This fixes it by clearing last_opcode in si_pm4_cmd_add, so that
si_pm4_set_reg doesn't try to combine set_reg calls across si_pm4_cmd_add.

Fixes: da78d50bc8 - radeonsi: make si_pm4_cmd_begin/end static and simplify all usages

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7721>
(cherry picked from commit 0d4f1dcd15)
This commit is contained in:
Marek Olšák 2020-11-22 23:19:44 -05:00 committed by Dylan Baker
parent 2f493068ec
commit cd94b261fc
2 changed files with 6 additions and 3 deletions

View file

@ -958,7 +958,7 @@
"description": "radeonsi: fix a nasty bug in si_pm4.c", "description": "radeonsi: fix a nasty bug in si_pm4.c",
"nominated": true, "nominated": true,
"nomination_type": 1, "nomination_type": 1,
"resolution": 0, "resolution": 1,
"master_sha": null, "master_sha": null,
"because_sha": "da78d50bc87ef5db846a942664094b6299cd1888" "because_sha": "da78d50bc87ef5db846a942664094b6299cd1888"
}, },

View file

@ -38,6 +38,7 @@ void si_pm4_cmd_add(struct si_pm4_state *state, uint32_t dw)
{ {
assert(state->ndw < SI_PM4_MAX_DW); assert(state->ndw < SI_PM4_MAX_DW);
state->pm4[state->ndw++] = dw; state->pm4[state->ndw++] = dw;
state->last_opcode = -1;
} }
static void si_pm4_cmd_end(struct si_pm4_state *state, bool predicate) static void si_pm4_cmd_end(struct si_pm4_state *state, bool predicate)
@ -76,13 +77,15 @@ void si_pm4_set_reg(struct si_pm4_state *state, unsigned reg, uint32_t val)
reg >>= 2; reg >>= 2;
assert(state->ndw + 2 <= SI_PM4_MAX_DW);
if (opcode != state->last_opcode || reg != (state->last_reg + 1)) { if (opcode != state->last_opcode || reg != (state->last_reg + 1)) {
si_pm4_cmd_begin(state, opcode); si_pm4_cmd_begin(state, opcode);
si_pm4_cmd_add(state, reg); state->pm4[state->ndw++] = reg;
} }
state->last_reg = reg; state->last_reg = reg;
si_pm4_cmd_add(state, val); state->pm4[state->ndw++] = val;
si_pm4_cmd_end(state, false); si_pm4_cmd_end(state, false);
} }