summaryrefslogtreecommitdiff
path: root/src/gallium/winsys
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2010-08-04 17:37:59 -0400
committerJerome Glisse <jglisse@redhat.com>2010-08-05 15:41:35 -0400
commit9c949d4a4dd43b7889e13bdf683bcf211f049ced (patch)
tree0059712f64b8121af96f025eeab3e6a1950df5b3 /src/gallium/winsys
parent0633c2e68312c292607d6af22d94d67d2d141600 (diff)
r600g: don't use dynamic state allocation for states
Simplify state handly by avoiding state allocation. Next step is to allocate once for all context packet buffer and then avoid rebuilding pm4 packet each time (through use of combined crc) this would also avoid number of memcpy. Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Diffstat (limited to 'src/gallium/winsys')
-rw-r--r--src/gallium/winsys/r600/drm/radeon.c11
-rw-r--r--src/gallium/winsys/r600/drm/radeon_ctx.c160
-rw-r--r--src/gallium/winsys/r600/drm/radeon_draw.c92
-rw-r--r--src/gallium/winsys/r600/drm/radeon_priv.h29
-rw-r--r--src/gallium/winsys/r600/drm/radeon_state.c70
5 files changed, 63 insertions, 299 deletions
diff --git a/src/gallium/winsys/r600/drm/radeon.c b/src/gallium/winsys/r600/drm/radeon.c
index 7e65669806..24d821d5cf 100644
--- a/src/gallium/winsys/r600/drm/radeon.c
+++ b/src/gallium/winsys/r600/drm/radeon.c
@@ -43,16 +43,6 @@ static int radeon_get_device(struct radeon *radeon)
return r;
}
-/* symbol missing drove me crazy hack to get symbol exported */
-static void fake(void)
-{
- struct radeon_ctx *ctx;
- struct radeon_draw *draw;
-
- ctx = radeon_ctx(NULL);
- draw = radeon_draw(NULL);
-}
-
struct radeon *radeon_new(int fd, unsigned device)
{
struct radeon *radeon;
@@ -60,7 +50,6 @@ struct radeon *radeon_new(int fd, unsigned device)
radeon = calloc(1, sizeof(*radeon));
if (radeon == NULL) {
- fake();
return NULL;
}
radeon->fd = fd;
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",
diff --git a/src/gallium/winsys/r600/drm/radeon_draw.c b/src/gallium/winsys/r600/drm/radeon_draw.c
index 4413ed79fb..53699eb0b1 100644
--- a/src/gallium/winsys/r600/drm/radeon_draw.c
+++ b/src/gallium/winsys/r600/drm/radeon_draw.c
@@ -31,111 +31,33 @@
/*
* draw functions
*/
-struct radeon_draw *radeon_draw(struct radeon *radeon)
+int radeon_draw_init(struct radeon_draw *draw, struct radeon *radeon)
{
- struct radeon_draw *draw;
-
- draw = calloc(1, sizeof(*draw));
- if (draw == NULL)
- return NULL;
+ memset(draw, 0, sizeof(struct radeon_draw));
draw->nstate = radeon->nstate;
draw->radeon = radeon;
- draw->refcount = 1;
- draw->state = calloc(1, sizeof(void*) * draw->nstate);
- if (draw->state == NULL) {
- free(draw);
- return NULL;
- }
- return draw;
-}
-
-struct radeon_draw *radeon_draw_incref(struct radeon_draw *draw)
-{
- draw->refcount++;
- return draw;
-}
-
-struct radeon_draw *radeon_draw_decref(struct radeon_draw *draw)
-{
- unsigned i;
-
- if (draw == NULL)
- return NULL;
- if (--draw->refcount > 0)
- return NULL;
- for (i = 0; i < draw->nstate; i++) {
- draw->state[i] = radeon_state_decref(draw->state[i]);
- }
- free(draw->state);
- memset(draw, 0, sizeof(*draw));
- free(draw);
- return NULL;
+ return 0;
}
-int radeon_draw_set_new(struct radeon_draw *draw, struct radeon_state *state)
+int radeon_draw_set(struct radeon_draw *draw, struct radeon_state *state)
{
if (state == NULL)
return 0;
if (state->type >= draw->radeon->ntype)
return -EINVAL;
- draw->state[state->id] = radeon_state_decref(draw->state[state->id]);
- draw->state[state->id] = state;
+ draw->state[state->id] = *state;
return 0;
}
-int radeon_draw_set(struct radeon_draw *draw, struct radeon_state *state)
-{
- if (state == NULL)
- return 0;
- radeon_state_incref(state);
- return radeon_draw_set_new(draw, state);
-}
-
int radeon_draw_check(struct radeon_draw *draw)
{
unsigned i;
int r;
- r = radeon_draw_pm4(draw);
- if (r)
- return r;
for (i = 0, draw->cpm4 = 0; i < draw->nstate; i++) {
- if (draw->state[i]) {
- draw->cpm4 += draw->state[i]->cpm4;
+ if (draw->state[i].valid) {
+ draw->cpm4 += draw->state[i].cpm4;
}
}
return 0;
}
-
-struct radeon_draw *radeon_draw_duplicate(struct radeon_draw *draw)
-{
- struct radeon_draw *ndraw;
- unsigned i;
-
- if (draw == NULL)
- return NULL;
- ndraw = radeon_draw(draw->radeon);
- if (ndraw == NULL) {
- return NULL;
- }
- for (i = 0; i < draw->nstate; i++) {
- if (radeon_draw_set(ndraw, draw->state[i])) {
- radeon_draw_decref(ndraw);
- return NULL;
- }
- }
- return ndraw;
-}
-
-int radeon_draw_pm4(struct radeon_draw *draw)
-{
- unsigned i;
- int r;
-
- for (i = 0; i < draw->nstate; i++) {
- r = radeon_state_pm4(draw->state[i]);
- if (r)
- return r;
- }
- return 0;
-}
diff --git a/src/gallium/winsys/r600/drm/radeon_priv.h b/src/gallium/winsys/r600/drm/radeon_priv.h
index b91421f438..80392cda96 100644
--- a/src/gallium/winsys/r600/drm/radeon_priv.h
+++ b/src/gallium/winsys/r600/drm/radeon_priv.h
@@ -24,7 +24,6 @@
#include "radeon.h"
struct radeon;
-struct radeon_ctx;
/*
* radeon functions
@@ -71,34 +70,6 @@ extern unsigned radeon_type_from_id(struct radeon *radeon, unsigned id);
/*
* radeon context functions
*/
-#pragma pack(1)
-struct radeon_cs_reloc {
- uint32_t handle;
- uint32_t read_domain;
- uint32_t write_domain;
- uint32_t flags;
-};
-#pragma pack()
-
-struct radeon_ctx {
- int refcount;
- struct radeon *radeon;
- u32 *pm4;
- u32 cpm4;
- u32 draw_cpm4;
- unsigned id;
- unsigned next_id;
- unsigned nreloc;
- struct radeon_cs_reloc *reloc;
- unsigned nbo;
- struct radeon_bo **bo;
- unsigned ndraw;
- struct radeon_draw *cdraw;
- struct radeon_draw **draw;
- unsigned nstate;
- struct radeon_state **state;
-};
-
int radeon_ctx_set_bo_new(struct radeon_ctx *ctx, struct radeon_bo *bo);
struct radeon_bo *radeon_ctx_get_bo(struct radeon_ctx *ctx, unsigned reloc);
void radeon_ctx_get_placement(struct radeon_ctx *ctx, unsigned reloc, u32 *placement);
diff --git a/src/gallium/winsys/r600/drm/radeon_state.c b/src/gallium/winsys/r600/drm/radeon_state.c
index 308288557a..d7cd1d7a94 100644
--- a/src/gallium/winsys/r600/drm/radeon_state.c
+++ b/src/gallium/winsys/r600/drm/radeon_state.c
@@ -32,82 +32,23 @@
/*
* state core functions
*/
-struct radeon_state *radeon_state(struct radeon *radeon, u32 type, u32 id)
+int radeon_state_init(struct radeon_state *state, struct radeon *radeon, u32 type, u32 id)
{
- struct radeon_state *state;
-
if (type > radeon->ntype) {
fprintf(stderr, "%s invalid type %d\n", __func__, type);
- return NULL;
+ return -EINVAL;
}
if (id > radeon->nstate) {
fprintf(stderr, "%s invalid state id %d\n", __func__, id);
- return NULL;
+ return -EINVAL;
}
- state = calloc(1, sizeof(*state));
- if (state == NULL)
- return NULL;
+ memset(state, 0, sizeof(struct radeon_state));
state->radeon = radeon;
state->type = type;
state->id = id;
- state->refcount = 1;
state->npm4 = radeon->type[type].npm4;
state->nstates = radeon->type[type].nstates;
- state->states = calloc(1, state->nstates * 4);
- state->pm4 = calloc(1, radeon->type[type].npm4 * 4);
- if (state->states == NULL || state->pm4 == NULL) {
- radeon_state_decref(state);
- return NULL;
- }
- return state;
-}
-
-struct radeon_state *radeon_state_duplicate(struct radeon_state *state)
-{
- struct radeon_state *nstate = radeon_state(state->radeon, state->type, state->id);
- unsigned i;
-
- if (state == NULL)
- return NULL;
- nstate->cpm4 = state->cpm4;
- nstate->nbo = state->nbo;
- nstate->nreloc = state->nreloc;
- memcpy(nstate->states, state->states, state->nstates * 4);
- memcpy(nstate->pm4, state->pm4, state->npm4 * 4);
- memcpy(nstate->placement, state->placement, 8 * 4);
- memcpy(nstate->reloc_pm4_id, state->reloc_pm4_id, 8 * 4);
- memcpy(nstate->reloc_bo_id, state->reloc_bo_id, 8 * 4);
- memcpy(nstate->bo_dirty, state->bo_dirty, 4 * 4);
- for (i = 0; i < state->nbo; i++) {
- nstate->bo[i] = radeon_bo_incref(state->radeon, state->bo[i]);
- }
- return nstate;
-}
-
-struct radeon_state *radeon_state_incref(struct radeon_state *state)
-{
- state->refcount++;
- return state;
-}
-
-struct radeon_state *radeon_state_decref(struct radeon_state *state)
-{
- unsigned i;
-
- if (state == NULL)
- return NULL;
- if (--state->refcount > 0) {
- return NULL;
- }
- for (i = 0; i < state->nbo; i++) {
- state->bo[i] = radeon_bo_decref(state->radeon, state->bo[i]);
- }
- free(state->immd);
- free(state->states);
- free(state->pm4);
- memset(state, 0, sizeof(*state));
- free(state);
- return NULL;
+ return 0;
}
int radeon_state_replace_always(struct radeon_state *ostate,
@@ -156,6 +97,7 @@ int radeon_state_pm4(struct radeon_state *state)
return r;
}
state->pm4_crc = crc32(state->pm4, state->cpm4 * 4);
+ state->valid = 1;
return 0;
}