Mesa (master): radeonsi: use a bitmask for looping over dirty PM4 states

Marek Olšák mareko at kemper.freedesktop.org
Mon Jan 30 12:27:32 UTC 2017


Module: Mesa
Branch: master
Commit: ac059f1c238ff8f9a6a1852ec9c89858e7276700
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ac059f1c238ff8f9a6a1852ec9c89858e7276700

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Wed Jan 25 00:09:24 2017 +0100

radeonsi: use a bitmask for looping over dirty PM4 states

also move it to draw_vbo, because it should be 0 in most cases

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>

---

 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 b6474e6..da6aca1 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 97b6799..2680439 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 9b02a80..106abe1 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 915a8eb..bdcfb5b 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 0374841..f0bd930 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);




More information about the mesa-commit mailing list