summaryrefslogtreecommitdiff
path: root/src/radeon_ctx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/radeon_ctx.c')
-rw-r--r--src/radeon_ctx.c436
1 files changed, 220 insertions, 216 deletions
diff --git a/src/radeon_ctx.c b/src/radeon_ctx.c
index 4e0ba56..1188b09 100644
--- a/src/radeon_ctx.c
+++ b/src/radeon_ctx.c
@@ -24,56 +24,33 @@
* Jerome Glisse
*/
#include <stdlib.h>
+#include <string.h>
#include "radeon_priv.h"
+#include "radeon_drm.h"
-#pragma pack(1)
-struct cs_reloc_gem {
- uint32_t handle;
- uint32_t read_domain;
- uint32_t write_domain;
- uint32_t flags;
-};
-#pragma pack()
-
-int radeon_ctx_set_object_new(struct radeon_ctx *ctx,
- struct radeon_object *bo,
- int id)
+int radeon_ctx_set_bo_new(struct radeon_ctx *ctx, struct radeon_bo *bo)
{
void *ptr;
- ptr = realloc(ctx->bo, sizeof(struct radeon_ctx_bo) * (ctx->nbo + 1));
+ ptr = realloc(ctx->bo, sizeof(struct radeon_bo) * (ctx->nbo + 1));
if (ptr == NULL) {
return -ENOMEM;
}
ctx->bo = ptr;
- ctx->bo[ctx->nbo].bo = bo;
- ctx->bo[ctx->nbo].id = id;
+ ctx->bo[ctx->nbo] = bo;
ctx->nbo++;
return 0;
}
-struct radeon_object *radeon_ctx_get_object(struct radeon_ctx *ctx, unsigned handle)
-{
- unsigned i;
-
- for (i = 0; i < ctx->nbo; i++) {
- if (ctx->bo[i].bo->handle == handle) {
- return radeon_object_incref(ctx->bo[i].bo);
- }
- }
- return NULL;
-}
-
-struct radeon_object *radeon_ctx_get_bo(struct radeon_ctx *ctx, unsigned reloc)
+struct radeon_bo *radeon_ctx_get_bo(struct radeon_ctx *ctx, unsigned reloc)
{
- struct cs_reloc_gem *greloc;
+ struct radeon_cs_reloc *greloc;
unsigned i;
- greloc = (struct cs_reloc_gem *)&ctx->reloc[reloc];
+ greloc = (void *)(((u8 *)ctx->reloc) + reloc * 4);
for (i = 0; i < ctx->nbo; i++) {
- if (ctx->bo[i].bo->handle == greloc->handle) {
- ctx->bo[i].id = reloc;
- return radeon_object_incref(ctx->bo[i].bo);
+ if (ctx->bo[i]->handle == greloc->handle) {
+ return radeon_bo_incref(ctx->radeon, ctx->bo[i]);
}
}
fprintf(stderr, "%s no bo for reloc[%d 0x%08X] %d\n", __func__, reloc, greloc->handle, ctx->nbo);
@@ -82,14 +59,14 @@ struct radeon_object *radeon_ctx_get_bo(struct radeon_ctx *ctx, unsigned reloc)
void radeon_ctx_get_placement(struct radeon_ctx *ctx, unsigned reloc, u32 *placement)
{
- struct cs_reloc_gem *greloc;
+ struct radeon_cs_reloc *greloc;
unsigned i;
placement[0] = 0;
placement[1] = 0;
- greloc = (struct cs_reloc_gem *)&ctx->reloc[reloc];
+ greloc = (void *)(((u8 *)ctx->reloc) + reloc * 4);
for (i = 0; i < ctx->nbo; i++) {
- if (ctx->bo[i].bo->handle == greloc->handle) {
+ if (ctx->bo[i]->handle == greloc->handle) {
placement[0] = greloc->read_domain | greloc->write_domain;
placement[1] = placement[0];
return;
@@ -97,45 +74,52 @@ void radeon_ctx_get_placement(struct radeon_ctx *ctx, unsigned reloc, u32 *place
}
}
-struct radeon_ctx *radeon_ctx(struct radeon *radeon, unsigned device)
+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);
- if (radeon == NULL) {
- ctx->radeon = radeon_new(-1, device);
- if (ctx->radeon == NULL) {
- free(ctx);
- return NULL;
- }
- }
return ctx;
}
-void radeon_ctx_destroy(struct radeon_ctx *ctx)
+struct radeon_ctx *radeon_ctx_incref(struct radeon_ctx *ctx)
+{
+ ctx->refcount++;
+ return ctx;
+}
+
+struct radeon_ctx *radeon_ctx_decref(struct radeon_ctx *ctx)
{
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].bo = radeon_object_decref(ctx->bo[i].bo);
+ ctx->bo[i] = radeon_bo_decref(ctx->radeon, ctx->bo[i]);
}
- radeon_decref(ctx->radeon);
+ ctx->radeon = radeon_decref(ctx->radeon);
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)
+static int radeon_ctx_state_bo(struct radeon_ctx *ctx, struct radeon_state *state)
{
unsigned i, j;
int r;
@@ -144,12 +128,12 @@ static int radeon_ctx_state_bo(struct radeon_ctx *ctx,
return 0;
for (i = 0; i < state->nbo; i++) {
for (j = 0; j < ctx->nbo; j++) {
- if (state->bo[i] == ctx->bo[j].bo)
+ if (state->bo[i] == ctx->bo[j])
break;
}
if (j == ctx->nbo) {
- radeon_object_incref(state->bo[i]);
- r = radeon_ctx_set_object_new(ctx, state->bo[i], -1);
+ radeon_bo_incref(ctx->radeon, state->bo[i]);
+ r = radeon_ctx_set_bo_new(ctx, state->bo[i]);
if (r)
return r;
}
@@ -157,95 +141,87 @@ static int radeon_ctx_state_bo(struct radeon_ctx *ctx,
return 0;
}
-int radeon_ctx_set_draw_new(struct radeon_ctx *ctx, struct radeon_draw *draw)
-{
- struct radeon_draw **ndraw;
- unsigned i;
- int r;
-
- 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]);
- if (r)
- return r;
- }
- ctx->draw[ctx->ndraw++] = draw;
- ctx->cdraw = draw;
- return 0;
-}
-
-struct radeon_object *radeon_object(struct radeon_bo *bo, unsigned handle,
- unsigned size, void *ptr)
-{
- struct radeon_object *object;
-
- object = calloc(1, sizeof(*object));
- if (object == NULL)
- return NULL;
- object->data = calloc(1, size);
- if (object->data == NULL) {
- return NULL;
- }
- object->size = size;
- object->handle = handle;
- object->bo = bo;
- object->refcount = 1;
- if (ptr)
- memcpy(object->data, ptr, size);
- return object;
-}
-
-struct radeon_object *radeon_object_incref(struct radeon_object *object)
-{
- object->refcount++;
- return object;
-}
-
-struct radeon_object *radeon_object_decref(struct radeon_object *object)
+static void radeon_ctx_dump_bof(struct radeon_ctx *ctx)
{
- if (object == NULL)
- return NULL;
- if (--object->refcount > 0) {
- return NULL;
- }
- free(object->data);
- object->data = NULL;
- object->bo = radeon_bo_unref(object->bo);
- free(object);
- return NULL;
-}
-
-int radeon_ctx_allocate_bo(struct radeon_ctx *ctx)
-{
- struct radeon *radeon = ctx->radeon;
- struct radeon_object *bo;
- struct cs_reloc_gem *greloc;
+ bof_t *bcs, *blob, *array, *bo, *size, *handle, *device_id, *root;
+ char tmp[256];
unsigned i;
+ root = device_id = bcs = blob = array = bo = size = handle = NULL;
+ root = bof_object();
+ if (root == NULL)
+ goto out_err;
+ device_id = bof_int32(ctx->radeon->device);
+ if (device_id == NULL)
+ return;
+ if (bof_object_set(root, "device_id", device_id))
+ goto out_err;
+ bof_decref(device_id);
+ device_id = NULL;
+ /* dump relocs */
+ blob = bof_blob(ctx->nreloc * 16, ctx->reloc);
+ if (blob == NULL)
+ goto out_err;
+ if (bof_object_set(root, "reloc", blob))
+ goto out_err;
+ bof_decref(blob);
+ blob = NULL;
+ /* dump cs */
+ blob = bof_blob(ctx->cpm4 * 4, ctx->pm4);
+ if (blob == NULL)
+ goto out_err;
+ if (bof_object_set(root, "pm4", blob))
+ goto out_err;
+ bof_decref(blob);
+ blob = NULL;
+ /* dump bo */
+ array = bof_array();
+ if (array == NULL)
+ goto out_err;
for (i = 0; i < ctx->nbo; i++) {
- bo = ctx->bo[i].bo;
- bo->bo = radeon_bo_open(radeon->bom, 0, bo->size, 0,
- RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
- if (bo->bo == NULL) {
- return -ENOMEM;
- }
- radeon_bo_map(bo->bo, 1);
- memcpy(bo->bo->ptr, bo->data, bo->size);
- radeon_bo_unmap(bo->bo);
- }
- for (i = 0; i < ctx->nbo; i++) {
- if (ctx->bo[i].id >= 0) {
- greloc = (struct cs_reloc_gem *)&ctx->reloc[ctx->bo[i].id];
- greloc->handle = ctx->bo[i].bo->bo->handle;
- }
- }
- for (i = 0; i < ctx->nbo; i++) {
- ctx->bo[i].bo->handle = ctx->bo[i].bo->bo->handle;
+ bo = bof_object();
+ if (bo == NULL)
+ goto out_err;
+ size = bof_int32(ctx->bo[i]->size);
+ if (size == NULL)
+ goto out_err;
+ if (bof_object_set(bo, "size", size))
+ goto out_err;
+ bof_decref(size);
+ size = NULL;
+ handle = bof_int32(ctx->bo[i]->handle);
+ if (handle == NULL)
+ goto out_err;
+ if (bof_object_set(bo, "handle", handle))
+ goto out_err;
+ bof_decref(handle);
+ handle = NULL;
+ radeon_bo_map(ctx->radeon, ctx->bo[i]);
+ blob = bof_blob(ctx->bo[i]->size, ctx->bo[i]->data);
+ radeon_bo_unmap(ctx->radeon, ctx->bo[i]);
+ if (blob == NULL)
+ goto out_err;
+ if (bof_object_set(bo, "data", blob))
+ goto out_err;
+ bof_decref(blob);
+ blob = NULL;
+ if (bof_array_append(array, bo))
+ goto out_err;
+ bof_decref(bo);
+ bo = NULL;
}
- return 0;
+ if (bof_object_set(root, "bo", array))
+ goto out_err;
+ sprintf(tmp, "d-0x%04X.bof", ctx->radeon->device);
+ bof_dump_file(root, tmp);
+out_err:
+ bof_decref(blob);
+ bof_decref(array);
+ bof_decref(bo);
+ bof_decref(size);
+ bof_decref(handle);
+ bof_decref(device_id);
+ bof_decref(root);
}
int radeon_ctx_submit(struct radeon_ctx *ctx)
@@ -256,7 +232,6 @@ int radeon_ctx_submit(struct radeon_ctx *ctx)
int r = 0;
#if 0
- printf("reloc %d %d %d pm4 %d\n", ctx->reloc_ndw, ctx->reloc_ndw / 4, ctx->nbo, ctx->cpm4);
for (r = 0; r < ctx->cpm4; r++) {
fprintf(stderr, "0x%08X\n", ctx->pm4[r]);
}
@@ -267,7 +242,7 @@ int radeon_ctx_submit(struct radeon_ctx *ctx)
chunks[0].length_dw = ctx->cpm4;
chunks[0].chunk_data = (uint64_t)(uintptr_t)ctx->pm4;
chunks[1].chunk_id = RADEON_CHUNK_ID_RELOCS;
- chunks[1].length_dw = ctx->reloc_ndw;
+ chunks[1].length_dw = ctx->nreloc * sizeof(struct radeon_cs_reloc) / 4;
chunks[1].chunk_data = (uint64_t)(uintptr_t)ctx->reloc;
chunk_array[0] = (uint64_t)(uintptr_t)&chunks[0];
chunk_array[1] = (uint64_t)(uintptr_t)&chunks[1];
@@ -283,39 +258,28 @@ int radeon_ctx_draw(struct radeon_ctx *ctx)
return ctx->radeon->asic->ctx_draw(ctx);
}
-int radeon_ctx_reloc(struct radeon_ctx *ctx, struct radeon_object *bo,
+int radeon_ctx_reloc(struct radeon_ctx *ctx, struct radeon_bo *bo,
unsigned id, unsigned *placement)
{
unsigned i;
- void *ptr;
- struct cs_reloc_gem *greloc;
+ struct radeon_cs_reloc *ptr;
- for (i = 0; i < ctx->nbo; i++) {
- if (ctx->bo[i].bo == bo) {
- if (ctx->bo[i].id >= 0) {
- ctx->pm4[id] = ctx->bo[i].id;
- return 0;
- }
- break;
+ for (i = 0; i < ctx->nreloc; i++) {
+ if (ctx->reloc[i].handle == bo->handle) {
+ ctx->pm4[id] = i * sizeof(struct radeon_cs_reloc) / 4;
+ return 0;
}
}
- if (i == ctx->nbo) {
- fprintf(stderr, "%s bo %p 0x%08X unknown to context\n",
- __func__, bo, bo->handle);
- return -EINVAL;
- }
- ptr = realloc(ctx->reloc, sizeof(struct cs_reloc_gem) + ctx->reloc_ndw *4);
+ ptr = realloc(ctx->reloc, sizeof(struct radeon_cs_reloc) * (ctx->nreloc + 1));
if (ptr == NULL)
return -ENOMEM;
ctx->reloc = ptr;
- greloc = (struct cs_reloc_gem *)&ctx->reloc[ctx->reloc_ndw];
- greloc->handle = bo->bo->handle;
- greloc->read_domain = placement[0] | placement [1];
- greloc->write_domain = placement[0] | placement [1];
- greloc->flags = 0;
- ctx->bo[i].id = ctx->reloc_ndw;
- ctx->pm4[id] = ctx->bo[i].id;
- ctx->reloc_ndw += sizeof(struct cs_reloc_gem) / 4;
+ 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;
+ ctx->pm4[id] = ctx->nreloc * sizeof(struct radeon_cs_reloc) / 4;
+ ctx->nreloc++;
return 0;
}
@@ -341,73 +305,113 @@ 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)
+
+void *copy_object(void *ptr, unsigned size)
{
- struct radeon_draw *draw;
- unsigned i;
- int r;
+ void *copy;
- draw = ctx->draw[id];
- for (i = 0; i < draw->nstate; i++) {
- r = radeon_ctx_state_schedule(ctx, draw->state[i]);
- if (r)
- return r;
- }
- return 0;
+ copy = calloc(1, size);
+ if (copy == NULL)
+ return NULL;
+ memcpy(copy, ptr, size);
+ return copy;
}
-#endif
-int radeon_ctx_draw_set_reg(struct radeon_ctx *ctx, unsigned offset, u32 value)
+
+int radeon_ctx_set_draw_new(struct radeon_ctx *ctx, struct radeon_draw *draw)
{
- struct radeon_draw *draw;
- struct radeon *radeon = ctx->radeon;
- struct radeon_object *bo;
- unsigned id, stateid, typeid, boid, reloc;
- int r;
+ struct radeon_draw *pdraw = NULL;
+ struct radeon_draw **ndraw;
+ struct radeon_state *nstate, *ostate;
+ unsigned cpm4, i, cstate;
+ void *tmp;
+ int r = 0;
- draw = ctx->cdraw;
- if (draw == NULL) {
- draw = radeon_draw(ctx->radeon);
- if (draw == NULL)
- return -ENOMEM;
- r = radeon_ctx_set_draw_new(ctx, draw);
- if (r) {
- radeon_draw_decref(draw);
+ 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]);
+ if (r)
return r;
- }
}
- r = radeon_reg_id(radeon, offset, &typeid, &stateid, &id);
- if (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;
}
- if (draw->state[stateid] == NULL) {
- draw->state[stateid] = radeon_state(radeon, typeid, stateid);
- if (draw->state[stateid] == NULL)
- return -ENOMEM;
- };
- draw->state[stateid]->states[id] = value;
- if (radeon->type[typeid].regs[id].need_reloc) {
- r = radeon_ctx_next_reloc(ctx, &reloc);
- if (r)
- return r;
- bo = radeon_ctx_get_bo(ctx, reloc);
- if (bo == NULL)
- return -ENOMEM;
- boid = radeon->type[typeid].regs[id].bo_id;
- radeon_object_decref(draw->state[stateid]->bo[boid]);
- draw->state[stateid]->bo[boid] = bo;
- radeon_ctx_get_placement(ctx, reloc, &draw->state[stateid]->placement[boid * 2]);
+ 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;
+ }
+ }
+ }
+ /* 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;
}
-void *copy_object(void *ptr, unsigned size)
+int radeon_ctx_set_draw(struct radeon_ctx *ctx, struct radeon_draw *draw)
{
- void *copy;
+ int r;
- copy = calloc(1, size);
- if (copy == NULL)
- return NULL;
- memcpy(copy, ptr, size);
- return copy;
+ 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;
+ 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;
+ }
+ if (ctx->id != ctx->draw_cpm4) {
+ fprintf(stderr, "%s miss predicted pm4 size %d for %d\n",
+ __func__, ctx->draw_cpm4, ctx->id);
+ return -EINVAL;
+ }
+ ctx->cpm4 = ctx->draw_cpm4;
+ return 0;
}