* Jérôme Glisse <glisse@freedesktop.org>
*/
#include <stdio.h>
+#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "drm.h"
#include "radeon_drm.h"
-#include "radeon_bo.h"
-#include "radeon_bo_legacy.h"
#include "radeon_common.h"
+#include "radeon_bocs_wrapper.h"
+
+/* no seriously texmem.c is this screwed up */
+struct bo_legacy_texture_object {
+ driTextureObject base;
+ struct bo_legacy *parent;
+};
struct bo_legacy {
struct radeon_bo base;
- driTextureObject tobj_base;
int map_count;
uint32_t pending;
int is_pending;
- int validated;
int static_bo;
- int got_dri_texture_obj;
- int dirty;
uint32_t offset;
- driTextureObject dri_texture_obj;
+ struct bo_legacy_texture_object *tobj;
+ int validated;
+ int dirty;
void *ptr;
struct bo_legacy *next, *prev;
struct bo_legacy *pnext, *pprev;
static void bo_legacy_tobj_destroy(void *data, driTextureObject *t)
{
- struct bo_legacy *bo_legacy;
-
- bo_legacy = (struct bo_legacy*)((char*)t)-sizeof(struct radeon_bo);
- bo_legacy->got_dri_texture_obj = 0;
- bo_legacy->validated = 0;
+ struct bo_legacy_texture_object *tobj = (struct bo_legacy_texture_object *)t;
+
+ if (tobj->parent) {
+ tobj->parent->tobj = NULL;
+ tobj->parent->validated = 0;
+ }
}
static void inline clean_handles(struct bo_manager_legacy *bom)
static int legacy_wait_any_pending(struct bo_manager_legacy *boml)
{
struct bo_legacy *bo_legacy;
- struct bo_legacy *next;
legacy_get_current_age(boml);
bo_legacy = boml->pending_bos.pnext;
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,
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;
/* dma buffers */
bo_dma_free(&bo_legacy->base);
} else {
+ driDestroyTextureObject(&bo_legacy->tobj->base);
+ bo_legacy->tobj = NULL;
/* free backing store */
free(bo_legacy->ptr);
}
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) {
- make_empty_list(&bo_legacy->dri_texture_obj);
- bo_legacy->dri_texture_obj.totalSize = bo->size;
+ 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->dri_texture_obj);
+ &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->dri_texture_obj.memBlock->ofs;
- bo_legacy->got_dri_texture_obj = 1;
+ bo_legacy->tobj->base.memBlock->ofs;
bo_legacy->dirty = 1;
}
- if (bo_legacy->dirty) {
+
+ 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]) {
/* Copy to VRAM using a blit.
* All memory is 4K aligned. We're using 1024 pixels wide blits.
*/
}
} while (ret == -EAGAIN);
bo_legacy->dirty = 0;
+ bo_legacy->tobj->base.dirty_images[0] = 0;
}
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",
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;
bo_free(bo_legacy);
bo_legacy = next;
}
+ driDestroyTextureHeap(boml->texture_heap);
free(boml->free_handles);
free(boml);
}
return NULL;
}
+ make_empty_list(&bom->texture_swapped);
+
bom->texture_heap = driCreateTextureHeap(0,
bom,
scrn->texSize[0],
(drmTextureRegionPtr)scrn->sarea->tex_list[0],
&scrn->sarea->tex_age[0],
&bom->texture_swapped,
- sizeof(struct bo_legacy),
+ sizeof(struct bo_legacy_texture_object),
&bo_legacy_tobj_destroy);
bom->texture_offset = scrn->texOffset[0];