summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
authorAdam Jackson <ajax@freedesktop.org>2006-04-21 19:53:52 +0000
committerAdam Jackson <ajax@freedesktop.org>2006-04-21 19:53:52 +0000
commite60ce392d8f49948b7b5a644e23c3174d04ac6af (patch)
tree9635fc05e518f4a73148a409761ff1c630d7c3f5 /src/mesa
parentca98203cd9fe7d890091cd41fb310aea33d7c314 (diff)
Ensure all GART allocations are freed on context destruction, rather than
waiting for the DRM to reap them at process exit. Fixes (fatal) allocation failures in AIGLX configurations. Reviewed by: Aapo Tahkola
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 4943d54997..21a474bf67 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -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) {