From ac059f1c238ff8f9a6a1852ec9c89858e7276700 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 25 Jan 2017 00:09:24 +0100 Subject: [PATCH] radeonsi: use a bitmask for looping over dirty PM4 states MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit also move it to draw_vbo, because it should be 0 in most cases Reviewed-by: Nicolai Hähnle --- src/gallium/drivers/radeonsi/si_pipe.h | 1 + src/gallium/drivers/radeonsi/si_pm4.c | 16 +--------------- src/gallium/drivers/radeonsi/si_pm4.h | 1 - src/gallium/drivers/radeonsi/si_state.h | 3 +++ src/gallium/drivers/radeonsi/si_state_draw.c | 17 +++++++++++++++-- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index b6474e6c38c..da6aca123d1 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -228,6 +228,7 @@ struct si_context { union si_state_atoms atoms; unsigned dirty_atoms; /* mask */ /* PM4 states (precomputed immutable states) */ + unsigned dirty_states; union si_state queued; union si_state emitted; diff --git a/src/gallium/drivers/radeonsi/si_pm4.c b/src/gallium/drivers/radeonsi/si_pm4.c index 97b6799f361..2680439d35e 100644 --- a/src/gallium/drivers/radeonsi/si_pm4.c +++ b/src/gallium/drivers/radeonsi/si_pm4.c @@ -29,8 +29,6 @@ #include "si_pipe.h" #include "sid.h" -#define NUMBER_OF_STATES (sizeof(union si_state) / sizeof(struct si_pm4_state *)) - void si_pm4_cmd_begin(struct si_pm4_state *state, unsigned opcode) { state->last_opcode = opcode; @@ -157,22 +155,10 @@ void si_pm4_emit(struct si_context *sctx, struct si_pm4_state *state) } } -void si_pm4_emit_dirty(struct si_context *sctx) -{ - for (int i = 0; i < NUMBER_OF_STATES; ++i) { - struct si_pm4_state *state = sctx->queued.array[i]; - - if (!state || sctx->emitted.array[i] == state) - continue; - - si_pm4_emit(sctx, state); - sctx->emitted.array[i] = state; - } -} - void si_pm4_reset_emitted(struct si_context *sctx) { memset(&sctx->emitted, 0, sizeof(sctx->emitted)); + sctx->dirty_states |= u_bit_consecutive(0, SI_NUM_STATES); } void si_pm4_upload_indirect_buffer(struct si_context *sctx, diff --git a/src/gallium/drivers/radeonsi/si_pm4.h b/src/gallium/drivers/radeonsi/si_pm4.h index 9b02a8025a6..106abe1ec7d 100644 --- a/src/gallium/drivers/radeonsi/si_pm4.h +++ b/src/gallium/drivers/radeonsi/si_pm4.h @@ -78,7 +78,6 @@ void si_pm4_free_state(struct si_context *sctx, unsigned idx); void si_pm4_emit(struct si_context *sctx, struct si_pm4_state *state); -void si_pm4_emit_dirty(struct si_context *sctx); void si_pm4_reset_emitted(struct si_context *sctx); #endif diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index 915a8eb8e53..bdcfb5b2a3f 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -129,6 +129,8 @@ union si_state { struct si_pm4_state *array[0]; }; +#define SI_NUM_STATES (sizeof(union si_state) / sizeof(struct si_pm4_state *)) + union si_state_atoms { struct { /* The order matters. */ @@ -267,6 +269,7 @@ struct si_buffer_resources { #define si_pm4_bind_state(sctx, member, value) \ do { \ (sctx)->queued.named.member = (value); \ + (sctx)->dirty_states |= 1 << si_pm4_block_idx(member); \ } while(0) #define si_pm4_delete_state(sctx, member, value) \ diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index 0374841f2b8..f0bd9304ea0 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -1122,7 +1122,7 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) if (sctx->b.flags) si_emit_cache_flush(sctx); - /* Emit states. */ + /* Emit state atoms. */ mask = sctx->dirty_atoms; while (mask) { struct r600_atom *atom = sctx->atoms.array[u_bit_scan(&mask)]; @@ -1131,7 +1131,20 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) } sctx->dirty_atoms = 0; - si_pm4_emit_dirty(sctx); + /* Emit states. */ + mask = sctx->dirty_states; + while (mask) { + unsigned i = u_bit_scan(&mask); + struct si_pm4_state *state = sctx->queued.array[i]; + + if (!state || sctx->emitted.array[i] == state) + continue; + + si_pm4_emit(sctx, state); + sctx->emitted.array[i] = state; + } + sctx->dirty_states = 0; + si_emit_scratch_reloc(sctx); si_emit_rasterizer_prim_state(sctx); si_emit_draw_registers(sctx, info); -- 2.30.2