radeonsi: use a bitmask for tracking dirty atoms

This mainly removes the cache misses when checking the dirty flags.
Not much else though.

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
This commit is contained in:
Marek Olšák 2015-08-29 00:49:40 +02:00
parent 2fe040ee61
commit 87c1e9e19c
3 changed files with 18 additions and 13 deletions

View file

@ -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);

View file

@ -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

View file

@ -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);