aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2011-01-04 01:14:00 +0100
committerChristoph Bumiller <[email protected]>2011-01-04 16:14:46 +0100
commit6de94e1012498b6859d9796f2836a162bb0ca4bc (patch)
treead57341116996f0f4d83364c4f1e268a6c346014 /src
parent471025929c893d223668814ad0f8e2bee76aac63 (diff)
nvc0: delete memory caches and fence on screen destruction
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/nvc0/nvc0_fence.c11
-rw-r--r--src/gallium/drivers/nvc0/nvc0_mm.c29
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.c7
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.h3
4 files changed, 50 insertions, 0 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_fence.c b/src/gallium/drivers/nvc0/nvc0_fence.c
index 0387c5940b7..7c214ca9a75 100644
--- a/src/gallium/drivers/nvc0/nvc0_fence.c
+++ b/src/gallium/drivers/nvc0/nvc0_fence.c
@@ -73,6 +73,9 @@ nvc0_fence_emit(struct nvc0_fence *fence)
fence->state = NVC0_FENCE_STATE_EMITTED;
}
+static void
+nvc0_fence_trigger_release_buffers(struct nvc0_fence *fence);
+
void
nvc0_fence_del(struct nvc0_fence *fence)
{
@@ -91,6 +94,13 @@ nvc0_fence_del(struct nvc0_fence *fence)
screen->fence.tail = it;
}
}
+
+ if (fence->buffers) {
+ debug_printf("WARNING: deleting fence with buffers "
+ "still hooked to it !\n");
+ nvc0_fence_trigger_release_buffers(fence);
+ }
+
FREE(fence);
}
@@ -104,6 +114,7 @@ nvc0_fence_trigger_release_buffers(struct nvc0_fence *fence)
nvc0_mm_free(alloc);
alloc = next;
};
+ fence->buffers = NULL;
}
static void
diff --git a/src/gallium/drivers/nvc0/nvc0_mm.c b/src/gallium/drivers/nvc0/nvc0_mm.c
index e031fb393ac..0629dad19c9 100644
--- a/src/gallium/drivers/nvc0/nvc0_mm.c
+++ b/src/gallium/drivers/nvc0/nvc0_mm.c
@@ -243,3 +243,32 @@ nvc0_mm_create(struct nouveau_device *dev, uint32_t domain,
return cache;
}
+static INLINE void
+nvc0_mm_free_slabs(struct list_head *head)
+{
+ struct mm_slab *slab, *next;
+
+ LIST_FOR_EACH_ENTRY_SAFE(slab, next, head, head) {
+ LIST_DEL(&slab->head);
+ nouveau_bo_ref(NULL, &slab->bo);
+ FREE(slab);
+ }
+}
+
+void
+nvc0_mm_destroy(struct nvc0_mman *cache)
+{
+ int i;
+
+ for (i = 0; i < MM_NUM_BUCKETS; ++i) {
+ if (!LIST_IS_EMPTY(&cache->bucket[i].used) ||
+ !LIST_IS_EMPTY(&cache->bucket[i].full))
+ debug_printf("WARNING: destroying GPU memory cache "
+ "with some buffers still in use\n");
+
+ nvc0_mm_free_slabs(&cache->bucket[i].free);
+ nvc0_mm_free_slabs(&cache->bucket[i].used);
+ nvc0_mm_free_slabs(&cache->bucket[i].full);
+ }
+}
+
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index a5641ba90fb..e149b907314 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -197,6 +197,9 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
{
struct nvc0_screen *screen = nvc0_screen(pscreen);
+ nvc0_fence_wait(screen->fence.current);
+ nvc0_fence_reference(&screen->fence.current, NULL);
+
nouveau_bo_ref(NULL, &screen->text);
nouveau_bo_ref(NULL, &screen->tls);
nouveau_bo_ref(NULL, &screen->txc);
@@ -208,6 +211,10 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
if (screen->tic.entries)
FREE(screen->tic.entries);
+ nvc0_mm_destroy(screen->mm_GART);
+ nvc0_mm_destroy(screen->mm_VRAM);
+ nvc0_mm_destroy(screen->mm_VRAM_fe0);
+
nouveau_grobj_free(&screen->fermi);
nouveau_grobj_free(&screen->eng2d);
nouveau_grobj_free(&screen->m2mf);
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h b/src/gallium/drivers/nvc0/nvc0_screen.h
index efa5ff63f16..5c6482be96b 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nvc0/nvc0_screen.h
@@ -89,6 +89,9 @@ struct nvc0_mm_allocation {
extern struct nvc0_mman *
nvc0_mm_create(struct nouveau_device *, uint32_t domain, uint32_t storage_type);
+extern void
+nvc0_mm_destroy(struct nvc0_mman *);
+
extern struct nvc0_mm_allocation *
nvc0_mm_allocate(struct nvc0_mman *,
uint32_t size, struct nouveau_bo **, uint32_t *offset);