summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/r600/drm/radeon_ctx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys/r600/drm/radeon_ctx.c')
-rw-r--r--src/gallium/winsys/r600/drm/radeon_ctx.c219
1 files changed, 83 insertions, 136 deletions
diff --git a/src/gallium/winsys/r600/drm/radeon_ctx.c b/src/gallium/winsys/r600/drm/radeon_ctx.c
index 1a12c1023e..50c5e4741e 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))