diff options
author | Jerome Glisse <[email protected]> | 2010-08-30 17:56:59 -0400 |
---|---|---|
committer | Jerome Glisse <[email protected]> | 2010-09-01 13:16:23 -0400 |
commit | 66e4cb1cd5a55402606a09417349d2be8b009e89 (patch) | |
tree | b9c4e20211fbfc1a979667598f141116f4a5cebd /src/gallium/winsys | |
parent | 15ce70252c5357081a61f3494261c7e343174301 (diff) |
r600g: avoid dynamic allocation of states
Make state statically allocated, this kills a bunch of code
and avoid intensive use of malloc/free. There is still a lot
of useless duplicate function wrapping that can be kill. This
doesn't improve yet performance, needs to avoid memcpy states
in radeon_ctx_set_draw and to avoid rebuilding vs_resources,
dsa, scissor, cb_cntl, ... states at each draw command.
Signed-off-by: Jerome Glisse <[email protected]>
Diffstat (limited to 'src/gallium/winsys')
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_state.c | 4 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/radeon.c | 26 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/radeon_ctx.c | 219 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/radeon_draw.c | 113 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/radeon_priv.h | 13 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/radeon_state.c | 55 |
6 files changed, 122 insertions, 308 deletions
diff --git a/src/gallium/winsys/r600/drm/r600_state.c b/src/gallium/winsys/r600/drm/r600_state.c index f6a428e884d..71d65f0feab 100644 --- a/src/gallium/winsys/r600/drm/r600_state.c +++ b/src/gallium/winsys/r600/drm/r600_state.c @@ -367,7 +367,6 @@ 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) { @@ -485,11 +484,10 @@ static void r600_build_types_array(struct radeon *radeon) } else { for (j = 0; j < R600_SHADER_MAX; j++) { if (r600_stypes[i].reginfo[j].shader_type) - id += r600_stypes[i].num; + id += r600_stypes[i].num; } } } - radeon->nstate = id; radeon->stype = r600_stypes; radeon->nstype = STYPES_SIZE; diff --git a/src/gallium/winsys/r600/drm/radeon.c b/src/gallium/winsys/r600/drm/radeon.c index 2b16e3ce884..e2d813ebac7 100644 --- a/src/gallium/winsys/r600/drm/radeon.c +++ b/src/gallium/winsys/r600/drm/radeon.c @@ -42,24 +42,13 @@ 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; - int r; + int r, i, id; radeon = calloc(1, sizeof(*radeon)); if (radeon == NULL) { - fake(); return NULL; } radeon->fd = fd; @@ -131,6 +120,19 @@ struct radeon *radeon_new(int fd, unsigned device) __func__, radeon->device); break; } + radeon->state_type_id = calloc(radeon->nstype, sizeof(unsigned)); + if (radeon->state_type_id == NULL) { + return radeon_decref(radeon); + } + for (i = 0, id = 0; i < radeon->nstype; i++) { + radeon->state_type_id[i] = id; + for (int j = 0; j < radeon->nstype; j++) { + if (radeon->stype[j].stype != i) + continue; + id += radeon->stype[j].num; + } + } + radeon->nstate_per_shader = id; return radeon; } diff --git a/src/gallium/winsys/r600/drm/radeon_ctx.c b/src/gallium/winsys/r600/drm/radeon_ctx.c index 1a12c1023e1..50c5e4741e1 100644 --- a/src/gallium/winsys/r600/drm/radeon_ctx.c +++ b/src/gallium/winsys/r600/drm/radeon_ctx.c @@ -30,21 +30,16 @@ #include "radeon_drm.h" #include "bof.h" -int radeon_ctx_set_bo_new(struct radeon_ctx *ctx, struct radeon_bo *bo) +static 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 >= RADEON_CTX_MAX_PM4) + return -EBUSY; ctx->bo[ctx->nbo] = bo; ctx->nbo++; return 0; } -struct radeon_bo *radeon_ctx_get_bo(struct radeon_ctx *ctx, unsigned reloc) +static struct radeon_bo *radeon_ctx_get_bo(struct radeon_ctx *ctx, unsigned reloc) { struct radeon_cs_reloc *greloc; unsigned i; @@ -59,7 +54,7 @@ struct radeon_bo *radeon_ctx_get_bo(struct radeon_ctx *ctx, unsigned reloc) return NULL; } -void radeon_ctx_get_placement(struct radeon_ctx *ctx, unsigned reloc, u32 *placement) +static void radeon_ctx_get_placement(struct radeon_ctx *ctx, unsigned reloc, u32 *placement) { struct radeon_cs_reloc *greloc; unsigned i; @@ -76,50 +71,58 @@ void radeon_ctx_get_placement(struct radeon_ctx *ctx, unsigned reloc, u32 *place } } -struct radeon_ctx *radeon_ctx(struct radeon *radeon) +void radeon_ctx_clear(struct radeon_ctx *ctx) { - 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; + for (int i = 0; i < ctx->nbo; i++) { + ctx->bo[i] = radeon_bo_decref(ctx->radeon, ctx->bo[i]); + } + ctx->ndwords = RADEON_CTX_MAX_PM4; + ctx->cdwords = 0; + ctx->nreloc = 0; + ctx->nbo = 0; } -struct radeon_ctx *radeon_ctx_incref(struct radeon_ctx *ctx) +int radeon_ctx_init(struct radeon_ctx *ctx, struct radeon *radeon) { - ctx->refcount++; - return ctx; + if (radeon == NULL) + return -EINVAL; + memset(ctx, 0, sizeof(struct radeon_ctx)); + ctx->radeon = radeon_incref(radeon); + radeon_ctx_clear(ctx); + ctx->pm4 = malloc(RADEON_CTX_MAX_PM4 * 4); + if (ctx->pm4 == NULL) { + radeon_ctx_fini(ctx); + return -ENOMEM; + } + ctx->reloc = malloc(sizeof(struct radeon_cs_reloc) * RADEON_CTX_MAX_PM4); + if (ctx->reloc == NULL) { + radeon_ctx_fini(ctx); + return -ENOMEM; + } + ctx->bo = malloc(sizeof(void *) * RADEON_CTX_MAX_PM4); + if (ctx->bo == NULL) { + radeon_ctx_fini(ctx); + return -ENOMEM; + } + return 0; } -struct radeon_ctx *radeon_ctx_decref(struct radeon_ctx *ctx) +void radeon_ctx_fini(struct radeon_ctx *ctx) { unsigned i; if (ctx == NULL) - return NULL; - if (--ctx->refcount > 0) { - return NULL; - } + return; - 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->state); - free(ctx->draw); free(ctx->bo); free(ctx->pm4); free(ctx->reloc); memset(ctx, 0, sizeof(*ctx)); free(ctx); - return NULL; } static int radeon_ctx_state_bo(struct radeon_ctx *ctx, struct radeon_state *state) @@ -152,17 +155,17 @@ int radeon_ctx_submit(struct radeon_ctx *ctx) uint64_t chunk_array[2]; int r = 0; - if (!ctx->cpm4) + if (!ctx->cdwords) return 0; #if 0 - for (r = 0; r < ctx->cpm4; r++) { + for (r = 0; r < ctx->cdwords; r++) { fprintf(stderr, "0x%08X\n", ctx->pm4[r]); } #endif drmib.num_chunks = 2; drmib.chunks = (uint64_t)(uintptr_t)chunk_array; chunks[0].chunk_id = RADEON_CHUNK_ID_IB; - chunks[0].length_dw = ctx->cpm4; + chunks[0].length_dw = ctx->cdwords; chunks[0].chunk_data = (uint64_t)(uintptr_t)ctx->pm4; chunks[1].chunk_id = RADEON_CHUNK_ID_RELOCS; chunks[1].length_dw = ctx->nreloc * sizeof(struct radeon_cs_reloc) / 4; @@ -180,7 +183,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) { @@ -188,14 +190,13 @@ 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 >= RADEON_CTX_MAX_PM4) { + return -EBUSY; + } + 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; @@ -208,11 +209,14 @@ static int radeon_ctx_state_schedule(struct radeon_ctx *ctx, struct radeon_state if (state == NULL) return 0; - memcpy(&ctx->pm4[ctx->id], state->pm4, state->cpm4 * 4); + if (state->cpm4 > ctx->ndwords) { + return -EBUSY; + } + memcpy(&ctx->pm4[ctx->cdwords], state->pm4, state->cpm4 * 4); for (i = 0; i < state->nreloc; i++) { rid = state->reloc_pm4_id[i]; bid = state->reloc_bo_id[i]; - cid = ctx->id + rid; + cid = ctx->cdwords + rid; r = radeon_ctx_reloc(ctx, state->bo[bid], cid, &state->placement[bid * 2]); if (r) { @@ -220,120 +224,65 @@ static int radeon_ctx_state_schedule(struct radeon_ctx *ctx, struct radeon_state return r; } } - ctx->id += state->cpm4; + ctx->cdwords += state->cpm4; + ctx->ndwords -= state->cpm4; return 0; } int radeon_ctx_set_query_state(struct radeon_ctx *ctx, struct radeon_state *state) { - void *tmp; int r = 0; /* !!! ONLY ACCEPT QUERY STATE HERE !!! */ - if (state->stype->stype != R600_STATE_QUERY_BEGIN && state->stype->stype != R600_STATE_QUERY_END) { - return -EINVAL; - } r = radeon_state_pm4(state); if (r) return r; - if ((ctx->draw_cpm4 + state->cpm4) > RADEON_CTX_MAX_PM4) { - /* need to flush */ - return -EBUSY; - } - if (state->cpm4 >= RADEON_CTX_MAX_PM4) { - fprintf(stderr, "%s single state too big %d, max %d\n", - __func__, state->cpm4, RADEON_CTX_MAX_PM4); - return -EINVAL; - } - tmp = realloc(ctx->state, (ctx->nstate + 1) * sizeof(void*)); - if (tmp == NULL) - return -ENOMEM; - ctx->state = tmp; - ctx->state[ctx->nstate++] = radeon_state_incref(state); /* BEGIN/END query are balanced in the same cs so account for END * END query when scheduling BEGIN query */ - if (state->stype->stype == R600_STATE_QUERY_BEGIN) { - ctx->draw_cpm4 += state->cpm4 * 2; + switch (state->stype->stype) { + case R600_STATE_QUERY_BEGIN: + /* is there enough place for begin & end */ + if ((state->cpm4 * 2) > ctx->ndwords) + return -EBUSY; + ctx->ndwords -= state->cpm4; + break; + case R600_STATE_QUERY_END: + ctx->ndwords += state->cpm4; + break; + default: + return -EINVAL; } - return 0; + return radeon_ctx_state_schedule(ctx, state); } -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 previous_cdwords; 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++) { + for (int i = 0; i < (ctx->radeon->nstate_per_shader * R600_SHADER_MAX); i++) { r = radeon_ctx_state_bo(ctx, draw->state[i]); if (r) return r; } - r = radeon_draw_check(draw); - if (r) - return r; - if (draw->cpm4 >= RADEON_CTX_MAX_PM4) { - fprintf(stderr, "%s single draw too big %d, max %d\n", - __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; + previous_cdwords = ctx->cdwords; + for (int i = 0, id = 0; i < ctx->radeon->nstate_per_shader; i++) { + for (int j = 0; j < R600_SHADER_MAX; j++) { + id = j * ctx->radeon->nstate_per_shader + i; + if (draw->state[id]) { + r = radeon_ctx_state_schedule(ctx, draw->state[id]); + if (r) { + ctx->cdwords = previous_cdwords; + return r; } - } 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->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; 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; -} - +#if 0 int radeon_ctx_pm4(struct radeon_ctx *ctx) { unsigned i; @@ -345,9 +294,6 @@ int radeon_ctx_pm4(struct radeon_ctx *ctx) 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; } if (ctx->id != ctx->draw_cpm4) { fprintf(stderr, "%s miss predicted pm4 size %d for %d\n", @@ -357,6 +303,7 @@ int radeon_ctx_pm4(struct radeon_ctx *ctx) ctx->cpm4 = ctx->draw_cpm4; return 0; } +#endif void radeon_ctx_dump_bof(struct radeon_ctx *ctx, const char *file) { @@ -384,8 +331,8 @@ printf("%d relocs\n", ctx->nreloc); bof_decref(blob); blob = NULL; /* dump cs */ -printf("%d pm4\n", ctx->cpm4); - blob = bof_blob(ctx->cpm4 * 4, ctx->pm4); +printf("%d pm4\n", ctx->cdwords); + blob = bof_blob(ctx->cdwords * 4, ctx->pm4); if (blob == NULL) goto out_err; if (bof_object_set(root, "pm4", blob)) diff --git a/src/gallium/winsys/r600/drm/radeon_draw.c b/src/gallium/winsys/r600/drm/radeon_draw.c index 0eacdc74a03..b992c4a55dc 100644 --- a/src/gallium/winsys/r600/drm/radeon_draw.c +++ b/src/gallium/winsys/r600/drm/radeon_draw.c @@ -31,116 +31,27 @@ /* * 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; - 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; -} - -int radeon_draw_set_new(struct radeon_draw *draw, struct radeon_state *state) -{ - int id; - if (state == NULL) - return 0; - - id = state->stype->base_id + (state->id + (state->stype->num * state->shader_index)); - if (id > draw->radeon->nstate) - { - return -EINVAL; - } - draw->state[id] = radeon_state_decref(draw->state[id]); - draw->state[id] = state; + draw->state = calloc(radeon->nstate_per_shader * R600_SHADER_MAX, sizeof(void*)); + if (draw->state == NULL) + return -ENOMEM; return 0; } -int radeon_draw_set(struct radeon_draw *draw, struct radeon_state *state) +void radeon_draw_bind(struct radeon_draw *draw, struct radeon_state *state) { if (state == NULL) - return 0; - radeon_state_incref(state); - return radeon_draw_set_new(draw, state); + return; + draw->state[state->state_id] = state; } -int radeon_draw_check(struct radeon_draw *draw) +void radeon_draw_unbind(struct radeon_draw *draw, struct radeon_state *state) { - 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; - } - } - 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; + if (state == NULL) + return; + if (draw->state[state->state_id] == state) { + draw->state[state->state_id] = NULL; } - return 0; } diff --git a/src/gallium/winsys/r600/drm/radeon_priv.h b/src/gallium/winsys/r600/drm/radeon_priv.h index af5319efd1f..84e552ba4d3 100644 --- a/src/gallium/winsys/r600/drm/radeon_priv.h +++ b/src/gallium/winsys/r600/drm/radeon_priv.h @@ -58,9 +58,10 @@ struct radeon { int refcount; unsigned device; unsigned family; - unsigned nstate; - unsigned nstype; - struct radeon_stype_info *stype; + unsigned nstype; + unsigned nstate_per_shader; + unsigned *state_type_id; + struct radeon_stype_info *stype; }; extern struct radeon *radeon_new(int fd, unsigned device); @@ -69,12 +70,6 @@ extern struct radeon *radeon_decref(struct radeon *radeon); extern unsigned radeon_family_from_device(unsigned device); extern int radeon_is_family_compatible(unsigned family1, unsigned family2); -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); -int radeon_ctx_set_draw_new(struct radeon_ctx *ctx, struct radeon_draw *draw); -int radeon_ctx_draw(struct radeon_ctx *ctx); - /* * r600/r700 context functions */ diff --git a/src/gallium/winsys/r600/drm/radeon_state.c b/src/gallium/winsys/r600/drm/radeon_state.c index d4e622cf7fd..ac60485b280 100644 --- a/src/gallium/winsys/r600/drm/radeon_state.c +++ b/src/gallium/winsys/r600/drm/radeon_state.c @@ -32,9 +32,8 @@ /* * state core functions */ -struct radeon_state *radeon_state_shader(struct radeon *radeon, u32 stype, u32 id, u32 shader_type) +int radeon_state_init(struct radeon_state *state, struct radeon *radeon, u32 stype, u32 id, u32 shader_type) { - struct radeon_state *state; struct radeon_stype_info *found = NULL; int i, j, shader_index = -1; @@ -67,12 +66,11 @@ struct radeon_state *radeon_state_shader(struct radeon *radeon, u32 stype, u32 i if (!found) { fprintf(stderr, "%s invalid type %d/id %d/shader class %d\n", __func__, stype, id, shader_type); - return NULL; + return -EINVAL; } - state = calloc(1, sizeof(*state)); - if (state == NULL) - return NULL; + memset(state, 0, sizeof(struct radeon_state)); + state->state_id = radeon->nstate_per_shader * shader_index + radeon->state_type_id[stype] + id; state->stype = found; state->radeon = radeon; state->id = id; @@ -80,7 +78,7 @@ struct radeon_state *radeon_state_shader(struct radeon *radeon, u32 stype, u32 i state->refcount = 1; state->npm4 = found->npm4; state->nstates = found->reginfo[shader_index].nstates; - return state; + return 0; } int radeon_state_convert(struct radeon_state *state, u32 stype, u32 id, u32 shader_type) @@ -130,57 +128,20 @@ int radeon_state_convert(struct radeon_state *state, u32 stype, u32 id, u32 shad state->stype = found; state->id = id; state->shader_index = shader_index; + state->state_id = state->radeon->nstate_per_shader * shader_index + state->radeon->state_type_id[stype] + id; return radeon_state_pm4(state); } -struct radeon_state *radeon_state(struct radeon *radeon, u32 type, u32 id) -{ - return radeon_state_shader(radeon, type, id, 0); -} - -struct radeon_state *radeon_state_duplicate(struct radeon_state *state) -{ - struct radeon_state *nstate = radeon_state_shader(state->radeon, state->stype->stype, state->id, (1 << state->shader_index)); - 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) +void radeon_state_fini(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]); } - memset(state, 0, sizeof(*state)); - free(state); - return NULL; + memset(state, 0, sizeof(struct radeon_state)); } int radeon_state_replace_always(struct radeon_state *ostate, |