diff options
author | Adam Jackson <ajax@freedesktop.org> | 2006-04-21 19:53:52 +0000 |
---|---|---|
committer | Adam Jackson <ajax@freedesktop.org> | 2006-04-21 19:53:52 +0000 |
commit | e60ce392d8f49948b7b5a644e23c3174d04ac6af (patch) | |
tree | 9635fc05e518f4a73148a409761ff1c630d7c3f5 /src | |
parent | ca98203cd9fe7d890091cd41fb310aea33d7c314 (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')
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_context.c | 50 |
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) { |