radeonsi: use a bitmask for looping over dirty PM4 states
authorMarek Olšák <marek.olsak@amd.com>
Tue, 24 Jan 2017 23:09:24 +0000 (00:09 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Mon, 30 Jan 2017 12:27:14 +0000 (13:27 +0100)
also move it to draw_vbo, because it should be 0 in most cases

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_pm4.c
src/gallium/drivers/radeonsi/si_pm4.h
src/gallium/drivers/radeonsi/si_state.h
src/gallium/drivers/radeonsi/si_state_draw.c

index b6474e6..da6aca1 100644 (file)
@@ -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;
 
index 97b6799..2680439 100644 (file)
@@ -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,
index 9b02a80..106abe1 100644 (file)
@@ -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
index 915a8eb..bdcfb5b 100644 (file)
@@ -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) \
index 0374841..f0bd930 100644 (file)
@@ -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);