diff options
author | Jerome Glisse <jglisse@redhat.com> | 2010-04-11 14:45:14 +0200 |
---|---|---|
committer | Jerome Glisse <jglisse@redhat.com> | 2010-04-11 14:45:14 +0200 |
commit | 0ff0d407d43d497a2e1834993e6855128c462ba9 (patch) | |
tree | 0814e50d7a3673bd0e98ab9a8588f053e5fcfc30 | |
parent | a47929eeb0e5e9a94a2dc83c8795c1bc759bd7b9 (diff) |
radeondb: avoid duplicate state emission
Avoid reemitting same state allow nice cut in the cs stream
size from the classic driver (up to 2 time smaller than what
classic does for same rendering)
Signed-off-by: Jerome Glisse <jglisse@redhat.com>
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | src/r600_ctx.c | 23 | ||||
-rw-r--r-- | src/r600_state.c | 8 | ||||
-rw-r--r-- | src/radeon.c | 32 | ||||
-rw-r--r-- | src/radeon.h | 2 | ||||
-rw-r--r-- | src/radeon_ctx.c | 4 | ||||
-rw-r--r-- | src/radeon_priv.h | 3 | ||||
-rw-r--r-- | src/radeon_state.c | 3 | ||||
-rw-r--r-- | src/radeondb.c | 2 |
9 files changed, 69 insertions, 11 deletions
diff --git a/Makefile.am b/Makefile.am index 4196901..a39844f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,4 +20,7 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. AUTOMAKE_OPTIONS = foreign +debug: + $(MAKE) all "CFLAGS=-O0 -g3 -DDEBUG" + SUBDIRS = src diff --git a/src/r600_ctx.c b/src/r600_ctx.c index 2181d51..5f1fdff 100644 --- a/src/r600_ctx.c +++ b/src/r600_ctx.c @@ -178,6 +178,27 @@ static int cs_draw_index(struct radeon_ctx *ctx) return r600_bof_ctx_new_draw(ctx); } +static int cs_draw_index_immd(struct radeon_ctx *ctx) +{ + unsigned i; + int r; + + r = radeon_ctx_draw_set_reg(ctx, R_008970_VGT_NUM_INDICES, ctx->pm4[ctx->id + 1]); + if (r) + return r; + r = radeon_ctx_draw_set_reg(ctx, R_0287F0_VGT_DRAW_INITIATOR, ctx->pm4[ctx->id + 2]); + if (r) + return r; + ctx->cdraw->state[R600_DRAW]->nimmd = PKT_COUNT_G(ctx->pm4[ctx->id]) - 1; + ctx->cdraw->state[R600_DRAW]->immd = calloc(1, ctx->cdraw->state[R600_DRAW]->nimmd * 4); + if (ctx->cdraw->state[R600_DRAW]->immd == NULL) + return -ENOMEM; + for (i = 0; i < ctx->cdraw->state[R600_DRAW]->nimmd; i++) { + ctx->cdraw->state[R600_DRAW]->immd[i] = ctx->pm4[ctx->id + 3 + i]; + } + return r600_bof_ctx_new_draw(ctx); +} + static int cs_set_alu_const(struct radeon_ctx *ctx) { unsigned i, count, offset; @@ -296,7 +317,7 @@ struct cs_packet3 r600_packet3[] = { {0x2A, "INDEX_TYPE", &cs_index_type}, {0x2B, "DRAW_INDEX", &cs_draw_index}, {0x2D, "DRAW_INDEX_AUTO", &cs_draw_auto}, - {0x2E, "DRAW_INDEX_IMMD", NULL}, + {0x2E, "DRAW_INDEX_IMMD", &cs_draw_index_immd}, {0x2F, "NUM_INSTANCES", &cs_num_instances}, {0x32, "INDIRECT_BUFFER", NULL}, {0x34, "STRMOUT_BUFFER_UPDATE", NULL}, diff --git a/src/r600_state.c b/src/r600_state.c index 739e260..397c5ad 100644 --- a/src/r600_state.c +++ b/src/r600_state.c @@ -286,6 +286,7 @@ static int r600_state_pm4_vgt(struct radeon_state *state) static int r600_state_pm4_draw(struct radeon_state *state) { + unsigned i; int r; if (state->nbo) { @@ -299,6 +300,13 @@ static int r600_state_pm4_draw(struct radeon_state *state) if (r) return r; state->pm4[state->cpm4++] = state->bo[0]->handle; + } else if (state->nimmd) { + state->pm4[state->cpm4++] = PKT3(PKT3_DRAW_INDEX_IMMD, state->nimmd + 1); + state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_NUM_INDICES]; + state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DRAW_INITIATOR]; + for (i = 0; i < state->nimmd; i++) { + state->pm4[state->cpm4++] = state->immd[i]; + } } else { state->pm4[state->cpm4++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1); state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_NUM_INDICES]; diff --git a/src/radeon.c b/src/radeon.c index 19ed4c8..66dbfc3 100644 --- a/src/radeon.c +++ b/src/radeon.c @@ -251,8 +251,8 @@ int radeon_flush(struct radeon *radeon) ctx->pm4 = malloc(ctx->cpm4 * 4); if (ctx->pm4 == NULL) return -EINVAL; - for (i = 0, ctx->id = 0; i < ctx->ndraw; i++) { - r = radeon_ctx_draw_schedule(ctx, i); + for (i = 0, ctx->id = 0; i < ctx->nstate; i++) { + r = radeon_ctx_state_schedule(ctx, ctx->state[i]); if (r) return r; } @@ -261,7 +261,10 @@ int radeon_flush(struct radeon *radeon) __func__, ctx->cpm4, ctx->id); return -EINVAL; } - return radeon_ctx_submit(ctx); + r = radeon_ctx_submit(ctx); + radeon_ctx_destroy(ctx); + radeon->ctx = radeon_ctx(radeon, 0); + return r; } int radeon_reg_id(struct radeon *radeon, unsigned offset, unsigned *typeid, unsigned *stateid, unsigned *id) @@ -313,7 +316,8 @@ int radeon_schedule_draw(struct radeon *radeon, struct radeon_draw *draw) struct radeon_ctx *ctx = radeon->ctx; struct radeon_draw *pdraw = NULL; struct radeon_state *nstate, *ostate; - unsigned cpm4, i; + unsigned cpm4, i, cstate; + void *tmp; int r = 0; if (ctx == NULL) { @@ -331,22 +335,36 @@ int radeon_schedule_draw(struct radeon *radeon, struct radeon_draw *draw) return -EINVAL; } reprocess: + tmp = realloc(ctx->state, (ctx->nstate + draw->nstate) * sizeof(void*)); + if (tmp == NULL) + return -ENOMEM; + ctx->state = tmp; pdraw = ctx->cdraw; - for (i = 0, cpm4 = 0; i < draw->nstate; i++) { + for (i = 0, cpm4 = 0, cstate = ctx->nstate; i < draw->nstate - 1; i++) { nstate = draw->state[i]; if (nstate) { if (pdraw && pdraw->state[i]) { ostate = pdraw->state[i]; if (ostate->pm4_crc == nstate->pm4_crc) { - cpm4 += nstate->cpm4; +// ctx->state[cstate++] = nstate; +// cpm4 += nstate->cpm4; } else { + ctx->state[cstate++] = nstate; cpm4 += nstate->cpm4; } } else { + ctx->state[cstate++] = nstate; cpm4 += nstate->cpm4; } } } + /* The last state is the draw state always add it */ + if (draw->state[i] == NULL) { + fprintf(stderr, "%s no draw command\n", __func__); + return -EINVAL; + } + ctx->state[cstate++] = draw->state[i]; + cpm4 += draw->state[i]->cpm4; if ((ctx->cpm4 + cpm4) > RADEON_CTX_MAX_PM4) { r = radeon_flush(radeon); if (r) @@ -356,7 +374,9 @@ reprocess: r = radeon_ctx_set_draw_new(ctx, draw); if (r) goto out_err; + radeon_draw_incref(draw); ctx->cpm4 += cpm4; + ctx->nstate = cstate; out_err: return r; } diff --git a/src/radeon.h b/src/radeon.h index a787550..806d85c 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -105,6 +105,8 @@ struct radeon_state { unsigned cpm4; u32 pm4_crc; u32 *pm4; + u32 nimmd; + u32 *immd; unsigned nbo; struct radeon_object *bo[4]; unsigned nreloc; diff --git a/src/radeon_ctx.c b/src/radeon_ctx.c index c625091..4e0ba56 100644 --- a/src/radeon_ctx.c +++ b/src/radeon_ctx.c @@ -341,7 +341,7 @@ int radeon_ctx_state_schedule(struct radeon_ctx *ctx, struct radeon_state *state ctx->id += state->cpm4; return 0; } - +#if 0 int radeon_ctx_draw_schedule(struct radeon_ctx *ctx, unsigned id) { struct radeon_draw *draw; @@ -356,7 +356,7 @@ int radeon_ctx_draw_schedule(struct radeon_ctx *ctx, unsigned id) } return 0; } - +#endif int radeon_ctx_draw_set_reg(struct radeon_ctx *ctx, unsigned offset, u32 value) { struct radeon_draw *draw; diff --git a/src/radeon_priv.h b/src/radeon_priv.h index 758c6c6..a30ba73 100644 --- a/src/radeon_priv.h +++ b/src/radeon_priv.h @@ -151,6 +151,8 @@ struct radeon_ctx { unsigned ndraw; struct radeon_draw *cdraw; struct radeon_draw **draw; + unsigned nstate; + struct radeon_state **state; }; extern struct radeon_ctx *radeon_ctx(struct radeon *radeon, unsigned device); @@ -165,6 +167,7 @@ extern int radeon_ctx_allocate_bo(struct radeon_ctx *ctx); extern int radeon_ctx_submit(struct radeon_ctx *ctx); extern int radeon_ctx_draw(struct radeon_ctx *ctx); extern int radeon_ctx_set_draw_new(struct radeon_ctx *ctx, struct radeon_draw *draw); +extern int radeon_ctx_state_schedule(struct radeon_ctx *ctx, struct radeon_state *state); extern int radeon_ctx_draw_schedule(struct radeon_ctx *ctx, unsigned id); extern int radeon_ctx_draw_set_reg(struct radeon_ctx *ctx, unsigned offset, u32 value); diff --git a/src/radeon_state.c b/src/radeon_state.c index 2a568a9..6cba23d 100644 --- a/src/radeon_state.c +++ b/src/radeon_state.c @@ -101,6 +101,7 @@ struct radeon_state *radeon_state_decref(struct radeon_state *state) for (i = 0; i < state->nbo; i++) { state->bo[i] = radeon_object_decref(state->bo[i]); } + free(state->immd); free(state->states); free(state->pm4); memset(state, 0, sizeof(*state)); @@ -152,7 +153,7 @@ int radeon_state_pm4(struct radeon_state *state) if (r) { return r; } - state->pm4_crc = crc32(state->pm4, state->cpm4); + state->pm4_crc = crc32(state->pm4, state->cpm4 * 4); return 0; } diff --git a/src/radeondb.c b/src/radeondb.c index c29e89e..b81fb5f 100644 --- a/src/radeondb.c +++ b/src/radeondb.c @@ -216,7 +216,7 @@ static int json(const char *file) goto out; } radeon_blit(&dst, &src, 0, 0, 0, 0, src.width, src.height); - for (unsigned i = 0; i < ctx->ndraw - 0; i++) { + for (unsigned i = 0; i < ctx->ndraw; i++) { if (radeon_draw_pm4(ctx->draw[i])) { fprintf(stderr, "failed to pm4 %d\n", i); goto out; |