nvc0: delete memory caches and fence on screen destruction
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Tue, 4 Jan 2011 00:14:00 +0000 (01:14 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Tue, 4 Jan 2011 15:14:46 +0000 (16:14 +0100)
src/gallium/drivers/nvc0/nvc0_fence.c
src/gallium/drivers/nvc0/nvc0_mm.c
src/gallium/drivers/nvc0/nvc0_screen.c
src/gallium/drivers/nvc0/nvc0_screen.h

index 0387c5940b75bbc22f92e33fa00036784ecd1d83..7c214ca9a7544cee73a98666f1f0a3279512269f 100644 (file)
@@ -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
index e031fb393ac46c76a43e1fce0ba8b8ee160c59be..0629dad19c9726bd493ce6cc0e2386aede4ee09c 100644 (file)
@@ -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);
+   }
+}
+
index a5641ba90fb09b95db5e0f324923b33c043b9626..e149b90731404d84c22096786dd3c5264590f3ed 100644 (file)
@@ -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);
index efa5ff63f16fa5b098700b3aee09a278b0d87328..5c6482be96b1b0ce4d31e1d6fd4596e7ac61f77c 100644 (file)
@@ -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);