Ensure all GART allocations are freed on context destruction, rather than
authorAdam Jackson <ajax@freedesktop.org>
Fri, 21 Apr 2006 19:53:52 +0000 (19:53 +0000)
committerAdam Jackson <ajax@freedesktop.org>
Fri, 21 Apr 2006 19:53:52 +0000 (19:53 +0000)
waiting for the DRM to reap them at process exit.  Fixes (fatal) allocation
failures in AIGLX configurations.

Reviewed by: Aapo Tahkola

src/mesa/drivers/dri/r300/r300_context.c

index 4943d54997340731dc718fb2ee545a00c946ff4d..21a474bf675809dd568129ce7669509a6887cd1e 100644 (file)
@@ -372,6 +372,53 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
        return GL_TRUE;
 }
 
+static void r300FreeGartAllocations(r300ContextPtr r300)
+{
+    int i, ret;
+    drm_radeon_mem_free_t memfree;
+
+    memfree.region = RADEON_MEM_REGION_GART;
+
+#if 0
+    if (r300->rmm->u_last + 1 >= r300->rmm->u_size)
+       resize_u_list(r300);
+#endif
+
+    for (i = r300->rmm->u_last + 1; i > 0; i--) {
+       if (r300->rmm->u_list[i].ptr == NULL) {
+           continue;
+       }
+
+       if (r300->rmm->u_list[i].h_pending == 0 &&
+               r300->rmm->u_list[i].pending) {
+           memfree.region_offset = (char *)r300->rmm->u_list[i].ptr -
+                       (char *)r300->radeon.radeonScreen->gartTextures.map;
+           ret = drmCommandWrite(r300->radeon.radeonScreen->driScreen->fd,
+                                 DRM_RADEON_FREE, &memfree, sizeof(memfree));
+           if (ret) {
+               fprintf(stderr, "Failed to free at %p\nret = %s\n",
+                       r300->rmm->u_list[i].ptr, strerror(-ret));
+           } else {
+               fprintf(stderr, "Really freed %d at age %x\n", i,
+                       radeonGetAge((radeonContextPtr)r300));
+               if (i == r300->rmm->u_last)
+                   r300->rmm->u_last--;
+               r300->rmm->u_list[i].pending = 0;
+               r300->rmm->u_list[i].ptr = NULL;
+               if (r300->rmm->u_list[i].fb) {
+                   LOCK_HARDWARE(&(r300->radeon));
+                   ret = mmFreeMem(r300->rmm->u_list[i].fb);
+                   UNLOCK_HARDWARE(&(r300->radeon));
+                   if (ret) fprintf(stderr, "failed to free!\n");
+                   r300->rmm->u_list[i].fb = NULL;
+               }
+               r300->rmm->u_list[i].ref_count = 0;
+           }
+       }
+    }
+    r300->rmm->u_head = i;
+}
+
 /* Destroy the device specific context.
  */
 void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
@@ -408,7 +455,8 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
                        r300ReleaseDmaRegion(r300, &r300->dma.current, __FUNCTION__ );
                        r300FlushCmdBuf(r300, __FUNCTION__ );
                }
-                               
+
+               r300FreeGartAllocations(r300); // XXX SO MUCH HATE              
                r300DestroyCmdBuf(r300);
 
                if (radeon->state.scissor.pClipRects) {