From: Grazvydas Ignotas Date: Wed, 2 Sep 2015 22:54:31 +0000 (+0300) Subject: r600g: simplify dirty atom tracking X-Git-Tag: upstream/17.1.0~16336 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ccbc7952a4c125741f412ebc0278e17b65cf6fd7;p=platform%2Fupstream%2Fmesa.git r600g: simplify dirty atom tracking Now that R600_NUM_ATOMS is below 64, dirty atom tracking can be simplified. Signed-off-by: Marek Olšák --- diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index 092f261..cf71597 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -48,16 +48,15 @@ void r600_need_cs_space(struct r600_context *ctx, unsigned num_dw, num_dw += ctx->b.rings.gfx.cs->cdw; if (count_draw_in) { - unsigned i; + uint64_t mask; /* The number of dwords all the dirty states would take. */ - i = r600_next_dirty_atom(ctx, 0); - while (i < R600_NUM_ATOMS) { - num_dw += ctx->atoms[i]->num_dw; + mask = ctx->dirty_atoms; + while (mask != 0) { + num_dw += ctx->atoms[u_bit_scan64(&mask)]->num_dw; if (ctx->screen->b.trace_bo) { num_dw += R600_TRACE_CS_DWORDS; } - i = r600_next_dirty_atom(ctx, i + 1); } /* The upper-bound of how much space a draw command would take. */ diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 9860eff..76539d6 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -87,9 +87,6 @@ #define R600_BIG_ENDIAN 0 #endif -#define R600_DIRTY_ATOM_WORD_BITS (sizeof(unsigned long) * 8) -#define R600_DIRTY_ATOM_ARRAY_LEN DIV_ROUND_UP(R600_NUM_ATOMS, R600_DIRTY_ATOM_WORD_BITS) - struct r600_context; struct r600_bytecode; union r600_shader_key; @@ -438,7 +435,7 @@ struct r600_context { /* State binding slots are here. */ struct r600_atom *atoms[R600_NUM_ATOMS]; /* Dirty atom bitmask for fast tests */ - unsigned long dirty_atoms[R600_DIRTY_ATOM_ARRAY_LEN]; + uint64_t dirty_atoms; /* States for CS initialization. */ struct r600_command_buffer start_cs_cmd; /* invariant state mostly */ /** Compute specific registers initializations. The start_cs_cmd atom @@ -515,18 +512,17 @@ static inline void r600_set_atom_dirty(struct r600_context *rctx, struct r600_atom *atom, bool dirty) { - unsigned long mask; - unsigned int w; + uint64_t mask; atom->dirty = dirty; assert(atom->id != 0); - w = atom->id / R600_DIRTY_ATOM_WORD_BITS; - mask = 1ul << (atom->id % R600_DIRTY_ATOM_WORD_BITS); + assert(atom->id < sizeof(mask) * 8); + mask = 1ull << atom->id; if (dirty) - rctx->dirty_atoms[w] |= mask; + rctx->dirty_atoms |= mask; else - rctx->dirty_atoms[w] &= ~mask; + rctx->dirty_atoms &= ~mask; } static inline void r600_mark_atom_dirty(struct r600_context *rctx, @@ -535,35 +531,6 @@ static inline void r600_mark_atom_dirty(struct r600_context *rctx, r600_set_atom_dirty(rctx, atom, true); } -static inline unsigned int r600_next_dirty_atom(struct r600_context *rctx, - unsigned int id) -{ -#if !defined(DEBUG) && defined(HAVE___BUILTIN_CTZ) - unsigned int w = id / R600_DIRTY_ATOM_WORD_BITS; - unsigned int bit = id % R600_DIRTY_ATOM_WORD_BITS; - unsigned long bits, mask = (1ul << bit) - 1; - - for (; w < R600_DIRTY_ATOM_ARRAY_LEN; w++, mask = 0ul) { - bits = rctx->dirty_atoms[w] & ~mask; - if (bits == 0) - continue; - return w * R600_DIRTY_ATOM_WORD_BITS + __builtin_ctzl(bits); - } - - return R600_NUM_ATOMS; -#else - for (; id < R600_NUM_ATOMS; id++) { - bool dirty = !!(rctx->dirty_atoms[id / R600_DIRTY_ATOM_WORD_BITS] & - (1ul << (id % R600_DIRTY_ATOM_WORD_BITS))); - assert(dirty == (rctx->atoms[id] && rctx->atoms[id]->dirty)); - if (dirty) - break; - } - - return id; -#endif -} - void r600_trace_emit(struct r600_context *rctx); static inline void r600_emit_atom(struct r600_context *rctx, struct r600_atom *atom) diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 1f96ed6..39c65ae 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -1427,8 +1427,8 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info struct r600_context *rctx = (struct r600_context *)ctx; struct pipe_draw_info info = *dinfo; struct pipe_index_buffer ib = {}; - unsigned i; struct radeon_winsys_cs *cs = rctx->b.rings.gfx.cs; + uint64_t mask; if (!info.indirect && !info.count && (info.indexed || !info.count_from_stream_output)) { return; @@ -1538,10 +1538,9 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info r600_need_cs_space(rctx, ib.user_buffer ? 5 : 0, TRUE); r600_flush_emit(rctx); - i = r600_next_dirty_atom(rctx, 0); - while (i < R600_NUM_ATOMS) { - r600_emit_atom(rctx, rctx->atoms[i]); - i = r600_next_dirty_atom(rctx, i + 1); + mask = rctx->dirty_atoms; + while (mask != 0) { + r600_emit_atom(rctx, rctx->atoms[u_bit_scan64(&mask)]); } if (rctx->b.chip_class == CAYMAN) {