r600g: use dirty list to track dirty blocks
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Tue, 5 Oct 2010 19:01:43 +0000 (21:01 +0200)
committerJerome Glisse <jglisse@redhat.com>
Tue, 5 Oct 2010 19:16:06 +0000 (15:16 -0400)
Got a speed up by tracking the dirty blocks in a seperate list instead of looping through all blocks. This version should work with block that get their dirty state disabled again and I added a dirty check during the flush as some blocks were already dirty.

src/gallium/drivers/r600/r600.h
src/gallium/winsys/r600/drm/evergreen_hw_context.c
src/gallium/winsys/r600/drm/r600_hw_context.c
src/gallium/winsys/r600/drm/r600_priv.h

index 59a255d2fae3e05dd5ae8653d0e8c0ee47cebf87..acacec0c413dc5437f92451bfac65a4a698dacf2 100644 (file)
@@ -160,6 +160,7 @@ struct r600_block_reloc {
 };
 
 struct r600_block {
+       struct list_head        list;
        unsigned                status;
        unsigned                start_offset;
        unsigned                pm4_ndwords;
@@ -221,6 +222,7 @@ struct r600_context {
        struct r600_range       range[256];
        unsigned                nblocks;
        struct r600_block       **blocks;
+       struct list_head        dirty;
        unsigned                pm4_ndwords;
        unsigned                pm4_cdwords;
        unsigned                pm4_dirty_cdwords;
index 96769add9052ecb180afe2c7afd47bb602ef1666..1355b0794508f0a1367ae51a4ee5d64cbbf2fe35 100644 (file)
@@ -613,6 +613,9 @@ int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon)
                r = -ENOMEM;
                goto out_err;
        }
+
+       /* init dirty list */
+       LIST_INITHEAD(&ctx->dirty);
        return 0;
 out_err:
        r600_context_fini(ctx);
@@ -630,6 +633,7 @@ static inline void evergreen_context_pipe_state_set_resource(struct r600_context
                block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY);
                r600_bo_reference(ctx->radeon, &block->reloc[1].bo, NULL);
                r600_bo_reference(ctx->radeon , &block->reloc[2].bo, NULL);
+               LIST_DEL(&block->list);
                return;
        }
        block->reg[0] = state->regs[0].value;
@@ -657,6 +661,7 @@ static inline void evergreen_context_pipe_state_set_resource(struct r600_context
                block->status |= R600_BLOCK_STATUS_ENABLED;
                block->status |= R600_BLOCK_STATUS_DIRTY;
                ctx->pm4_dirty_cdwords += block->pm4_ndwords + block->pm4_flush_ndwords;
+               LIST_ADDTAIL(&block->list,&ctx->dirty);
        }
 }
 
@@ -683,6 +688,7 @@ static inline void evergreen_context_pipe_state_set_sampler(struct r600_context
        block = range->blocks[CTX_BLOCK_ID(ctx, offset)];
        if (state == NULL) {
                block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY);
+               LIST_DEL(&block->list);
                return;
        }
        block->reg[0] = state->regs[0].value;
@@ -692,6 +698,7 @@ static inline void evergreen_context_pipe_state_set_sampler(struct r600_context
                block->status |= R600_BLOCK_STATUS_ENABLED;
                block->status |= R600_BLOCK_STATUS_DIRTY;
                ctx->pm4_dirty_cdwords += block->pm4_ndwords + block->pm4_flush_ndwords;
+               LIST_ADDTAIL(&block->list,&ctx->dirty);
        }
 }
 
@@ -705,6 +712,7 @@ static inline void evergreen_context_pipe_state_set_sampler_border(struct r600_c
        block = range->blocks[CTX_BLOCK_ID(ctx, fake_offset)];
        if (state == NULL) {
                block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY);
+               LIST_DEL(&block->list);
                return;
        }
        if (state->nregs <= 3) {
@@ -719,6 +727,7 @@ static inline void evergreen_context_pipe_state_set_sampler_border(struct r600_c
                block->status |= R600_BLOCK_STATUS_ENABLED;
                block->status |= R600_BLOCK_STATUS_DIRTY;
                ctx->pm4_dirty_cdwords += block->pm4_ndwords + block->pm4_flush_ndwords;
+               LIST_ADDTAIL(&block->list,&ctx->dirty);
        }
 }
 
@@ -746,6 +755,7 @@ void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *dr
        struct r600_bo *cb[12];
        struct r600_bo *db;
        unsigned ndwords = 9, flush;
+       struct r600_block *dirty_block;
 
        if (draw->indices) {
                ndwords = 13;
@@ -800,11 +810,10 @@ void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *dr
        }
 
        /* enough room to copy packet */
-       for (int i = 0; i < ctx->nblocks; i++) {
-               if (ctx->blocks[i]->status & R600_BLOCK_STATUS_DIRTY) {
-                       r600_context_block_emit_dirty(ctx, ctx->blocks[i]);
-               }
+       LIST_FOR_EACH_ENTRY(dirty_block,&ctx->dirty,list) {
+               r600_context_block_emit_dirty(ctx, dirty_block);
        }
+       LIST_INITHEAD(&ctx->dirty);
 
        /* draw packet */
        ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0);
@@ -884,6 +893,7 @@ static inline void evergreen_resource_set(struct r600_context *ctx, struct r600_
                block->status |= R600_BLOCK_STATUS_ENABLED;
                block->status |= R600_BLOCK_STATUS_DIRTY;
                ctx->pm4_dirty_cdwords += block->pm4_ndwords + block->pm4_flush_ndwords;
+               LIST_ADDTAIL(&block->list,&ctx->dirty);
        }
 }
 
