summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bo_legacy.c70
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_cs_legacy.c4
2 files changed, 60 insertions, 14 deletions
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
index c40e140187..03a6299ed8 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
@@ -61,7 +61,6 @@ struct bo_legacy {
uint32_t pending;
int is_pending;
int static_bo;
- int got_dri_texture_obj;
uint32_t offset;
struct bo_legacy_texture_object *tobj;
int validated;
@@ -95,8 +94,8 @@ static void bo_legacy_tobj_destroy(void *data, driTextureObject *t)
struct bo_legacy_texture_object *tobj = (struct bo_legacy_texture_object *)t;
if (tobj->parent) {
- tobj->parent->got_dri_texture_obj = 0;
- tobj->parent->validated = 0;
+ tobj->parent->tobj = NULL;
+ tobj->parent->validated = 0;
}
}
@@ -258,6 +257,23 @@ static int legacy_wait_any_pending(struct bo_manager_legacy *boml)
return 0;
}
+static void legacy_kick_all_buffers(struct bo_manager_legacy *boml)
+{
+ struct bo_legacy *legacy;
+
+ legacy = boml->bos.next;
+ while (legacy != &boml->bos) {
+ if (legacy->tobj) {
+ if (legacy->validated) {
+ driDestroyTextureObject(&legacy->tobj->base);
+ legacy->tobj = 0;
+ legacy->validated = 0;
+ }
+ }
+ legacy = legacy->next;
+ }
+}
+
static struct bo_legacy *bo_allocate(struct bo_manager_legacy *boml,
uint32_t size,
uint32_t alignment,
@@ -286,7 +302,6 @@ static struct bo_legacy *bo_allocate(struct bo_manager_legacy *boml,
bo_legacy->map_count = 0;
bo_legacy->next = NULL;
bo_legacy->prev = NULL;
- bo_legacy->got_dri_texture_obj = 0;
bo_legacy->pnext = NULL;
bo_legacy->pprev = NULL;
bo_legacy->next = boml->bos.next;
@@ -523,27 +538,38 @@ static int bo_vram_validate(struct radeon_bo *bo,
struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
int r;
+ int retry_count = 0, pending_retry = 0;
- if (!bo_legacy->got_dri_texture_obj) {
+ if (!bo_legacy->tobj) {
bo_legacy->tobj = CALLOC(sizeof(struct bo_legacy_texture_object));
bo_legacy->tobj->parent = bo_legacy;
make_empty_list(&bo_legacy->tobj->base);
bo_legacy->tobj->base.totalSize = bo->size;
+ retry:
r = driAllocateTexture(&boml->texture_heap, 1,
&bo_legacy->tobj->base);
if (r) {
- uint8_t *segfault=NULL;
- fprintf(stderr, "Ouch! vram_validate failed %d\n", r);
- *segfault=1;
- return -1;
- }
+ pending_retry = 0;
+ while(boml->cpendings && pending_retry++ < 10000) {
+ legacy_track_pending(boml, 0);
+ retry_count++;
+ if (retry_count > 2) {
+ free(bo_legacy->tobj);
+ bo_legacy->tobj = NULL;
+ fprintf(stderr, "Ouch! vram_validate failed %d\n", r);
+ return -1;
+ }
+ goto retry;
+ }
+ }
bo_legacy->offset = boml->texture_offset +
bo_legacy->tobj->base.memBlock->ofs;
- bo_legacy->got_dri_texture_obj = 1;
bo_legacy->dirty = 1;
}
- if (bo_legacy->got_dri_texture_obj)
+ assert(bo_legacy->tobj->base.memBlock);
+
+ if (bo_legacy->tobj)
driUpdateTextureLRU(&bo_legacy->tobj->base);
if (bo_legacy->dirty || bo_legacy->tobj->base.dirty_images[0]) {
@@ -589,12 +615,21 @@ static int bo_vram_validate(struct radeon_bo *bo,
return 0;
}
+/*
+ * radeon_bo_legacy_validate -
+ * returns:
+ * 0 - all good
+ * -EINVAL - mapped buffer can't be validated
+ * -EAGAIN - restart validation we've kicked all the buffers out
+ */
int radeon_bo_legacy_validate(struct radeon_bo *bo,
uint32_t *soffset,
uint32_t *eoffset)
{
+ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bo->bom;
struct bo_legacy *bo_legacy = (struct bo_legacy*)bo;
int r;
+ int retries = 0;
if (bo_legacy->map_count) {
fprintf(stderr, "bo(%p, %d) is mapped (%d) can't valide it.\n",
@@ -607,9 +642,18 @@ int radeon_bo_legacy_validate(struct radeon_bo *bo,
return 0;
}
if (!(bo->domains & RADEON_GEM_DOMAIN_GTT)) {
+
r = bo_vram_validate(bo, soffset, eoffset);
if (r) {
- return r;
+ legacy_track_pending(boml, 0);
+ legacy_kick_all_buffers(boml);
+ retries++;
+ if (retries == 2) {
+ fprintf(stderr,"legacy bo: failed to get relocations into aperture\n");
+ assert(0);
+ exit(-1);
+ }
+ return -EAGAIN;
}
}
*soffset = bo_legacy->offset;
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
index aa95d86cd4..3acc206a8b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
@@ -216,12 +216,15 @@ static int cs_process_relocs(struct radeon_cs *cs)
csm = (struct cs_manager_legacy*)cs->csm;
relocs = (struct cs_reloc_legacy *)cs->relocs;
+ restart:
for (i = 0; i < cs->crelocs; i++) {
for (j = 0; j < relocs[i].cindices; j++) {
uint32_t soffset, eoffset;
r = radeon_bo_legacy_validate(relocs[i].base.bo,
&soffset, &eoffset);
+ if (r == -EAGAIN)
+ goto restart;
if (r) {
fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n",
relocs[i].base.bo, soffset, eoffset);
@@ -276,7 +279,6 @@ static int cs_emit(struct radeon_cs *cs)
csm->ctx->vtbl.emit_cs_header(cs, csm->ctx);
-
/* append buffer age */
if (IS_R300_CLASS(csm->ctx->radeonScreen)) {
age.scratch.cmd_type = R300_CMD_SCRATCH;