diff options
Diffstat (limited to 'src/gallium/winsys/r600/drm/radeon_ctx.c')
-rw-r--r-- | src/gallium/winsys/r600/drm/radeon_ctx.c | 160 |
1 files changed, 50 insertions, 110 deletions
diff --git a/src/gallium/winsys/r600/drm/radeon_ctx.c b/src/gallium/winsys/r600/drm/radeon_ctx.c index 6b0eba0b28..af270d5d20 100644 --- a/src/gallium/winsys/r600/drm/radeon_ctx.c +++ b/src/gallium/winsys/r600/drm/radeon_ctx.c @@ -32,13 +32,8 @@ int radeon_ctx_set_bo_new(struct radeon_ctx *ctx, struct radeon_bo *bo) { - void *ptr; - - ptr = realloc(ctx->bo, sizeof(struct radeon_bo) * (ctx->nbo + 1)); - if (ptr == NULL) { - return -ENOMEM; - } - ctx->bo = ptr; + if (ctx->nbo >= 2048) + return -EBUSY; ctx->bo[ctx->nbo] = bo; ctx->nbo++; return 0; @@ -76,49 +71,26 @@ void radeon_ctx_get_placement(struct radeon_ctx *ctx, unsigned reloc, u32 *place } } -struct radeon_ctx *radeon_ctx(struct radeon *radeon) -{ - struct radeon_ctx *ctx; - - if (radeon == NULL) - return NULL; - ctx = calloc(1, sizeof(*ctx)); - if (ctx == NULL) - return NULL; - ctx->radeon = radeon_incref(radeon); - return ctx; -} - -struct radeon_ctx *radeon_ctx_incref(struct radeon_ctx *ctx) +static void radeon_ctx_clear(struct radeon_ctx *ctx) { - ctx->refcount++; - return ctx; + ctx->draw_cpm4 = 0; + ctx->cpm4 = 0; + ctx->ndraw = 0; + ctx->nbo = 0; + ctx->nreloc = 0; } -struct radeon_ctx *radeon_ctx_decref(struct radeon_ctx *ctx) +int radeon_ctx_init(struct radeon_ctx *ctx, struct radeon *radeon) { - unsigned i; - - if (ctx == NULL) - return NULL; - if (--ctx->refcount > 0) { - return NULL; - } - - for (i = 0; i < ctx->ndraw; i++) { - ctx->draw[i] = radeon_draw_decref(ctx->draw[i]); - } - for (i = 0; i < ctx->nbo; i++) { - ctx->bo[i] = radeon_bo_decref(ctx->radeon, ctx->bo[i]); - } - ctx->radeon = radeon_decref(ctx->radeon); - free(ctx->draw); - free(ctx->bo); + memset(ctx, 0, sizeof(struct radeon_ctx)); + ctx->radeon = radeon_incref(radeon); + radeon_ctx_clear(ctx); free(ctx->pm4); - free(ctx->reloc); - memset(ctx, 0, sizeof(*ctx)); - free(ctx); - return NULL; + ctx->cpm4 = 0; + ctx->pm4 = malloc(64 * 1024); + if (ctx->pm4 == NULL) + return -ENOMEM; + return 0; } static int radeon_ctx_state_bo(struct radeon_ctx *ctx, struct radeon_state *state) @@ -143,7 +115,6 @@ static int radeon_ctx_state_bo(struct radeon_ctx *ctx, struct radeon_state *stat return 0; } - int radeon_ctx_submit(struct radeon_ctx *ctx) { struct drm_radeon_cs drmib; @@ -170,6 +141,7 @@ int radeon_ctx_submit(struct radeon_ctx *ctx) r = drmCommandWriteRead(ctx->radeon->fd, DRM_RADEON_CS, &drmib, sizeof(struct drm_radeon_cs)); #endif + radeon_ctx_clear(ctx); return r; } @@ -177,7 +149,6 @@ static int radeon_ctx_reloc(struct radeon_ctx *ctx, struct radeon_bo *bo, unsigned id, unsigned *placement) { unsigned i; - struct radeon_cs_reloc *ptr; for (i = 0; i < ctx->nreloc; i++) { if (ctx->reloc[i].handle == bo->handle) { @@ -185,14 +156,12 @@ static int radeon_ctx_reloc(struct radeon_ctx *ctx, struct radeon_bo *bo, return 0; } } - ptr = realloc(ctx->reloc, sizeof(struct radeon_cs_reloc) * (ctx->nreloc + 1)); - if (ptr == NULL) - return -ENOMEM; - ctx->reloc = ptr; - ptr[ctx->nreloc].handle = bo->handle; - ptr[ctx->nreloc].read_domain = placement[0] | placement [1]; - ptr[ctx->nreloc].write_domain = placement[0] | placement [1]; - ptr[ctx->nreloc].flags = 0; + if (ctx->nreloc >= 2048) + return -EINVAL; + ctx->reloc[ctx->nreloc].handle = bo->handle; + ctx->reloc[ctx->nreloc].read_domain = placement[0] | placement [1]; + ctx->reloc[ctx->nreloc].write_domain = placement[0] | placement [1]; + ctx->reloc[ctx->nreloc].flags = 0; ctx->pm4[id] = ctx->nreloc * sizeof(struct radeon_cs_reloc) / 4; ctx->nreloc++; return 0; @@ -221,21 +190,13 @@ static int radeon_ctx_state_schedule(struct radeon_ctx *ctx, struct radeon_state return 0; } -int radeon_ctx_set_draw_new(struct radeon_ctx *ctx, struct radeon_draw *draw) +int radeon_ctx_set_draw(struct radeon_ctx *ctx, struct radeon_draw *draw) { - struct radeon_draw *pdraw = NULL; - struct radeon_draw **ndraw; - struct radeon_state *nstate, *ostate; - unsigned cpm4, i, cstate; - void *tmp; + unsigned cpm4, i; int r = 0; - ndraw = realloc(ctx->draw, sizeof(void*) * (ctx->ndraw + 1)); - if (ndraw == NULL) - return -ENOMEM; - ctx->draw = ndraw; for (i = 0; i < draw->nstate; i++) { - r = radeon_ctx_state_bo(ctx, draw->state[i]); + r = radeon_ctx_state_bo(ctx, &draw->state[i]); if (r) return r; } @@ -247,69 +208,48 @@ int radeon_ctx_set_draw_new(struct radeon_ctx *ctx, struct radeon_draw *draw) __func__, draw->cpm4, RADEON_CTX_MAX_PM4); return -EINVAL; } - 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, 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) { - ctx->state[cstate++] = nstate; - cpm4 += nstate->cpm4; - } - } else { - ctx->state[cstate++] = nstate; - cpm4 += nstate->cpm4; + ctx->draw[ctx->ndraw] = *draw; + for (i = 0, cpm4 = 0; i < draw->nstate - 1; i++) { + ctx->draw[ctx->ndraw].state[i].valid &= ~2; + if (ctx->draw[ctx->ndraw].state[i].valid) { + if (ctx->ndraw > 1 && ctx->draw[ctx->ndraw - 1].state[i].valid) { + if (ctx->draw[ctx->ndraw - 1].state[i].pm4_crc == draw->state[i].pm4_crc) + continue; } + ctx->draw[ctx->ndraw].state[i].valid |= 2; + cpm4 += ctx->draw[ctx->ndraw].state[i].cpm4; } } /* The last state is the draw state always add it */ - if (draw->state[i] == NULL) { + if (!draw->state[i].valid) { fprintf(stderr, "%s no draw command\n", __func__); return -EINVAL; } - ctx->state[cstate++] = draw->state[i]; - cpm4 += draw->state[i]->cpm4; + ctx->draw[ctx->ndraw].state[i].valid |= 2; + cpm4 += ctx->draw[ctx->ndraw].state[i].cpm4; if ((ctx->draw_cpm4 + cpm4) > RADEON_CTX_MAX_PM4) { /* need to flush */ return -EBUSY; } ctx->draw_cpm4 += cpm4; - ctx->nstate = cstate; - ctx->draw[ctx->ndraw++] = draw; - ctx->cdraw = draw; + ctx->ndraw++; return 0; } -int radeon_ctx_set_draw(struct radeon_ctx *ctx, struct radeon_draw *draw) -{ - int r; - - radeon_draw_incref(draw); - r = radeon_ctx_set_draw_new(ctx, draw); - if (r) - radeon_draw_decref(draw); - return r; -} - int radeon_ctx_pm4(struct radeon_ctx *ctx) { - unsigned i; + unsigned i, j, c; int r; - free(ctx->pm4); - ctx->cpm4 = 0; - ctx->pm4 = malloc(ctx->draw_cpm4 * 4); - if (ctx->pm4 == NULL) - return -EINVAL; - for (i = 0, ctx->id = 0; i < ctx->nstate; i++) { - r = radeon_ctx_state_schedule(ctx, ctx->state[i]); - if (r) - return r; + for (i = 0, c = 0, ctx->id = 0; i < ctx->ndraw; i++) { + for (j = 0; j < ctx->draw[i].nstate; j++) { + if (ctx->draw[i].state[j].valid & 2) { + r = radeon_ctx_state_schedule(ctx, &ctx->draw[i].state[j]); + if (r) + return r; + c += ctx->draw[i].state[j].cpm4; + } + } } if (ctx->id != ctx->draw_cpm4) { fprintf(stderr, "%s miss predicted pm4 size %d for %d\n", |