index 84539d143965dd6ee6f93e43e5c5137266647e0a..5019c26df05cdf0fec1bb479b35ab072fcc1463f 100644 (file)
@@ -691,6 +691,9 @@ int r600_context_init(struct r600_context *ctx, struct radeon *radeon)
                r = -ENOMEM;
                goto out_err;
        }
+
+       /* init dirty list */
+       LIST_INITHEAD(&ctx->dirty);
        return 0;
 out_err:
        r600_context_fini(ctx);
@@ -762,6 +765,7 @@ void r600_context_pipe_state_set(struct r600_context *ctx, struct r600_pipe_stat
                        block->status |= R600_BLOCK_STATUS_ENABLED;
                        block->status |= R600_BLOCK_STATUS_DIRTY;
                        ctx->pm4_dirty_cdwords += block->pm4_ndwords + block->pm4_flush_ndwords;
+                       LIST_ADDTAIL(&block->list,&ctx->dirty);
                }
        }
 }
@@ -777,6 +781,7 @@ static inline void r600_context_pipe_state_set_resource(struct r600_context *ctx
                block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY);
                r600_bo_reference(ctx->radeon, &block->reloc[1].bo, NULL);
                r600_bo_reference(ctx->radeon , &block->reloc[2].bo, NULL);
+               LIST_DEL(&block->list);
                return;
        }
        block->reg[0] = state->regs[0].value;
@@ -803,6 +808,7 @@ static inline void r600_context_pipe_state_set_resource(struct r600_context *ctx
                block->status |= R600_BLOCK_STATUS_ENABLED;
                block->status |= R600_BLOCK_STATUS_DIRTY;
                ctx->pm4_dirty_cdwords += block->pm4_ndwords + block->pm4_flush_ndwords;
+               LIST_ADDTAIL(&block->list,&ctx->dirty);
        }
 }
 
@@ -829,6 +835,7 @@ static inline void r600_context_pipe_state_set_sampler(struct r600_context *ctx,
        block = range->blocks[CTX_BLOCK_ID(ctx, offset)];
        if (state == NULL) {
                block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY);
+               LIST_DEL(&block->list);
                return;
        }
        block->reg[0] = state->regs[0].value;
@@ -838,6 +845,7 @@ static inline void r600_context_pipe_state_set_sampler(struct r600_context *ctx,
                block->status |= R600_BLOCK_STATUS_ENABLED;
                block->status |= R600_BLOCK_STATUS_DIRTY;
                ctx->pm4_dirty_cdwords += block->pm4_ndwords + block->pm4_flush_ndwords;
+               LIST_ADDTAIL(&block->list,&ctx->dirty);
        }
 }
 
@@ -850,6 +858,7 @@ static inline void r600_context_pipe_state_set_sampler_border(struct r600_contex
        block = range->blocks[CTX_BLOCK_ID(ctx, offset)];
        if (state == NULL) {
                block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY);
+               LIST_DEL(&block->list);
                return;
        }
        if (state->nregs <= 3) {
@@ -863,6 +872,7 @@ static inline void r600_context_pipe_state_set_sampler_border(struct r600_contex
                block->status |= R600_BLOCK_STATUS_ENABLED;
                block->status |= R600_BLOCK_STATUS_DIRTY;
                ctx->pm4_dirty_cdwords += block->pm4_ndwords + block->pm4_flush_ndwords;
+               LIST_ADDTAIL(&block->list,&ctx->dirty);
        }
 }
 
@@ -907,6 +917,7 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw)
        struct r600_bo *cb[8];
        struct r600_bo *db;
        unsigned ndwords = 9;
+       struct r600_block *dirty_block;
 
        if (draw->indices) {
                ndwords = 13;
@@ -959,11 +970,10 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw)
        }
 
        /* enough room to copy packet */
-       for (int i = 0; i < ctx->nblocks; i++) {
-               if (ctx->blocks[i]->status & R600_BLOCK_STATUS_DIRTY) {
-                       r600_context_block_emit_dirty(ctx, ctx->blocks[i]);
-               }
+       LIST_FOR_EACH_ENTRY(dirty_block,&ctx->dirty,list) {
+               r600_context_block_emit_dirty(ctx, dirty_block);
        }
+       LIST_INITHEAD(&ctx->dirty);
 
        /* draw packet */
        ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0);
@@ -1052,6 +1062,8 @@ void r600_context_flush(struct r600_context *ctx)
         */
        for (int i = 0; i < ctx->nblocks; i++) {
                if (ctx->blocks[i]->status & R600_BLOCK_STATUS_ENABLED) {
+                       if(!(ctx->blocks[i]->status & R600_BLOCK_STATUS_DIRTY))
+                               LIST_ADDTAIL(&ctx->blocks[i]->list,&ctx->dirty);
                        ctx->pm4_dirty_cdwords += ctx->blocks[i]->pm4_ndwords + ctx->blocks[i]->pm4_flush_ndwords;
                        ctx->blocks[i]->status |= R600_BLOCK_STATUS_DIRTY;
                }
index f6ceb0adc36ba4fb63acbfd93e49a01fbda1296d..9a38cc51f700c462c6727978e8804ba1cce32f7f 100644 (file)
@@ -137,6 +137,7 @@ static void inline r600_context_reg(struct r600_context *ctx,
                ctx->pm4_dirty_cdwords += block->pm4_ndwords;
                block->status |= R600_BLOCK_STATUS_ENABLED;
                block->status |= R600_BLOCK_STATUS_DIRTY;
+               LIST_ADDTAIL(&block->list,&ctx->dirty);
        }
 }