summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2010-04-11 14:45:14 +0200
committerJerome Glisse <jglisse@redhat.com>2010-04-11 14:45:14 +0200
commit0ff0d407d43d497a2e1834993e6855128c462ba9 (patch)
tree0814e50d7a3673bd0e98ab9a8588f053e5fcfc30
parenta47929eeb0e5e9a94a2dc83c8795c1bc759bd7b9 (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.am3
-rw-r--r--src/r600_ctx.c23
-rw-r--r--src/r600_state.c8
-rw-r--r--src/radeon.c32
-rw-r--r--src/radeon.h2
-rw-r--r--src/radeon_ctx.c4
-rw-r--r--src/radeon_priv.h3
-rw-r--r--src/radeon_state.c3
-rw-r--r--src/radeondb.c2
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;