From 87c1e9e19c6baa8c6fb03b0894c72744a07cde63 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sat, 29 Aug 2015 00:49:40 +0200 Subject: [PATCH] radeonsi: use a bitmask for tracking dirty atoms MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This mainly removes the cache misses when checking the dirty flags. Not much else though. Reviewed-by: Alex Deucher Acked-by: Christian König --- src/gallium/drivers/radeonsi/si_hw_context.c | 10 ++++------ src/gallium/drivers/radeonsi/si_pipe.h | 8 +++++++- src/gallium/drivers/radeonsi/si_state_draw.c | 13 +++++++------ 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c index f821ad33ff3..2381b6c0004 100644 --- a/src/gallium/drivers/radeonsi/si_hw_context.c +++ b/src/gallium/drivers/radeonsi/si_hw_context.c @@ -31,7 +31,6 @@ void si_need_cs_space(struct si_context *ctx, unsigned num_dw, boolean count_draw_in) { struct radeon_winsys_cs *cs = ctx->b.rings.gfx.cs; - int i; /* There are two memory usage counters in the winsys for all buffers * that have been added (cs_add_reloc) and two counters in the pipe @@ -59,11 +58,10 @@ void si_need_cs_space(struct si_context *ctx, unsigned num_dw, num_dw += cs->cdw; if (count_draw_in) { - for (i = 0; i < SI_NUM_ATOMS; i++) { - if (ctx->atoms.array[i]->dirty) { - num_dw += ctx->atoms.array[i]->num_dw; - } - } + unsigned mask = ctx->dirty_atoms; + + while (mask) + num_dw += ctx->atoms.array[u_bit_scan(&mask)]->num_dw; /* The number of dwords all the dirty states would take. */ num_dw += si_pm4_dirty_dw(ctx); diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 5ca83e7a2d2..35104cf7848 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -155,6 +155,7 @@ struct si_context { struct si_shader_selector *fixed_func_tcs_shader; union si_state_atoms atoms; + unsigned dirty_atoms; /* mask */ struct si_framebuffer framebuffer; struct si_vertex_element *vertex_elements; @@ -339,7 +340,12 @@ static inline void si_set_atom_dirty(struct si_context *sctx, struct r600_atom *atom, bool dirty) { - atom->dirty = dirty; + unsigned bit = 1 << (atom->id - 1); + + if (dirty) + sctx->dirty_atoms |= bit; + else + sctx->dirty_atoms &= ~bit; } static inline void diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index 2ff58d1f332..81575b53dd8 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -729,7 +729,7 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) { struct si_context *sctx = (struct si_context *)ctx; struct pipe_index_buffer ib = {}; - unsigned i; + unsigned mask; if (!info->count && !info->indirect && (info->indexed || !info->count_from_stream_output)) @@ -821,12 +821,13 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) si_need_cs_space(sctx, 0, TRUE); /* Emit states. */ - for (i = 0; i < SI_NUM_ATOMS; i++) { - if (sctx->atoms.array[i]->dirty) { - sctx->atoms.array[i]->emit(&sctx->b, sctx->atoms.array[i]); - sctx->atoms.array[i]->dirty = false; - } + mask = sctx->dirty_atoms; + while (mask) { + struct r600_atom *atom = sctx->atoms.array[u_bit_scan(&mask)]; + + atom->emit(&sctx->b, atom); } + sctx->dirty_atoms = 0; si_pm4_emit_dirty(sctx); si_emit_scratch_reloc(sctx); -- 2.30.2