[Mesa-dev] [PATCH 13/42] radeonsi: use a bitmask for tracking dirty atoms

Marek Olšák maraeo at gmail.com
Sun Aug 30 12:11:43 PDT 2015


From: Marek Olšák <marek.olsak at amd.com>

This mainly removes the cache misses when checking the dirty flags.
Not much else though.
---
 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 f821ad3..2381b6c 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 5ca83e7..35104cf 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 2ff58d1..81575b5 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.1.4



More information about the mesa-dev mailing list