summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2017-01-25 00:09:24 +0100
committerMarek Olšák <[email protected]>2017-01-30 13:27:14 +0100
commitac059f1c238ff8f9a6a1852ec9c89858e7276700 (patch)
tree9f06a4e94884b22ed7451dc2c4ea9fd64a2c8b96
parent802fcdc0d2997bbcda794ffe8b78d45d29e3ed47 (diff)
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 <[email protected]>
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.h1
-rw-r--r--src/gallium/drivers/radeonsi/si_pm4.c16
-rw-r--r--src/gallium/drivers/radeonsi/si_pm4.h1
-rw-r--r--src/gallium/drivers/radeonsi/si_state.h3
-rw-r--r--src/gallium/drivers/radeonsi/si_state_draw.c17
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);