diff options
author | Marek Olšák <marek.olsak@amd.com> | 2020-11-22 23:19:44 -0500 |
---|---|---|
committer | Dylan Baker <dylan.c.baker@intel.com> | 2020-12-02 15:08:40 -0800 |
commit | 2b9da404c1a8c1b6938a18d5452be7a213647faa (patch) | |
tree | 194336f24ab9f30e51926cddf56bd2f9872638d7 | |
parent | b7659c5ed766b3494b6f06339505cd755d2f1bd0 (diff) |
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: da78d50bc87 - 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 0d4f1dcd155be753ff49cd763be916cf701cda25)
-rw-r--r-- | .pick_status.json | 2 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_pm4.c | 7 |
2 files changed, 6 insertions, 3 deletions
diff --git a/.pick_status.json b/.pick_status.json index 3f79954013c..f45ec88836e 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -733,7 +733,7 @@ "description": "radeonsi: fix a nasty bug in si_pm4.c", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "master_sha": null, "because_sha": "da78d50bc87ef5db846a942664094b6299cd1888" }, diff --git a/src/gallium/drivers/radeonsi/si_pm4.c b/src/gallium/drivers/radeonsi/si_pm4.c index d1d003af1d4..e4ddbc8d59b 100644 --- a/src/gallium/drivers/radeonsi/si_pm4.c +++ b/src/gallium/drivers/radeonsi/si_pm4.c @@ -38,6 +38,7 @@ void si_pm4_cmd_add(struct si_pm4_state *state, uint32_t dw) { assert(state->ndw < SI_PM4_MAX_DW); state->pm4[state->ndw++] = dw; + state->last_opcode = -1; } 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; + assert(state->ndw + 2 <= SI_PM4_MAX_DW); + if (opcode != state->last_opcode || reg != (state->last_reg + 1)) { si_pm4_cmd_begin(state, opcode); - si_pm4_cmd_add(state, reg); + state->pm4[state->ndw++] = reg; } state->last_reg = reg; - si_pm4_cmd_add(state, val); + state->pm4[state->ndw++] = val; si_pm4_cmd_end(state, false); } |