diff options
author | Christoph Bumiller <[email protected]> | 2011-01-04 01:14:00 +0100 |
---|---|---|
committer | Christoph Bumiller <[email protected]> | 2011-01-04 16:14:46 +0100 |
commit | 6de94e1012498b6859d9796f2836a162bb0ca4bc (patch) | |
tree | ad57341116996f0f4d83364c4f1e268a6c346014 | |
parent | 471025929c893d223668814ad0f8e2bee76aac63 (diff) |
nvc0: delete memory caches and fence on screen destruction
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_fence.c | 11 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_mm.c | 29 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_screen.c | 7 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_screen.h | 3 |
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); |