From a61a6b1db610a07060d0dcca54b66a4b2b3686cc Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 21 Feb 2007 09:43:24 -0800 Subject: Reformat to 4-space indents, no trailing whitespace, and 80 columns. I'm in the process of rewriting this file, and wanted to separate my whitespace changes. --- src/i830_memory.c | 3124 +++++++++++++++++++++++++++-------------------------- 1 file changed, 1584 insertions(+), 1540 deletions(-) diff --git a/src/i830_memory.c b/src/i830_memory.c index 6ceb05b5..1b2af120 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -68,15 +68,15 @@ static unsigned int tileGeneration = -1; static unsigned long GetBestTileAlignment(unsigned long size) { - unsigned long i; + unsigned long i; - for (i = KB(512); i < size; i <<= 1) - ; + for (i = KB(512); i < size; i <<= 1) + ; - if (i > MB(64)) - i = MB(64); + if (i > MB(64)) + i = MB(64); - return i; + return i; } /* @@ -87,274 +87,279 @@ static unsigned long AllocFromPool(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool, long size, unsigned long alignment, int flags) { - I830Ptr pI830 = I830PTR(pScrn); - long needed, start, end; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - - if (!result || !pool || !size) - return 0; - - /* Calculate how much space is needed. */ - if (alignment <= GTT_PAGE_SIZE) - needed = size; - else { - if (flags & ALLOCATE_AT_BOTTOM) { - start = ROUND_TO(pool->Free.Start, alignment); - if (flags & ALIGN_BOTH_ENDS) - end = ROUND_TO(start + size, alignment); - else - end = start + size; - needed = end - pool->Free.Start; - } else { /* allocate at top */ - if (flags & ALIGN_BOTH_ENDS) - end = ROUND_DOWN_TO(pool->Free.End, alignment); - else - end = pool->Free.End; - - start = ROUND_DOWN_TO(end - size, alignment); - needed = end - start; - } - } - if (needed > pool->Free.Size) { - long extra; - /* See if the pool can be grown. */ - if (pI830->StolenOnly && !dryrun) - return 0; - extra = needed - pool->Free.Size; - extra = ROUND_TO_PAGE(extra); - if (extra > pI830->FreeMemory) { - if (dryrun) - pI830->FreeMemory = extra; - else + I830Ptr pI830 = I830PTR(pScrn); + long needed, start, end; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + + if (!result || !pool || !size) + return 0; + + /* Calculate how much space is needed. */ + if (alignment <= GTT_PAGE_SIZE) + needed = size; + else { + if (flags & ALLOCATE_AT_BOTTOM) { + start = ROUND_TO(pool->Free.Start, alignment); + if (flags & ALIGN_BOTH_ENDS) + end = ROUND_TO(start + size, alignment); + else + end = start + size; + needed = end - pool->Free.Start; + } else { /* allocate at top */ + if (flags & ALIGN_BOTH_ENDS) + end = ROUND_DOWN_TO(pool->Free.End, alignment); + else + end = pool->Free.End; + + start = ROUND_DOWN_TO(end - size, alignment); + needed = end - start; + } + } + if (needed > pool->Free.Size) { + long extra; + /* See if the pool can be grown. */ + if (pI830->StolenOnly && !dryrun) + return 0; + extra = needed - pool->Free.Size; + extra = ROUND_TO_PAGE(extra); + if (extra > pI830->FreeMemory) { + if (dryrun) + pI830->FreeMemory = extra; + else + return 0; + } + + if (!dryrun && ((long)extra > pI830->MemoryAperture.Size)) return 0; - } - if (!dryrun && ((long)extra > pI830->MemoryAperture.Size)) - return 0; - - pool->Free.Size += extra; - pool->Free.End += extra; - pool->Total.Size += extra; - pool->Total.End += extra; - pI830->FreeMemory -= extra; - pI830->MemoryAperture.Start += extra; - pI830->MemoryAperture.Size -= extra; - } - if (flags & ALLOCATE_AT_BOTTOM) { - result->Start = ROUND_TO(pool->Free.Start, alignment); - pool->Free.Start += needed; - result->End = pool->Free.Start; - } else { - result->Start = ROUND_DOWN_TO(pool->Free.End - size, alignment); - pool->Free.End -= needed; - result->End = result->Start + needed; - } - pool->Free.Size = pool->Free.End - pool->Free.Start; - result->Size = result->End - result->Start; - result->Pool = pool; - result->Alignment = alignment; - return needed; + pool->Free.Size += extra; + pool->Free.End += extra; + pool->Total.Size += extra; + pool->Total.End += extra; + pI830->FreeMemory -= extra; + pI830->MemoryAperture.Start += extra; + pI830->MemoryAperture.Size -= extra; + } + if (flags & ALLOCATE_AT_BOTTOM) { + result->Start = ROUND_TO(pool->Free.Start, alignment); + pool->Free.Start += needed; + result->End = pool->Free.Start; + } else { + result->Start = ROUND_DOWN_TO(pool->Free.End - size, alignment); + pool->Free.End -= needed; + result->End = result->Start + needed; + } + pool->Free.Size = pool->Free.End - pool->Free.Start; + result->Size = result->End - result->Start; + result->Pool = pool; + result->Alignment = alignment; + return needed; } static unsigned long AllocFromAGP(ScrnInfoPtr pScrn, I830MemRange *result, long size, unsigned long alignment, int flags) { - I830Ptr pI830 = I830PTR(pScrn); - unsigned long start, end; - unsigned long newApStart, newApEnd; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - - if (!result || !size) - return 0; - - if ((flags & ALLOCATE_AT_BOTTOM) && pI830->StolenMemory.Size != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "AllocFromAGP(): can't allocate from " - "bottom when there is stolen memory\n"); - return 0; - } - - if (size > pI830->FreeMemory) { - if (dryrun) - pI830->FreeMemory = size; - else - return 0; - } - - /* Calculate offset */ - if (flags & ALLOCATE_AT_BOTTOM) { - start = ROUND_TO(pI830->MemoryAperture.Start, alignment); - if (flags & ALIGN_BOTH_ENDS) - end = ROUND_TO(start + size, alignment); - else - end = start + size; - newApStart = end; - newApEnd = pI830->MemoryAperture.End; - } else { - if (flags & ALIGN_BOTH_ENDS) - end = ROUND_DOWN_TO(pI830->MemoryAperture.End, alignment); - else - end = pI830->MemoryAperture.End; - start = ROUND_DOWN_TO(end - size, alignment); - newApStart = pI830->MemoryAperture.Start; - newApEnd = start; - } - - if (!dryrun) { - if (newApStart > newApEnd) - return 0; - - if (flags & NEED_PHYSICAL_ADDR) - result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2, - &(result->Physical)); - else - result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL); - - if (result->Key == -1) - return 0; - } - - pI830->allocatedMemory += size; - pI830->MemoryAperture.Start = newApStart; - pI830->MemoryAperture.End = newApEnd; - pI830->MemoryAperture.Size = newApEnd - newApStart; - pI830->FreeMemory -= size; - result->Start = start; - result->End = start + size; - result->Size = size; - result->Offset = start; - result->Alignment = alignment; - result->Pool = NULL; - - return size; + I830Ptr pI830 = I830PTR(pScrn); + unsigned long start, end; + unsigned long newApStart, newApEnd; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + + if (!result || !size) + return 0; + + if ((flags & ALLOCATE_AT_BOTTOM) && pI830->StolenMemory.Size != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "AllocFromAGP(): can't allocate from " + "bottom when there is stolen memory\n"); + return 0; + } + + if (size > pI830->FreeMemory) { + if (dryrun) + pI830->FreeMemory = size; + else + return 0; + } + + /* Calculate offset */ + if (flags & ALLOCATE_AT_BOTTOM) { + start = ROUND_TO(pI830->MemoryAperture.Start, alignment); + if (flags & ALIGN_BOTH_ENDS) + end = ROUND_TO(start + size, alignment); + else + end = start + size; + newApStart = end; + newApEnd = pI830->MemoryAperture.End; + } else { + if (flags & ALIGN_BOTH_ENDS) + end = ROUND_DOWN_TO(pI830->MemoryAperture.End, alignment); + else + end = pI830->MemoryAperture.End; + start = ROUND_DOWN_TO(end - size, alignment); + newApStart = pI830->MemoryAperture.Start; + newApEnd = start; + } + + if (!dryrun) { + if (newApStart > newApEnd) + return 0; + + if (flags & NEED_PHYSICAL_ADDR) { + result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2, + &(result->Physical)); + } else { + result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, + NULL); + } + + if (result->Key == -1) + return 0; + } + + pI830->allocatedMemory += size; + pI830->MemoryAperture.Start = newApStart; + pI830->MemoryAperture.End = newApEnd; + pI830->MemoryAperture.Size = newApEnd - newApStart; + pI830->FreeMemory -= size; + result->Start = start; + result->End = start + size; + result->Size = size; + result->Offset = start; + result->Alignment = alignment; + result->Pool = NULL; + + return size; } void I830FreeVidMem(ScrnInfoPtr pScrn, I830MemRange *range) { - I830Ptr pI830 = I830PTR(pScrn); - - if (!range || range->Size == 0) - return; - - if (range->Key != -1) - xf86DeallocateGARTMemory(pScrn->scrnIndex, range->Key); - - if (range->Pool) { - /* - * This code essentially resets what I830DoPoolAllocation() did. - * And if things are freed in the wrong order this can break wildly! - * USE CAUTION when changing anything here... - */ - I830MemPool *Pool = range->Pool; - Pool->Total.End = pI830->StolenMemory.End; - - if (pI830->StolenOnly) - Pool->Free.End += range->Size; - else - Pool->Free.End = Pool->Total.End; - - if (Pool->Free.End < Pool->Free.Start) { - Pool->Free.End = Pool->Free.Start; - } - - Pool->Free.Size = Pool->Free.End - Pool->Free.Start; - Pool->Total.Size = Pool->Total.End - Pool->Total.Start; + I830Ptr pI830 = I830PTR(pScrn); + + if (!range || range->Size == 0) + return; + + if (range->Key != -1) + xf86DeallocateGARTMemory(pScrn->scrnIndex, range->Key); + + if (range->Pool) { + /* + * This code essentially resets what I830DoPoolAllocation() did. + * And if things are freed in the wrong order this can break wildly! + * USE CAUTION when changing anything here... + */ + I830MemPool *Pool = range->Pool; + Pool->Total.End = pI830->StolenMemory.End; + + if (pI830->StolenOnly) + Pool->Free.End += range->Size; + else + Pool->Free.End = Pool->Total.End; + + if (Pool->Free.End < Pool->Free.Start) { + Pool->Free.End = Pool->Free.Start; + } + + Pool->Free.Size = Pool->Free.End - Pool->Free.Start; + Pool->Total.Size = Pool->Total.End - Pool->Total.Start; + + if (!pI830->StolenOnly) { + pI830->FreeMemory -= Pool->Free.Size; + pI830->MemoryAperture.Start -= (range->Size - Pool->Free.Size); + pI830->MemoryAperture.Size += (range->Size - Pool->Free.Size); + } + } else { + if (range->Alignment == GTT_PAGE_SIZE) + pI830->MemoryAperture.End = range->End; + else { + pI830->MemoryAperture.End = range->End - range->Size + + range->Alignment; + } + pI830->MemoryAperture.Size = pI830->MemoryAperture.End - + pI830->MemoryAperture.Start; + } - if (!pI830->StolenOnly) { - pI830->FreeMemory -= Pool->Free.Size; - pI830->MemoryAperture.Start -= (range->Size - Pool->Free.Size); - pI830->MemoryAperture.Size += (range->Size - Pool->Free.Size); - } - } else { - if (range->Alignment == GTT_PAGE_SIZE) - pI830->MemoryAperture.End = range->End; - else - pI830->MemoryAperture.End = range->End - range->Size + range->Alignment; - pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start; - } - - if (!pI830->StolenOnly) - pI830->FreeMemory += range->Size; - pI830->allocatedMemory -= range->Size; + if (!pI830->StolenOnly) + pI830->FreeMemory += range->Size; + pI830->allocatedMemory -= range->Size; } unsigned long I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool, long size, unsigned long alignment, int flags) { - I830Ptr pI830 = I830PTR(pScrn); - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - - if (!result) - return 0; - - /* Make sure these are initialised. */ - result->Size = 0; - result->Key = -1; - - if (!size) { - return 0; - } - - switch (flags & FROM_MASK) { - case FROM_POOL_ONLY: - return AllocFromPool(pScrn, result, pool, size, alignment, flags); - case FROM_NEW_ONLY: - if (!dryrun && (pI830->StolenOnly || (pI830->FreeMemory <= 0))) - return 0; - return AllocFromAGP(pScrn, result, size, alignment, flags); - case FROM_ANYWHERE: - if ((!(flags & ALLOCATE_AT_BOTTOM) && (pI830->FreeMemory >= size)) || - (flags & NEED_PHYSICAL_ADDR)) - return AllocFromAGP(pScrn, result, size, alignment, flags); - else - return AllocFromPool(pScrn, result, pool, size, alignment, flags); - default: - /* Shouldn't happen. */ - return 0; - } + I830Ptr pI830 = I830PTR(pScrn); + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + + if (!result) + return 0; + + /* Make sure these are initialised. */ + result->Size = 0; + result->Key = -1; + + if (!size) { + return 0; + } + + switch (flags & FROM_MASK) { + case FROM_POOL_ONLY: + return AllocFromPool(pScrn, result, pool, size, alignment, flags); + case FROM_NEW_ONLY: + if (!dryrun && (pI830->StolenOnly || (pI830->FreeMemory <= 0))) + return 0; + return AllocFromAGP(pScrn, result, size, alignment, flags); + case FROM_ANYWHERE: + if ((!(flags & ALLOCATE_AT_BOTTOM) && (pI830->FreeMemory >= size)) || + (flags & NEED_PHYSICAL_ADDR)) + return AllocFromAGP(pScrn, result, size, alignment, flags); + else + return AllocFromPool(pScrn, result, pool, size, alignment, flags); + default: + /* Shouldn't happen. */ + return 0; + } } static Bool AllocateRingBuffer(ScrnInfoPtr pScrn, int flags) { - I830Ptr pI830 = I830PTR(pScrn); - unsigned long size, alloced; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - - /* Clear ring buffer info */ - memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); - pI830->LpRing->mem.Key = -1; - - if (pI830->noAccel) - return TRUE; - - /* Ring buffer */ - size = PRIMARY_RINGBUFFER_SIZE; - if (flags & FORCE_LOW) - flags |= FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM; - else - flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP; - - alloced = I830AllocVidMem(pScrn, &(pI830->LpRing->mem), - &(pI830->StolenPool), size, - GTT_PAGE_SIZE, flags); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate Ring Buffer space\n"); - } - return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the ring buffer at 0x%lx\n", s, - alloced / 1024, pI830->LpRing->mem.Start); - pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; - return TRUE; + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size, alloced; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + + /* Clear ring buffer info */ + memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); + pI830->LpRing->mem.Key = -1; + + if (pI830->noAccel) + return TRUE; + + /* Ring buffer */ + size = PRIMARY_RINGBUFFER_SIZE; + if (flags & FORCE_LOW) + flags |= FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM; + else + flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP; + + alloced = I830AllocVidMem(pScrn, &(pI830->LpRing->mem), + &(pI830->StolenPool), size, + GTT_PAGE_SIZE, flags); + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate Ring Buffer space\n"); + } + return FALSE; + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for the ring buffer at 0x%lx\n", s, + alloced / 1024, pI830->LpRing->mem.Start); + pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; + return TRUE; } #ifdef I830_XV @@ -364,127 +369,130 @@ AllocateRingBuffer(ScrnInfoPtr pScrn, int flags) static Bool AllocateOverlay(ScrnInfoPtr pScrn, int flags) { - I830Ptr pI830 = I830PTR(pScrn); - unsigned long size, alloced; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - - /* Clear overlay info */ - memset(pI830->OverlayMem, 0, sizeof(I830MemRange)); - pI830->OverlayMem->Key = -1; - - if (!pI830->XvEnabled) - return TRUE; - - /* - * The overlay register space needs a physical address in - * system memory. We get this from the agpgart module using - * a special memory type. - */ - - size = OVERLAY_SIZE; - if (flags & FORCE_LOW) - flags |= FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM | NEED_PHYSICAL_ADDR; - else - flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP | NEED_PHYSICAL_ADDR; - - alloced = I830AllocVidMem(pScrn, pI830->OverlayMem, - &(pI830->StolenPool), size, GTT_PAGE_SIZE, flags); - - /* - * XXX For testing only. Don't enable this unless you know how to set - * physBase. - */ - if (flags & FORCE_LOW) { - ErrorF("AllocateOverlay() doesn't support setting FORCE_LOW\n"); - return FALSE; - } - - if (!dryrun && (alloced < size)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate Overlay register space.\n"); - /* This failure isn't fatal. */ - } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for Overlay registers at 0x%lx " - "(0x%08lx).\n", s, - alloced / 1024, pI830->OverlayMem->Start, - pI830->OverlayMem->Physical); - } - - /* Clear linearmem info */ - if (pI830->LinearAlloc) { - memset(&(pI830->LinearMem), 0, sizeof(I830MemRange)); - pI830->LinearMem.Key = -1; - - size = KB(pI830->LinearAlloc); - alloced = I830AllocVidMem(pScrn, &(pI830->LinearMem), &(pI830->StolenPool), - size, GTT_PAGE_SIZE, - FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate linear buffer space\n"); - } - } else - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the linear buffer at 0x%lx\n", s, - alloced / 1024, pI830->LinearMem.Start); - } - - return TRUE; + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size, alloced; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + + /* Clear overlay info */ + memset(pI830->OverlayMem, 0, sizeof(I830MemRange)); + pI830->OverlayMem->Key = -1; + + if (!pI830->XvEnabled) + return TRUE; + + /* + * The overlay register space needs a physical address in + * system memory. We get this from the agpgart module using + * a special memory type. + */ + + size = OVERLAY_SIZE; + if (flags & FORCE_LOW) + flags |= FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM | NEED_PHYSICAL_ADDR; + else + flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP | NEED_PHYSICAL_ADDR; + + alloced = I830AllocVidMem(pScrn, pI830->OverlayMem, + &(pI830->StolenPool), size, GTT_PAGE_SIZE, + flags); + + /* + * XXX For testing only. Don't enable this unless you know how to set + * physBase. + */ + if (flags & FORCE_LOW) { + ErrorF("AllocateOverlay() doesn't support setting FORCE_LOW\n"); + return FALSE; + } + + if (!dryrun && (alloced < size)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate Overlay register space.\n"); + /* This failure isn't fatal. */ + } else { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for Overlay registers at 0x%lx " + "(0x%08lx).\n", s, + alloced / 1024, pI830->OverlayMem->Start, + pI830->OverlayMem->Physical); + } + + /* Clear linearmem info */ + if (pI830->LinearAlloc) { + memset(&(pI830->LinearMem), 0, sizeof(I830MemRange)); + pI830->LinearMem.Key = -1; + + size = KB(pI830->LinearAlloc); + alloced = I830AllocVidMem(pScrn, &(pI830->LinearMem), + &(pI830->StolenPool), + size, GTT_PAGE_SIZE, + FROM_ANYWHERE | ALLOCATE_AT_TOP); + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate linear buffer space\n"); + } + } else + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for the linear buffer at " + "0x%lx\n", s, + alloced / 1024, pI830->LinearMem.Start); + } + + return TRUE; } #endif static Bool IsTileable(ScrnInfoPtr pScrn, int pitch) { - I830Ptr pI830 = I830PTR(pScrn); - - if (IS_I965G(pI830)) { - if (pitch / 512 * 512 == pitch && pitch <= KB(128)) - return TRUE; - else - return FALSE; - } - - /* - * Allow tiling for pitches that are a power of 2 multiple of 128 bytes, - * up to 64 * 128 (= 8192) bytes. - */ - switch (pitch) { - case 128: - case 256: - if (IS_I945G(pI830) || IS_I945GM(pI830)) - return TRUE; - else - return FALSE; - case 512: - case KB(1): - case KB(2): - case KB(4): - case KB(8): - return TRUE; - default: - return FALSE; - } + I830Ptr pI830 = I830PTR(pScrn); + + if (IS_I965G(pI830)) { + if (pitch / 512 * 512 == pitch && pitch <= KB(128)) + return TRUE; + else + return FALSE; + } + + /* + * Allow tiling for pitches that are a power of 2 multiple of 128 bytes, + * up to 64 * 128 (= 8192) bytes. + */ + switch (pitch) { + case 128: + case 256: + if (IS_I945G(pI830) || IS_I945GM(pI830)) + return TRUE; + else + return FALSE; + case 512: + case KB(1): + case KB(2): + case KB(4): + case KB(8): + return TRUE; + default: + return FALSE; + } } static unsigned long GetFreeSpace(ScrnInfoPtr pScrn) { - I830Ptr pI830 = I830PTR(pScrn); - unsigned long extra = 0; + I830Ptr pI830 = I830PTR(pScrn); + unsigned long extra = 0; - /* First check for free space in StolenPool. */ - if (pI830->StolenPool.Free.Size > 0) - extra = pI830->StolenPool.Free.Size; - /* Next check for unallocated space. */ - if (pI830->FreeMemory > 0) - extra += pI830->FreeMemory; + /* First check for free space in StolenPool. */ + if (pI830->StolenPool.Free.Size > 0) + extra = pI830->StolenPool.Free.Size; + /* Next check for unallocated space. */ + if (pI830->FreeMemory > 0) + extra += pI830->FreeMemory; - return extra; + return extra; } /* This is the 2D rendering vertical coordinate limit. We can ignore @@ -509,199 +517,200 @@ I830AllocateFramebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, I830MemRange *FrontBuffer, I830MemPool *StolenPool, Bool secondary, const int flags) { - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - unsigned long minspace, avail, lineSize; - int cacheLines, maxCacheLines; - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - Bool tileable; - int align, alignflags; - long size, alloced, fb_height; - - /* Clear everything first. */ - memset(FbMemBox, 0, sizeof(*FbMemBox)); - memset(FrontBuffer, 0, sizeof(*FrontBuffer)); - FrontBuffer->Key = -1; - - /* We'll allocate the fb such that the root window will fit regardless of - * rotation. - */ - if (pScrn->virtualX > pScrn->virtualY) - fb_height = pScrn->virtualX; - else - fb_height = pScrn->virtualY; - - FbMemBox->x1 = 0; - FbMemBox->x2 = pScrn->displayWidth; - FbMemBox->y1 = 0; - FbMemBox->y2 = fb_height; - - /* Calculate how much framebuffer memory to allocate. For the - * initial allocation, calculate a reasonable minimum. This is - * enough for the virtual screen size, plus some pixmap cache - * space if we're using XAA. - */ - - lineSize = pScrn->displayWidth * pI830->cpp; - minspace = lineSize * pScrn->virtualY; - avail = pScrn->videoRam * 1024; - - if (!pI830->useEXA) { - maxCacheLines = (avail - minspace) / lineSize; - /* This shouldn't happen. */ - if (maxCacheLines < 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Internal Error: " - "maxCacheLines < 0 in I830Allocate2DMemory()\n"); - maxCacheLines = 0; - } - if (maxCacheLines > (MAX_2D_HEIGHT - pScrn->virtualY)) - maxCacheLines = MAX_2D_HEIGHT - pScrn->virtualY; - - if (pI830->CacheLines >= 0) { - cacheLines = pI830->CacheLines; - } else { - int size; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + unsigned long minspace, avail, lineSize; + int cacheLines, maxCacheLines; + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + Bool tileable; + int align, alignflags; + long size, alloced, fb_height; + + /* Clear everything first. */ + memset(FbMemBox, 0, sizeof(*FbMemBox)); + memset(FrontBuffer, 0, sizeof(*FrontBuffer)); + FrontBuffer->Key = -1; + + /* We'll allocate the fb such that the root window will fit regardless of + * rotation. + */ + if (pScrn->virtualX > pScrn->virtualY) + fb_height = pScrn->virtualX; + else + fb_height = pScrn->virtualY; + + FbMemBox->x1 = 0; + FbMemBox->x2 = pScrn->displayWidth; + FbMemBox->y1 = 0; + FbMemBox->y2 = fb_height; + + /* Calculate how much framebuffer memory to allocate. For the + * initial allocation, calculate a reasonable minimum. This is + * enough for the virtual screen size, plus some pixmap cache + * space if we're using XAA. + */ + + lineSize = pScrn->displayWidth * pI830->cpp; + minspace = lineSize * pScrn->virtualY; + avail = pScrn->videoRam * 1024; + + if (!pI830->useEXA) { + maxCacheLines = (avail - minspace) / lineSize; + /* This shouldn't happen. */ + if (maxCacheLines < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal Error: " + "maxCacheLines < 0 in I830Allocate2DMemory()\n"); + maxCacheLines = 0; + } + if (maxCacheLines > (MAX_2D_HEIGHT - pScrn->virtualY)) + maxCacheLines = MAX_2D_HEIGHT - pScrn->virtualY; + + if (pI830->CacheLines >= 0) { + cacheLines = pI830->CacheLines; + } else { + int size; + + size = 3 * lineSize * pScrn->virtualY; + size += 1920 * 1088 * 2 * 2; + size = ROUND_TO_PAGE(size); + + cacheLines = (size + lineSize - 1) / lineSize; + } + if (cacheLines > maxCacheLines) + cacheLines = maxCacheLines; + + FbMemBox->y2 += cacheLines; + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocating at least %d scanlines for pixmap cache\n", + s, cacheLines); + } else { + /* For EXA, we have a separate allocation for the linear allocator + * which also does the pixmap cache. + */ + cacheLines = 0; + } - size = 3 * lineSize * pScrn->virtualY; - size += 1920 * 1088 * 2 * 2; - size = ROUND_TO_PAGE(size); + tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip && + IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); + if (tileable) { + if (IS_I9XX(pI830)) + align = MB(1); + else + align = KB(512); + alignflags = ALIGN_BOTH_ENDS; + } else { + align = KB(64); + alignflags = 0; + } - cacheLines = (size + lineSize - 1) / lineSize; - } - if (cacheLines > maxCacheLines) - cacheLines = maxCacheLines; - - FbMemBox->y2 += cacheLines; - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocating at least %d scanlines for pixmap cache\n", - s, cacheLines); - } else { - /* For EXA, we have a separate allocation for the linear allocator which - * also does the pixmap cache. - */ - cacheLines = 0; - } - - tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip && - IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); - if (tileable) { - if (IS_I9XX(pI830)) - align = MB(1); - else - align = KB(512); - alignflags = ALIGN_BOTH_ENDS; - } else { - align = KB(64); - alignflags = 0; - } - - size = lineSize * (fb_height + cacheLines); - size = ROUND_TO_PAGE(size); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sInitial %sframebuffer allocation size: %ld kByte\n", - s, secondary ? "secondary " : "", - size / 1024); - alloced = I830AllocVidMem(pScrn, FrontBuffer, - StolenPool, size, align, - flags | alignflags | - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " - "%sframebuffer. Is your VideoRAM set too low?\n", - secondary ? "secondary " : ""); - } - return FALSE; - } + size = lineSize * (fb_height + cacheLines); + size = ROUND_TO_PAGE(size); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sInitial %sframebuffer allocation size: %ld kByte\n", + s, secondary ? "secondary " : "", + size / 1024); + alloced = I830AllocVidMem(pScrn, FrontBuffer, + StolenPool, size, align, + flags | alignflags | + FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " + "%sframebuffer. Is your VideoRAM set too low?\n", + secondary ? "secondary " : ""); + } + return FALSE; + } - return TRUE; + return TRUE; } static Bool I830AllocateCursorBuffers(xf86CrtcPtr crtc, const int flags) { - ScrnInfoPtr pScrn = crtc->scrn; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - I830Ptr pI830 = I830PTR(pScrn); - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - long size, alloced; - int cursFlags = 0; - - /* Clear cursor info */ - memset(&intel_crtc->cursor_mem, 0, sizeof(I830MemRange)); - intel_crtc->cursor_mem.Key = -1; - memset(&intel_crtc->cursor_mem_argb, 0, sizeof(I830MemRange)); - intel_crtc->cursor_mem_argb.Key = -1; - - if (pI830->SWCursor) - return FALSE; - - /* - * Mouse cursor -- The i810-i830 need a physical address in system - * memory from which to upload the cursor. We get this from - * the agpgart module using a special memory type. - */ - - size = HWCURSOR_SIZE; - cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP; - if (pI830->CursorNeedsPhysical) - cursFlags |= NEED_PHYSICAL_ADDR; - - alloced = I830AllocVidMem(pScrn, &intel_crtc->cursor_mem, - &pI830->StolenPool, size, - GTT_PAGE_SIZE, flags | cursFlags); - if (alloced < size || - (pI830->CursorNeedsPhysical && !intel_crtc->cursor_mem.Physical)) - { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate HW cursor space.\n"); - return FALSE; - } - } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for HW cursor at 0x%lx", s, - alloced / 1024, intel_crtc->cursor_mem.Start); - if (pI830->CursorNeedsPhysical) { - xf86ErrorFVerb(verbosity, " (0x%08lx)", - intel_crtc->cursor_mem.Physical); - } - xf86ErrorFVerb(verbosity, "\n"); - } - - /* Allocate the ARGB cursor space. Its success is optional -- we won't set - * SWCursor if it fails. - */ - size = HWCURSOR_SIZE_ARGB; - cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP; - if (pI830->CursorNeedsPhysical) - cursFlags |= NEED_PHYSICAL_ADDR; - - alloced = I830AllocVidMem(pScrn, &intel_crtc->cursor_mem_argb, - &pI830->StolenPool, size, - GTT_PAGE_SIZE, flags | cursFlags); - if (alloced < size || - (pI830->CursorNeedsPhysical && !intel_crtc->cursor_mem_argb.Physical)) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate HW (ARGB) cursor space.\n"); - } - } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for HW (ARGB) cursor at 0x%lx", s, - alloced / 1024, intel_crtc->cursor_mem_argb.Start); - if (pI830->CursorNeedsPhysical) { - xf86ErrorFVerb(verbosity, " (0x%08lx)", - intel_crtc->cursor_mem_argb.Physical); - } - xf86ErrorFVerb(verbosity, "\n"); - } + ScrnInfoPtr pScrn = crtc->scrn; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + I830Ptr pI830 = I830PTR(pScrn); + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + long size, alloced; + int cursFlags = 0; + + /* Clear cursor info */ + memset(&intel_crtc->cursor_mem, 0, sizeof(I830MemRange)); + intel_crtc->cursor_mem.Key = -1; + memset(&intel_crtc->cursor_mem_argb, 0, sizeof(I830MemRange)); + intel_crtc->cursor_mem_argb.Key = -1; + + if (pI830->SWCursor) + return FALSE; + + /* + * Mouse cursor -- The i810-i830 need a physical address in system + * memory from which to upload the cursor. We get this from + * the agpgart module using a special memory type. + */ + + size = HWCURSOR_SIZE; + cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP; + if (pI830->CursorNeedsPhysical) + cursFlags |= NEED_PHYSICAL_ADDR; + + alloced = I830AllocVidMem(pScrn, &intel_crtc->cursor_mem, + &pI830->StolenPool, size, + GTT_PAGE_SIZE, flags | cursFlags); + if (alloced < size || + (pI830->CursorNeedsPhysical && !intel_crtc->cursor_mem.Physical)) + { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate HW cursor space.\n"); + return FALSE; + } + } else { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for HW cursor at 0x%lx", s, + alloced / 1024, intel_crtc->cursor_mem.Start); + if (pI830->CursorNeedsPhysical) { + xf86ErrorFVerb(verbosity, " (0x%08lx)", + intel_crtc->cursor_mem.Physical); + } + xf86ErrorFVerb(verbosity, "\n"); + } + + /* Allocate the ARGB cursor space. Its success is optional -- we won't set + * SWCursor if it fails. + */ + size = HWCURSOR_SIZE_ARGB; + cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP; + if (pI830->CursorNeedsPhysical) + cursFlags |= NEED_PHYSICAL_ADDR; + + alloced = I830AllocVidMem(pScrn, &intel_crtc->cursor_mem_argb, + &pI830->StolenPool, size, + GTT_PAGE_SIZE, flags | cursFlags); + if (alloced < size || + (pI830->CursorNeedsPhysical && !intel_crtc->cursor_mem_argb.Physical)) + { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate HW (ARGB) cursor space.\n"); + } + } else { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for HW (ARGB) cursor at 0x%lx", s, + alloced / 1024, intel_crtc->cursor_mem_argb.Start); + if (pI830->CursorNeedsPhysical) { + xf86ErrorFVerb(verbosity, " (0x%08lx)", + intel_crtc->cursor_mem_argb.Physical); + } + xf86ErrorFVerb(verbosity, "\n"); + } - return FALSE; + return FALSE; } /* @@ -711,561 +720,586 @@ I830AllocateCursorBuffers(xf86CrtcPtr crtc, const int flags) Bool I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) { - I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - long size, alloced; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - Bool tileable; - int align, alignflags, i; - - DPRINTF(PFX, "I830Allocate2DMemory: inital is %s\n", - BOOLTOSTRING(flags & ALLOC_INITIAL)); - - if (!pI830->StolenOnly && - (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "AGP GART support is either not available or cannot " - "be used.\n" - "\tMake sure your kernel has agpgart support or has the\n" - "\tagpgart module loaded.\n"); - } - return FALSE; - } - - - /* - * The I830 is slightly different from the I830/I815, it has no - * dcache and it has stolen memory by default in its gtt. All - * additional memory must go after it. - */ - - DPRINTF(PFX, - "size == %luk (%lu bytes == pScrn->videoRam)\n" - "pI830->StolenSize == %luk (%lu bytes)\n", - pScrn->videoRam, pScrn->videoRam * 1024, - pI830->StolenPool.Free.Size / 1024, - pI830->StolenPool.Free.Size); - - if (flags & ALLOC_INITIAL) { - if (pI830->NeedRingBufferLow) - AllocateRingBuffer(pScrn, flags | FORCE_LOW); - - /* Unfortunately this doesn't run on the DRY_RUN pass because our - * second head hasn't been created yet..... */ - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { - I830EntPtr pI830Ent = pI830->entityPrivate; - I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2); - - if (!I830AllocateFramebuffer(pI830Ent->pScrn_2, pI8302, - &pI830->FbMemBox2, - &pI830->FrontBuffer2, &pI830->StolenPool, - TRUE, flags)) - { + I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + long size, alloced; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + Bool tileable; + int align, alignflags, i; + + DPRINTF(PFX, "I830Allocate2DMemory: inital is %s\n", + BOOLTOSTRING(flags & ALLOC_INITIAL)); + + if (!pI830->StolenOnly && + (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "AGP GART support is either not available or cannot " + "be used.\n" + "\tMake sure your kernel has agpgart support or has " + "the\n" + "\tagpgart module loaded.\n"); + } + return FALSE; + } + + + /* + * The I830 is slightly different from the I830/I815, it has no + * dcache and it has stolen memory by default in its gtt. All + * additional memory must go after it. + */ + + DPRINTF(PFX, + "size == %luk (%lu bytes == pScrn->videoRam)\n" + "pI830->StolenSize == %luk (%lu bytes)\n", + pScrn->videoRam, pScrn->videoRam * 1024, + pI830->StolenPool.Free.Size / 1024, + pI830->StolenPool.Free.Size); + + if (flags & ALLOC_INITIAL) { + if (pI830->NeedRingBufferLow) + AllocateRingBuffer(pScrn, flags | FORCE_LOW); + + /* Unfortunately this doesn't run on the DRY_RUN pass because our + * second head hasn't been created yet..... */ + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { + I830EntPtr pI830Ent = pI830->entityPrivate; + I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2); + + if (!I830AllocateFramebuffer(pI830Ent->pScrn_2, pI8302, + &pI830->FbMemBox2, + &pI830->FrontBuffer2, + &pI830->StolenPool, + TRUE, flags)) + { + return FALSE; + } + } + if (!I830AllocateFramebuffer(pScrn, pI830, &pI830->FbMemBox, + &pI830->FrontBuffer, &pI830->StolenPool, + FALSE, flags)) + { return FALSE; - } - } - if (!I830AllocateFramebuffer(pScrn, pI830, &pI830->FbMemBox, - &pI830->FrontBuffer, &pI830->StolenPool, - FALSE, flags)) - { - return FALSE; - } + } #ifdef I830_USE_EXA - if (pI830->useEXA) { - /* Default EXA to having 3 screens worth of offscreen memory space - * (for pixmaps), plus a double-buffered, 1920x1088 video's worth. - */ - size = 3 * pScrn->displayWidth * pI830->cpp * pScrn->virtualY; - size += 1920 * 1088 * 2 * 2; - size = ROUND_TO_PAGE(size); - - alloced = I830AllocVidMem(pScrn, &(pI830->Offscreen), - &(pI830->StolenPool), size, 1, - flags | - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " - "offscreen memory. Not enough VRAM?\n"); + if (pI830->useEXA) { + /* Default EXA to having 3 screens worth of offscreen memory space + * (for pixmaps), plus a double-buffered, 1920x1088 video's worth. + */ + size = 3 * pScrn->displayWidth * pI830->cpp * pScrn->virtualY; + size += 1920 * 1088 * 2 * 2; + size = ROUND_TO_PAGE(size); + + alloced = I830AllocVidMem(pScrn, &(pI830->Offscreen), + &(pI830->StolenPool), size, 1, + flags | + FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " + "offscreen memory. Not enough VRAM?\n"); + } + return FALSE; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Successful allocation of " + "EXA offscreen memory at 0x%lx, size %ld KB\n", + pI830->Offscreen.Start, pI830->Offscreen.Size/1024); } - return FALSE; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Successful allocation of " - "EXA offscreen memory at 0x%lx, size %ld KB\n", - pI830->Offscreen.Start, pI830->Offscreen.Size/1024); - } - } - if (pI830->useEXA && IS_I965G(pI830)) { - memset(&(pI830->EXAStateMem), 0, sizeof(I830MemRange)); - pI830->EXAStateMem.Key = -1; - size = ROUND_TO_PAGE(EXA_LINEAR_EXTRA); - align = GTT_PAGE_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->EXAStateMem), - &(pI830->StolenPool), size, align, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "G965: Failed to allocate exa state buffer space.\n"); - } - return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the G965 exa state buffer at 0x%lx - 0x%lx.\n", s, - alloced / 1024, pI830->EXAStateMem.Start, pI830->EXAStateMem.End); - } + } + if (pI830->useEXA && IS_I965G(pI830)) { + memset(&(pI830->EXAStateMem), 0, sizeof(I830MemRange)); + pI830->EXAStateMem.Key = -1; + size = ROUND_TO_PAGE(EXA_LINEAR_EXTRA); + align = GTT_PAGE_SIZE; + alloced = I830AllocVidMem(pScrn, &(pI830->EXAStateMem), + &(pI830->StolenPool), size, align, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "G965: Failed to allocate exa state buffer " + "space.\n"); + } + return FALSE; + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for the G965 exa state buffer " + "at 0x%lx - 0x%lx.\n", s, + alloced / 1024, pI830->EXAStateMem.Start, + pI830->EXAStateMem.End); + } #endif - } else { - long lineSize; - long extra = 0; - long maxFb = 0; - - /* - * XXX Need to "free" up any 3D allocations if the DRI ended up - * and make them available for 2D. The best way to do this would - * be position all of those regions contiguously at the end of the - * StolenPool. - */ - extra = GetFreeSpace(pScrn); - - if (extra == 0) - return TRUE; - - maxFb = pI830->FrontBuffer.Size + extra; - lineSize = pScrn->displayWidth * pI830->cpp; - maxFb = ROUND_DOWN_TO(maxFb, lineSize); - if (maxFb > lineSize * MAX_2D_HEIGHT) - maxFb = lineSize * MAX_2D_HEIGHT; - if (0/*maxFb > pI830->FrontBuffer.Size*/) { - unsigned long oldsize; - /* - * Sanity check -- the fb should be the last thing allocated at - * the bottom of the stolen pool. - */ - if (pI830->StolenPool.Free.Start != pI830->FrontBuffer.End) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Internal error in I830Allocate2DMemory():\n\t" - "Framebuffer isn't the last allocation at the bottom" - " of StolenPool\n\t(%lx != %lx).\n", - pI830->FrontBuffer.End, - pI830->StolenPool.Free.Start); - return FALSE; - } - /* - * XXX Maybe should have a "Free" function. This should be - * the only place where a region is resized, and we know that - * the fb is always at the bottom of the aperture/stolen pool, - * and is the only region that is allocated bottom-up. - * Allowing for more general realloction would require a smarter - * allocation system. - */ - oldsize = pI830->FrontBuffer.Size; - pI830->StolenPool.Free.Size += pI830->FrontBuffer.Size; - pI830->StolenPool.Free.Start -= pI830->FrontBuffer.Size; - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sUpdated framebuffer allocation size from %ld " - "to %ld kByte\n", s, oldsize / 1024, maxFb / 1024); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sUpdated pixmap cache from %ld scanlines to %ld " - "scanlines\n", s, - oldsize / lineSize - pScrn->virtualY, - maxFb / lineSize - pScrn->virtualY); - pI830->FbMemBox.y2 = maxFb / lineSize; - tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip && - IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); - if (tileable) { - if (IS_I9XX(pI830)) - align = MB(1); - else - align = KB(512); - alignflags = ALIGN_BOTH_ENDS; - } else { - align = KB(64); - alignflags = 0; - } - alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer), - &(pI830->StolenPool), maxFb, align, - flags | alignflags | - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); - if (alloced < maxFb) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to re-allocate framebuffer\n"); + } else { + long lineSize; + long extra = 0; + long maxFb = 0; + + /* + * XXX Need to "free" up any 3D allocations if the DRI ended up + * and make them available for 2D. The best way to do this would + * be position all of those regions contiguously at the end of the + * StolenPool. + */ + extra = GetFreeSpace(pScrn); + + if (extra == 0) + return TRUE; + + maxFb = pI830->FrontBuffer.Size + extra; + lineSize = pScrn->displayWidth * pI830->cpp; + maxFb = ROUND_DOWN_TO(maxFb, lineSize); + if (maxFb > lineSize * MAX_2D_HEIGHT) + maxFb = lineSize * MAX_2D_HEIGHT; + if (0/*maxFb > pI830->FrontBuffer.Size*/) { + unsigned long oldsize; + /* + * Sanity check -- the fb should be the last thing allocated at + * the bottom of the stolen pool. + */ + if (pI830->StolenPool.Free.Start != pI830->FrontBuffer.End) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal error in I830Allocate2DMemory():\n\t" + "Framebuffer isn't the last allocation at the " + "bottom of StolenPool\n\t(%lx != %lx).\n", + pI830->FrontBuffer.End, + pI830->StolenPool.Free.Start); + return FALSE; } - return FALSE; - } - } - return TRUE; - } + /* + * XXX Maybe should have a "Free" function. This should be + * the only place where a region is resized, and we know that + * the fb is always at the bottom of the aperture/stolen pool, + * and is the only region that is allocated bottom-up. + * Allowing for more general realloction would require a smarter + * allocation system. + */ + oldsize = pI830->FrontBuffer.Size; + pI830->StolenPool.Free.Size += pI830->FrontBuffer.Size; + pI830->StolenPool.Free.Start -= pI830->FrontBuffer.Size; + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sUpdated framebuffer allocation size from %ld " + "to %ld kByte\n", s, oldsize / 1024, maxFb / 1024); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sUpdated pixmap cache from %ld scanlines to %ld " + "scanlines\n", s, + oldsize / lineSize - pScrn->virtualY, + maxFb / lineSize - pScrn->virtualY); + pI830->FbMemBox.y2 = maxFb / lineSize; + tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip && + IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); + if (tileable) { + if (IS_I9XX(pI830)) + align = MB(1); + else + align = KB(512); + alignflags = ALIGN_BOTH_ENDS; + } else { + align = KB(64); + alignflags = 0; + } + alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer), + &(pI830->StolenPool), maxFb, align, + flags | alignflags | + FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); + if (alloced < maxFb) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to re-allocate framebuffer\n"); + } + return FALSE; + } + } + return TRUE; + } #if REMAP_RESERVED - /* - * Allocate a dummy page to pass when attempting to rebind the - * pre-allocated region. - */ - if (!dryrun) { - memset(&(pI830->Dummy), 0, sizeof(pI830->Dummy)); - pI830->Dummy.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL); - pI830->Dummy.Offset = 0; - } + /* + * Allocate a dummy page to pass when attempting to rebind the + * pre-allocated region. + */ + if (!dryrun) { + memset(&(pI830->Dummy), 0, sizeof(pI830->Dummy)); + pI830->Dummy.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, + NULL); + pI830->Dummy.Offset = 0; + } #endif - if (!pI830->SWCursor && !dryrun) { - for (i = 0; i < xf86_config->num_crtc; i++) { - if (!I830AllocateCursorBuffers(xf86_config->crtc[i], flags) && - pI830->SWCursor) - { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Disabling HW cursor because the cursor memory " - "allocation failed.\n"); - pI830->SWCursor = TRUE; - break; - } - } - } + if (!pI830->SWCursor && !dryrun) { + for (i = 0; i < xf86_config->num_crtc; i++) { + if (!I830AllocateCursorBuffers(xf86_config->crtc[i], flags) && + pI830->SWCursor) + { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Disabling HW cursor because the cursor memory " + "allocation failed.\n"); + pI830->SWCursor = TRUE; + break; + } + } + } #ifdef I830_XV - AllocateOverlay(pScrn, flags); + AllocateOverlay(pScrn, flags); #endif - if (!pI830->NeedRingBufferLow) - AllocateRingBuffer(pScrn, flags); - - /* Clear scratch info */ - memset(&(pI830->Scratch), 0, sizeof(I830MemRange)); - pI830->Scratch.Key = -1; - memset(&(pI830->Scratch2), 0, sizeof(I830MemRange)); - pI830->Scratch2.Key = -1; - - if (!pI830->noAccel) { - size = MAX_SCRATCH_BUFFER_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->Scratch), &(pI830->StolenPool), - size, GTT_PAGE_SIZE, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { - size = MIN_SCRATCH_BUFFER_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->Scratch), - &(pI830->StolenPool), size, - GTT_PAGE_SIZE, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - } - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate scratch buffer space\n"); - } - return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the scratch buffer at 0x%lx\n", s, - alloced / 1024, pI830->Scratch.Start); - - /* Let's allocate another scratch buffer for the second head */ - /* Again, this code won't execute on the dry run pass */ - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { - size = MAX_SCRATCH_BUFFER_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->Scratch2), - &(pI830->StolenPool), - size, GTT_PAGE_SIZE, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { + if (!pI830->NeedRingBufferLow) + AllocateRingBuffer(pScrn, flags); + + /* Clear scratch info */ + memset(&(pI830->Scratch), 0, sizeof(I830MemRange)); + pI830->Scratch.Key = -1; + memset(&(pI830->Scratch2), 0, sizeof(I830MemRange)); + pI830->Scratch2.Key = -1; + + if (!pI830->noAccel) { + size = MAX_SCRATCH_BUFFER_SIZE; + alloced = I830AllocVidMem(pScrn, &(pI830->Scratch), + &(pI830->StolenPool), + size, GTT_PAGE_SIZE, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); + if (alloced < size) { size = MIN_SCRATCH_BUFFER_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->Scratch2), - &(pI830->StolenPool), size, - GTT_PAGE_SIZE, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - } - if (alloced < size) { + alloced = I830AllocVidMem(pScrn, &(pI830->Scratch), + &(pI830->StolenPool), size, + GTT_PAGE_SIZE, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); + } + if (alloced < size) { if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate second scratch buffer space\n"); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate scratch buffer space\n"); } return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the second scratch buffer at 0x%lx\n", s, - alloced / 1024, pI830->Scratch2.Start); - } - } + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for the scratch buffer at 0x%lx\n", + s, alloced / 1024, pI830->Scratch.Start); + + /* Let's allocate another scratch buffer for the second head */ + /* Again, this code won't execute on the dry run pass */ + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { + size = MAX_SCRATCH_BUFFER_SIZE; + alloced = I830AllocVidMem(pScrn, &(pI830->Scratch2), + &(pI830->StolenPool), + size, GTT_PAGE_SIZE, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); + if (alloced < size) { + size = MIN_SCRATCH_BUFFER_SIZE; + alloced = I830AllocVidMem(pScrn, &(pI830->Scratch2), + &(pI830->StolenPool), size, + GTT_PAGE_SIZE, + flags | FROM_ANYWHERE | + ALLOCATE_AT_TOP); + } + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate second scratch buffer " + "space\n"); + } + return FALSE; + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for the second scratch buffer " + "at 0x%lx\n", s, + alloced / 1024, pI830->Scratch2.Start); + } + } - return TRUE; + return TRUE; } void I830ResetAllocations(ScrnInfoPtr pScrn, const int flags) { - I830Ptr pI830 = I830PTR(pScrn); + I830Ptr pI830 = I830PTR(pScrn); - pI830->MemoryAperture.Start = pI830->StolenMemory.End; - pI830->MemoryAperture.End = pI830->FbMapSize; - pI830->MemoryAperture.Size = pI830->FbMapSize - pI830->StolenMemory.Size; + pI830->MemoryAperture.Start = pI830->StolenMemory.End; + pI830->MemoryAperture.End = pI830->FbMapSize; + pI830->MemoryAperture.Size = pI830->FbMapSize - pI830->StolenMemory.Size; #ifdef XF86DRI - if (!pI830->directRenderingDisabled) { - pI830->MemoryAperture.End -= KB(pI830->mmSize); - pI830->MemoryAperture.Size -= KB(pI830->mmSize); - } + if (!pI830->directRenderingDisabled) { + pI830->MemoryAperture.End -= KB(pI830->mmSize); + pI830->MemoryAperture.Size -= KB(pI830->mmSize); + } #endif - pI830->StolenPool.Fixed = pI830->StolenMemory; - pI830->StolenPool.Total = pI830->StolenMemory; - pI830->StolenPool.Free = pI830->StolenPool.Total; - pI830->FreeMemory = pI830->TotalVideoRam - pI830->StolenPool.Total.Size; - pI830->allocatedMemory = 0; + pI830->StolenPool.Fixed = pI830->StolenMemory; + pI830->StolenPool.Total = pI830->StolenMemory; + pI830->StolenPool.Free = pI830->StolenPool.Total; + pI830->FreeMemory = pI830->TotalVideoRam - pI830->StolenPool.Total.Size; + pI830->allocatedMemory = 0; } long I830GetExcessMemoryAllocations(ScrnInfoPtr pScrn) { - I830Ptr pI830 = I830PTR(pScrn); - long allocated; - - allocated = pI830->StolenPool.Total.Size + pI830->allocatedMemory; - if (allocated > pI830->TotalVideoRam) - return allocated - pI830->TotalVideoRam; - else - return 0; + I830Ptr pI830 = I830PTR(pScrn); + long allocated; + + allocated = pI830->StolenPool.Total.Size + pI830->allocatedMemory; + if (allocated > pI830->TotalVideoRam) + return allocated - pI830->TotalVideoRam; + else + return 0; } #ifdef XF86DRI static unsigned int myLog2(unsigned int n) { - unsigned int log2 = 1; + unsigned int log2 = 1; - while (n > 1) { - n >>= 1; - log2++; - } - return log2; + while (n > 1) { + n >>= 1; + log2++; + } + return log2; } Bool I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags) { - I830Ptr pI830 = I830PTR(pScrn); - unsigned long size, alloced, align = 0; - Bool tileable; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - int lines; - int height = (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) ? pScrn->virtualY : pScrn->virtualX; - - /* Back Buffer */ - memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); - pI830->BackBuffer.Key = -1; - tileable = !(flags & ALLOC_NO_TILING) && - IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); - if (tileable) { - /* Make the height a multiple of the tile height (16) */ - lines = (height + 15) / 16 * 16; - } else { - lines = height; - } - - size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp); - /* - * Try to allocate on the best tile-friendly boundaries. - */ - alloced = 0; - if (tileable) { - align = GetBestTileAlignment(size); - for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) { - alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer), - &(pI830->StolenPool), size, align, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP | - ALIGN_BOTH_ENDS); - if (alloced >= size) - break; - } - } - if (alloced < size) { - /* Give up on trying to tile */ - tileable = FALSE; - size = ROUND_TO_PAGE(pScrn->displayWidth * height * pI830->cpp); - align = GTT_PAGE_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer), - &(pI830->StolenPool), size, align, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - } - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate back buffer space.\n"); - } - return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the back buffer at 0x%lx.\n", s, - alloced / 1024, pI830->BackBuffer.Start); + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size, alloced, align = 0; + Bool tileable; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + int lines; + int height; + + if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) + height = pScrn->virtualY; + else + height = pScrn->virtualX; + + /* Back Buffer */ + memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); + pI830->BackBuffer.Key = -1; + tileable = !(flags & ALLOC_NO_TILING) && + IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); + if (tileable) { + /* Make the height a multiple of the tile height (16) */ + lines = (height + 15) / 16 * 16; + } else { + lines = height; + } + + size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp); + /* + * Try to allocate on the best tile-friendly boundaries. + */ + alloced = 0; + if (tileable) { + align = GetBestTileAlignment(size); + for (align = GetBestTileAlignment(size); + align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) + { + alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer), + &(pI830->StolenPool), size, align, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP | + ALIGN_BOTH_ENDS); + if (alloced >= size) + break; + } + } + if (alloced < size) { + /* Give up on trying to tile */ + tileable = FALSE; + size = ROUND_TO_PAGE(pScrn->displayWidth * height * pI830->cpp); + align = GTT_PAGE_SIZE; + alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer), + &(pI830->StolenPool), size, align, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); + } + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate back buffer space.\n"); + } + return FALSE; + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for the back buffer at 0x%lx.\n", s, + alloced / 1024, pI830->BackBuffer.Start); - return TRUE; + return TRUE; } Bool I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags) { - I830Ptr pI830 = I830PTR(pScrn); - unsigned long size, alloced, align = 0; - Bool tileable; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - int lines; - int height = (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) ? pScrn->virtualY : pScrn->virtualX; - - /* Depth Buffer -- same size as the back buffer */ - memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); - pI830->DepthBuffer.Key = -1; - tileable = !(flags & ALLOC_NO_TILING) && - IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); - if (tileable) { - /* Make the height a multiple of the tile height (16) */ - lines = (height + 15) / 16 * 16; - } else { - lines = height; - } - - size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp); - /* - * Try to allocate on the best tile-friendly boundaries. - */ - alloced = 0; - if (tileable) { - align = GetBestTileAlignment(size); - for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) { - alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer), - &(pI830->StolenPool), size, align, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP | - ALIGN_BOTH_ENDS); - if (alloced >= size) - break; - } - } - if (alloced < size) { - /* Give up on trying to tile */ - tileable = FALSE; - size = ROUND_TO_PAGE(pScrn->displayWidth * height * pI830->cpp); - align = GTT_PAGE_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer), - &(pI830->StolenPool), size, align, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - } - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate depth buffer space.\n"); - } - return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the depth buffer at 0x%lx.\n", s, - alloced / 1024, pI830->DepthBuffer.Start); + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size, alloced, align = 0; + Bool tileable; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + int lines; + int height; + + if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) + height = pScrn->virtualY; + else + height = pScrn->virtualX; + + /* Depth Buffer -- same size as the back buffer */ + memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); + pI830->DepthBuffer.Key = -1; + tileable = !(flags & ALLOC_NO_TILING) && + IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); + if (tileable) { + /* Make the height a multiple of the tile height (16) */ + lines = (height + 15) / 16 * 16; + } else { + lines = height; + } + + size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp); + /* + * Try to allocate on the best tile-friendly boundaries. + */ + alloced = 0; + if (tileable) { + align = GetBestTileAlignment(size); + for (align = GetBestTileAlignment(size); + align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) + { + alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer), + &(pI830->StolenPool), size, align, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP | + ALIGN_BOTH_ENDS); + if (alloced >= size) + break; + } + } + if (alloced < size) { + /* Give up on trying to tile */ + tileable = FALSE; + size = ROUND_TO_PAGE(pScrn->displayWidth * height * pI830->cpp); + align = GTT_PAGE_SIZE; + alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer), + &(pI830->StolenPool), size, align, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); + } + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate depth buffer space.\n"); + } + return FALSE; + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for the depth buffer at 0x%lx.\n", s, + alloced / 1024, pI830->DepthBuffer.Start); - return TRUE; + return TRUE; } Bool I830AllocateTextureMemory(ScrnInfoPtr pScrn, const int flags) { - I830Ptr pI830 = I830PTR(pScrn); - unsigned long size, alloced; - int i; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - - /* Allocate the remaining space for textures. */ - memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); - pI830->TexMem.Key = -1; - - if (pI830->mmModeFlags & I830_KERNEL_TEX) { - - if (dryrun && pI830->pEnt->device->videoRam == 0) { - /* If we're laying out a default-sized allocation, then don't be - * too greedy and just ask for 32MB. - */ - size = MB(32); - } else { - size = GetFreeSpace(pScrn); - } - if (dryrun && (size < MB(1))) - size = MB(1); - i = myLog2(size / I830_NR_TEX_REGIONS); - if (i < I830_LOG_MIN_TEX_REGION_SIZE) - i = I830_LOG_MIN_TEX_REGION_SIZE; - pI830->TexGranularity = i; - /* Truncate size */ - size >>= i; - size <<= i; - if (size < KB(512)) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Less than 512 kBytes for texture space (real %ld kBytes).\n", - size / 1024); - } - return FALSE; - } - alloced = I830AllocVidMem(pScrn, &(pI830->TexMem), - &(pI830->StolenPool), size, GTT_PAGE_SIZE, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate texture space.\n"); - } - return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for textures at 0x%lx\n", s, - alloced / 1024, pI830->TexMem.Start); - } + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size, alloced; + int i; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + + /* Allocate the remaining space for textures. */ + memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); + pI830->TexMem.Key = -1; + + if (pI830->mmModeFlags & I830_KERNEL_TEX) { + if (dryrun && pI830->pEnt->device->videoRam == 0) { + /* If we're laying out a default-sized allocation, then don't be + * too greedy and just ask for 32MB. + */ + size = MB(32); + } else { + size = GetFreeSpace(pScrn); + } + if (dryrun && (size < MB(1))) + size = MB(1); + i = myLog2(size / I830_NR_TEX_REGIONS); + if (i < I830_LOG_MIN_TEX_REGION_SIZE) + i = I830_LOG_MIN_TEX_REGION_SIZE; + pI830->TexGranularity = i; + /* Truncate size */ + size >>= i; + size <<= i; + if (size < KB(512)) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Less than 512 kBytes for texture space (real %ld " + "kBytes).\n", + size / 1024); + } + return FALSE; + } + alloced = I830AllocVidMem(pScrn, &(pI830->TexMem), + &(pI830->StolenPool), size, GTT_PAGE_SIZE, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate texture space.\n"); + } + return FALSE; + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for textures at 0x%lx\n", s, + alloced / 1024, pI830->TexMem.Start); + } - return TRUE; + return TRUE; } Bool I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags) { - I830Ptr pI830 = I830PTR(pScrn); - unsigned long size, alloced; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - - DPRINTF(PFX, "I830Allocate3DMemory\n"); - - /* Space for logical context. 32k is fine for right now. */ - memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); - pI830->ContextMem.Key = -1; - size = KB(32); - alloced = I830AllocVidMem(pScrn, &(pI830->ContextMem), - &(pI830->StolenPool), size, GTT_PAGE_SIZE, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate logical context space.\n"); - } - return FALSE; - } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the logical context at 0x%lx.\n", s, - alloced / 1024, pI830->ContextMem.Start); + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size, alloced; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + + DPRINTF(PFX, "I830Allocate3DMemory\n"); + + /* Space for logical context. 32k is fine for right now. */ + memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); + pI830->ContextMem.Key = -1; + size = KB(32); + alloced = I830AllocVidMem(pScrn, &(pI830->ContextMem), + &(pI830->StolenPool), size, GTT_PAGE_SIZE, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate logical context space.\n"); + } + return FALSE; + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for the logical context at 0x%lx.\n", s, + alloced / 1024, pI830->ContextMem.Start); - if (!I830AllocateBackBuffer(pScrn, flags)) - return FALSE; + if (!I830AllocateBackBuffer(pScrn, flags)) + return FALSE; - if (!I830AllocateDepthBuffer(pScrn, flags)) - return FALSE; + if (!I830AllocateDepthBuffer(pScrn, flags)) + return FALSE; - if (!I830AllocateTextureMemory(pScrn, flags)) - return FALSE; + if (!I830AllocateTextureMemory(pScrn, flags)) + return FALSE; - return TRUE; + return TRUE; } #endif @@ -1273,39 +1307,40 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags) Bool I830DoPoolAllocation(ScrnInfoPtr pScrn, I830MemPool *pool) { - I830Ptr pI830 = I830PTR(pScrn); - - DPRINTF(PFX, "I830DoPoolAllocation\n"); - - if (!pool) - return FALSE; - - /* - * Sanity check: there shouldn't be an allocation required when - * there is only stolen memory. - */ - if (pI830->StolenOnly && (pool->Total.Size > pool->Fixed.Size)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "I830DoPoolAllocation(): pool size is greater than the " - "preallocated size,\n\t" - "and there is no allocatable memory.\n"); - return FALSE; - } - - if (pool->Total.Size > pool->Fixed.Size) { - pool->Allocated.Size = pool->Total.Size - pool->Fixed.Size; - pool->Allocated.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, - pool->Allocated.Size, 0, NULL); - if (pool->Allocated.Key == -1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Pool allocation failed\n"); - return FALSE; - } - pool->Allocated.Start = pool->Fixed.End; - pool->Allocated.End = pool->Total.Size; - pool->Allocated.Offset = pool->Allocated.Start; - } else - pool->Allocated.Key = -1; - return TRUE; + I830Ptr pI830 = I830PTR(pScrn); + + DPRINTF(PFX, "I830DoPoolAllocation\n"); + + if (!pool) + return FALSE; + + /* + * Sanity check: there shouldn't be an allocation required when + * there is only stolen memory. + */ + if (pI830->StolenOnly && (pool->Total.Size > pool->Fixed.Size)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "I830DoPoolAllocation(): pool size is greater than the " + "preallocated size,\n\t" + "and there is no allocatable memory.\n"); + return FALSE; + } + + if (pool->Total.Size > pool->Fixed.Size) { + pool->Allocated.Size = pool->Total.Size - pool->Fixed.Size; + pool->Allocated.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, + pool->Allocated.Size, 0, + NULL); + if (pool->Allocated.Key == -1) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Pool allocation failed\n"); + return FALSE; + } + pool->Allocated.Start = pool->Fixed.End; + pool->Allocated.End = pool->Total.Size; + pool->Allocated.Offset = pool->Allocated.Start; + } else + pool->Allocated.Key = -1; + return TRUE; } static unsigned long topOfMem = 0; @@ -1333,114 +1368,117 @@ Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem) { #if POOL_RANGES - I830Ptr pI830 = I830PTR(pScrn); + I830Ptr pI830 = I830PTR(pScrn); #endif - if (!mem) - return FALSE; + if (!mem) + return FALSE; - if (mem->Pool && mem->Key == -1 && mem->Start < 0) { - mem->Start = mem->Pool->Total.End + mem->Start; - mem->End = mem->Start + mem->Size; - } + if (mem->Pool && mem->Key == -1 && mem->Start < 0) { + mem->Start = mem->Pool->Total.End + mem->Start; + mem->End = mem->Start + mem->Size; + } #if PACK_RANGES - /* - * Map AGP-allocated areas at the top of the stolen area, resulting in - * a contiguous region in the aperture. Normally most AGP-allocated areas - * will be at the top of the aperture, making alignment requirements - * easier to achieve. This optin is primarily for debugging purposes, - * and using this option can break any special alignment requirements. - */ - if (!mem->Pool && mem->Start != 0 && mem->Key != -1 && mem->Physical == 0 && - mem->Offset != 0) { - long diff; - if (mem->Offset != mem->Start) - ErrorF("mem %p, Offset != Start\n", mem); - diff = mem->Offset - topOfMem; - mem->Start -= diff; - mem->End -= diff; - mem->Offset -= diff; - topOfMem += mem->Size; - } + /* + * Map AGP-allocated areas at the top of the stolen area, resulting in + * a contiguous region in the aperture. Normally most AGP-allocated areas + * will be at the top of the aperture, making alignment requirements + * easier to achieve. This optin is primarily for debugging purposes, + * and using this option can break any special alignment requirements. + */ + if (!mem->Pool && mem->Start != 0 && mem->Key != -1 && + mem->Physical == 0 && mem->Offset != 0) + { + long diff; + if (mem->Offset != mem->Start) + ErrorF("mem %p, Offset != Start\n", mem); + diff = mem->Offset - topOfMem; + mem->Start -= diff; + mem->End -= diff; + mem->Offset -= diff; + topOfMem += mem->Size; + } #elif POOL_RANGES - /* - * Move AGP-allocated regions (that don't need a physical address) into - * the pre-allocated pool when there's enough space to do so. Note: the - * AGP-allocated areas aren't freed. This option is primarily for - * debugging purposes, and using it can break any special alignment - * requirements. - */ - if (!mem->Pool && mem->Start >= pI830->StolenPool.Free.End && - mem->Key != -1 && mem->Physical == 0 && mem->Offset != 0 && - pI830->StolenPool.Free.Size >= mem->Size) { - long diff; - if (mem->Offset != mem->Start) - ErrorF("mem %p, Offset != Start\n", mem); - diff = mem->Offset - pI830->StolenPool.Free.Start; - mem->Start -= diff; - mem->End -= diff; - mem->Offset -= diff; - mem->Key = -1; - pI830->StolenPool.Free.Start += mem->Size; - pI830->StolenPool.Free.Size -= mem->Size; - } + /* + * Move AGP-allocated regions (that don't need a physical address) into + * the pre-allocated pool when there's enough space to do so. Note: the + * AGP-allocated areas aren't freed. This option is primarily for + * debugging purposes, and using it can break any special alignment + * requirements. + */ + if (!mem->Pool && mem->Start >= pI830->StolenPool.Free.End && + mem->Key != -1 && mem->Physical == 0 && mem->Offset != 0 && + pI830->StolenPool.Free.Size >= mem->Size) + { + long diff; + + if (mem->Offset != mem->Start) + ErrorF("mem %p, Offset != Start\n", mem); + diff = mem->Offset - pI830->StolenPool.Free.Start; + mem->Start -= diff; + mem->End -= diff; + mem->Offset -= diff; + mem->Key = -1; + pI830->StolenPool.Free.Start += mem->Size; + pI830->StolenPool.Free.Size -= mem->Size; + } #endif - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%p: Memory at offset 0x%08lx, size %ld kBytes\n", (void *)mem, - mem->Start, mem->Size / 1024); - return TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "%p: Memory at offset 0x%08lx, size %ld kBytes\n", (void *)mem, + mem->Start, mem->Size / 1024); + return TRUE; } Bool I830FixupOffsets(ScrnInfoPtr pScrn) { - I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; + I830Ptr pI830 = I830PTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; - DPRINTF(PFX, "I830FixupOffsets\n"); + DPRINTF(PFX, "I830FixupOffsets\n"); - topOfMem = pI830->StolenPool.Total.End; - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - I830FixOffset(pScrn, &(pI830->FrontBuffer2)); - I830FixOffset(pScrn, &(pI830->FrontBuffer)); + topOfMem = pI830->StolenPool.Total.End; + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) + I830FixOffset(pScrn, &(pI830->FrontBuffer2)); + I830FixOffset(pScrn, &(pI830->FrontBuffer)); - for (i = 0; i < xf86_config->num_crtc; i++) { - I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; + for (i = 0; i < xf86_config->num_crtc; i++) { + I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; - I830FixOffset(pScrn, &intel_crtc->cursor_mem); - I830FixOffset(pScrn, &intel_crtc->cursor_mem_argb); - } + I830FixOffset(pScrn, &intel_crtc->cursor_mem); + I830FixOffset(pScrn, &intel_crtc->cursor_mem_argb); + } - I830FixOffset(pScrn, &(pI830->LpRing->mem)); - I830FixOffset(pScrn, &(pI830->Scratch)); - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - I830FixOffset(pScrn, &(pI830->Scratch2)); + I830FixOffset(pScrn, &(pI830->LpRing->mem)); + I830FixOffset(pScrn, &(pI830->Scratch)); + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) + I830FixOffset(pScrn, &(pI830->Scratch2)); #ifdef I830_XV - if (pI830->XvEnabled) { - I830FixOffset(pScrn, pI830->OverlayMem); - if (pI830->LinearAlloc) - I830FixOffset(pScrn, &(pI830->LinearMem)); - } + if (pI830->XvEnabled) { + I830FixOffset(pScrn, pI830->OverlayMem); + if (pI830->LinearAlloc) + I830FixOffset(pScrn, &(pI830->LinearMem)); + } #endif #ifdef XF86DRI - if (pI830->directRenderingEnabled) { - I830FixOffset(pScrn, &(pI830->ContextMem)); - I830FixOffset(pScrn, &(pI830->BackBuffer)); - I830FixOffset(pScrn, &(pI830->DepthBuffer)); - if (pI830->mmModeFlags & I830_KERNEL_TEX) { - I830FixOffset(pScrn, &(pI830->TexMem)); - } - } + if (pI830->directRenderingEnabled) { + I830FixOffset(pScrn, &(pI830->ContextMem)); + I830FixOffset(pScrn, &(pI830->BackBuffer)); + I830FixOffset(pScrn, &(pI830->DepthBuffer)); + if (pI830->mmModeFlags & I830_KERNEL_TEX) { + I830FixOffset(pScrn, &(pI830->TexMem)); + } + } #endif #ifdef I830_USE_EXA - if (pI830->useEXA) { - I830FixOffset(pScrn, &(pI830->Offscreen)); - if (IS_I965G(pI830)) - I830FixOffset(pScrn, &(pI830->EXAStateMem)); + if (pI830->useEXA) { + I830FixOffset(pScrn, &(pI830->Offscreen)); + if (IS_I965G(pI830)) + I830FixOffset(pScrn, &(pI830->EXAStateMem)); } #endif - return TRUE; + return TRUE; } #ifdef XF86DRI @@ -1455,499 +1493,505 @@ static void SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, unsigned int size) { - I830Ptr pI830 = I830PTR(pScrn); - I830RegPtr i830Reg = &pI830->ModeReg; - CARD32 val; - CARD32 fence_mask = 0; - unsigned int fence_pitch; - - DPRINTF(PFX, "SetFence: %d, 0x%08x, %d, %d kByte\n", - nr, start, pitch, size / 1024); - - if (nr < 0 || nr > 7) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: fence %d out of range\n",nr); - return; - } + I830Ptr pI830 = I830PTR(pScrn); + I830RegPtr i830Reg = &pI830->ModeReg; + CARD32 val; + CARD32 fence_mask = 0; + unsigned int fence_pitch; + + DPRINTF(PFX, "SetFence: %d, 0x%08x, %d, %d kByte\n", + nr, start, pitch, size / 1024); + + if (nr < 0 || nr > 7) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "SetFence: fence %d out of range\n",nr); + return; + } - i830Reg->Fence[nr] = 0; + i830Reg->Fence[nr] = 0; - if (IS_I9XX(pI830)) + if (IS_I9XX(pI830)) fence_mask = ~I915G_FENCE_START_MASK; - else + else fence_mask = ~I830_FENCE_START_MASK; - if (start & fence_mask) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: start (0x%08x) is not %s aligned\n", - nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); - return; - } - - if (start % size) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", - nr, start, size / 1024); - return; - } - - if (pitch & 127) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", - nr, pitch); - return; - } - - val = (start | FENCE_X_MAJOR | FENCE_VALID); - - if (IS_I9XX(pI830)) { + if (start & fence_mask) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "SetFence: %d: start (0x%08x) is not %s aligned\n", + nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); + return; + } + + if (start % size) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", + nr, start, size / 1024); + return; + } + + if (pitch & 127) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", + nr, pitch); + return; + } + + val = (start | FENCE_X_MAJOR | FENCE_VALID); + + if (IS_I9XX(pI830)) { switch (size) { - case MB(1): - val |= I915G_FENCE_SIZE_1M; - break; - case MB(2): - val |= I915G_FENCE_SIZE_2M; - break; - case MB(4): - val |= I915G_FENCE_SIZE_4M; - break; - case MB(8): - val |= I915G_FENCE_SIZE_8M; - break; + case MB(1): + val |= I915G_FENCE_SIZE_1M; + break; + case MB(2): + val |= I915G_FENCE_SIZE_2M; + break; + case MB(4): + val |= I915G_FENCE_SIZE_4M; + break; + case MB(8): + val |= I915G_FENCE_SIZE_8M; + break; case MB(16): - val |= I915G_FENCE_SIZE_16M; - break; - case MB(32): - val |= I915G_FENCE_SIZE_32M; - break; - case MB(64): - val |= I915G_FENCE_SIZE_64M; - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; + val |= I915G_FENCE_SIZE_16M; + break; + case MB(32): + val |= I915G_FENCE_SIZE_32M; + break; + case MB(64): + val |= I915G_FENCE_SIZE_64M; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "SetFence: %d: illegal size (%d kByte)\n", + nr, size / 1024); + return; } } else { switch (size) { - case KB(512): - val |= FENCE_SIZE_512K; - break; - case MB(1): - val |= FENCE_SIZE_1M; - break; - case MB(2): - val |= FENCE_SIZE_2M; - break; - case MB(4): - val |= FENCE_SIZE_4M; - break; - case MB(8): - val |= FENCE_SIZE_8M; - break; - case MB(16): - val |= FENCE_SIZE_16M; - break; - case MB(32): - val |= FENCE_SIZE_32M; - break; - case MB(64): - val |= FENCE_SIZE_64M; - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; + case KB(512): + val |= FENCE_SIZE_512K; + break; + case MB(1): + val |= FENCE_SIZE_1M; + break; + case MB(2): + val |= FENCE_SIZE_2M; + break; + case MB(4): + val |= FENCE_SIZE_4M; + break; + case MB(8): + val |= FENCE_SIZE_8M; + break; + case MB(16): + val |= FENCE_SIZE_16M; + break; + case MB(32): + val |= FENCE_SIZE_32M; + break; + case MB(64): + val |= FENCE_SIZE_64M; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "SetFence: %d: illegal size (%d kByte)\n", + nr, size / 1024); + return; } - } + } - if (IS_I9XX(pI830)) + if (IS_I9XX(pI830)) fence_pitch = pitch / 512; - else + else fence_pitch = pitch / 128; - switch (fence_pitch) { - case 1: - val |= FENCE_PITCH_1; - break; - case 2: - val |= FENCE_PITCH_2; - break; - case 4: - val |= FENCE_PITCH_4; - break; - case 8: - val |= FENCE_PITCH_8; - break; - case 16: - val |= FENCE_PITCH_16; - break; - case 32: - val |= FENCE_PITCH_32; - break; - case 64: - val |= FENCE_PITCH_64; - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: illegal pitch (%d)\n", nr, pitch); - return; - } - - i830Reg->Fence[nr] = val; + switch (fence_pitch) { + case 1: + val |= FENCE_PITCH_1; + break; + case 2: + val |= FENCE_PITCH_2; + break; + case 4: + val |= FENCE_PITCH_4; + break; + case 8: + val |= FENCE_PITCH_8; + break; + case 16: + val |= FENCE_PITCH_16; + break; + case 32: + val |= FENCE_PITCH_32; + break; + case 64: + val |= FENCE_PITCH_64; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "SetFence: %d: illegal pitch (%d)\n", nr, pitch); + return; + } + + i830Reg->Fence[nr] = val; } static Bool MakeTiles(ScrnInfoPtr pScrn, I830MemRange *pMem, unsigned int fence) { - I830Ptr pI830 = I830PTR(pScrn); - int pitch, ntiles, i; + I830Ptr pI830 = I830PTR(pScrn); + int pitch, ntiles, i; #if 0 - /* Hack to "improve" the alignment of the front buffer. - */ - while (!(pMem->Start & ~pMem->Alignment) && pMem->Alignment < 0x00400000 ) - pMem->Alignment <<= 1; + /* Hack to "improve" the alignment of the front buffer. */ + while (!(pMem->Start & ~pMem->Alignment) && pMem->Alignment < 0x00400000 ) + pMem->Alignment <<= 1; #endif - if (tileGeneration != serverGeneration) { - tileGeneration = serverGeneration; - nextTile = 0; - } + if (tileGeneration != serverGeneration) { + tileGeneration = serverGeneration; + nextTile = 0; + } - pitch = pScrn->displayWidth * pI830->cpp; + pitch = pScrn->displayWidth * pI830->cpp; - if (IS_I965G(pI830)) { - I830RegPtr i830Reg = &pI830->ModeReg; + if (IS_I965G(pI830)) { + I830RegPtr i830Reg = &pI830->ModeReg; - switch (fence) { - case FENCE_XMAJOR: - i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | pMem->Start | 1; + switch (fence) { + case FENCE_XMAJOR: + i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | + pMem->Start | 1; break; - case FENCE_YMAJOR: + case FENCE_YMAJOR: /* YMajor can be 128B aligned but the current code dictates * otherwise. This isn't a problem apart from memory waste. * FIXME */ - i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | pMem->Start | 1; + i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | + pMem->Start | 1; i830Reg->Fence[nextTile] |= (1<<1); break; - default: - case FENCE_LINEAR: + default: + case FENCE_LINEAR: break; - } + } + + i830Reg->Fence[nextTile+FENCE_NEW_NR] = pMem->End; + nextTile++; + return TRUE; + } - i830Reg->Fence[nextTile+FENCE_NEW_NR] = pMem->End; - nextTile++; - return TRUE; - } - - /* - * Simply try to break the region up into at most four pieces of size - * equal to the alignment. - */ - ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; - if (ntiles >= 4) { - return FALSE; - } - - for (i = 0; i < ntiles; i++, nextTile++) { - SetFence(pScrn, nextTile, pMem->Start + i * pMem->Alignment, - pitch, pMem->Alignment); - } - return TRUE; + /* + * Simply try to break the region up into at most four pieces of size + * equal to the alignment. + */ + ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; + if (ntiles >= 4) { + return FALSE; + } + + for (i = 0; i < ntiles; i++, nextTile++) { + SetFence(pScrn, nextTile, pMem->Start + i * pMem->Alignment, + pitch, pMem->Alignment); + } + return TRUE; } void I830SetupMemoryTiling(ScrnInfoPtr pScrn) { - I830Ptr pI830 = I830PTR(pScrn); - int i; - - /* Clear out */ - if (IS_I965G(pI830)) { - for (i = 0; i < FENCE_NEW_NR*2; i++) - pI830->ModeReg.Fence[i] = 0; - } else { - for (i = 0; i < 8; i++) - pI830->ModeReg.Fence[i] = 0; - } - - nextTile = 0; - tileGeneration = -1; - - /* We currently only attempt to tile the back and depth buffers. */ - if (!pI830->directRenderingEnabled) - return; - - if (!IsTileable(pScrn, pScrn->displayWidth * pI830->cpp)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "I830SetupMemoryTiling: Not tileable 0x%x\n", - pScrn->displayWidth * pI830->cpp); - pI830->allowPageFlip = FALSE; - return; - } - - pI830->front_tiled = FENCE_LINEAR; - pI830->back_tiled = FENCE_LINEAR; - pI830->depth_tiled = FENCE_LINEAR; - - if (pI830->allowPageFlip) { - if (pI830->allowPageFlip && pI830->FrontBuffer.Alignment >= KB(512)) { - if (MakeTiles(pScrn, &(pI830->FrontBuffer), FENCE_XMAJOR)) { + I830Ptr pI830 = I830PTR(pScrn); + int i; + + /* Clear out */ + if (IS_I965G(pI830)) { + for (i = 0; i < FENCE_NEW_NR*2; i++) + pI830->ModeReg.Fence[i] = 0; + } else { + for (i = 0; i < 8; i++) + pI830->ModeReg.Fence[i] = 0; + } + + nextTile = 0; + tileGeneration = -1; + + /* We currently only attempt to tile the back and depth buffers. */ + if (!pI830->directRenderingEnabled) + return; + + if (!IsTileable(pScrn, pScrn->displayWidth * pI830->cpp)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "I830SetupMemoryTiling: Not tileable 0x%x\n", + pScrn->displayWidth * pI830->cpp); + pI830->allowPageFlip = FALSE; + return; + } + + pI830->front_tiled = FENCE_LINEAR; + pI830->back_tiled = FENCE_LINEAR; + pI830->depth_tiled = FENCE_LINEAR; + + if (pI830->allowPageFlip) { + if (pI830->allowPageFlip && pI830->FrontBuffer.Alignment >= KB(512)) { + if (MakeTiles(pScrn, &(pI830->FrontBuffer), FENCE_XMAJOR)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Activating tiled memory for the front buffer\n"); + pI830->front_tiled = FENCE_XMAJOR; + } else { + pI830->allowPageFlip = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MakeTiles failed for the front buffer\n"); + } + } else { + pI830->allowPageFlip = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Alignment bad for the front buffer\n"); + } + } + + /* + * We tried to get the best alignment during the allocation. Check + * the alignment values to tell. If well-aligned allocations were + * successful, the address range reserved is a multiple of the align + * value. + */ + if (pI830->BackBuffer.Alignment >= KB(512)) { + if (MakeTiles(pScrn, &(pI830->BackBuffer), FENCE_XMAJOR)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Activating tiled memory for the front buffer\n"); - pI830->front_tiled = FENCE_XMAJOR; - } else { + "Activating tiled memory for the back buffer.\n"); + pI830->back_tiled = FENCE_XMAJOR; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MakeTiles failed for the back buffer.\n"); pI830->allowPageFlip = FALSE; + } + } + + if (pI830->DepthBuffer.Alignment >= KB(512)) { + if (MakeTiles(pScrn, &(pI830->DepthBuffer), FENCE_YMAJOR)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MakeTiles failed for the front buffer\n"); - } - } else { - pI830->allowPageFlip = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Alignment bad for the front buffer\n"); - } - } - - /* - * We tried to get the best alignment during the allocation. Check - * the alignment values to tell. If well-aligned allocations were - * successful, the address range reserved is a multiple of the align - * value. - */ - if (pI830->BackBuffer.Alignment >= KB(512)) { - if (MakeTiles(pScrn, &(pI830->BackBuffer), FENCE_XMAJOR)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Activating tiled memory for the back buffer.\n"); - pI830->back_tiled = FENCE_XMAJOR; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MakeTiles failed for the back buffer.\n"); - pI830->allowPageFlip = FALSE; - } - } - - if (pI830->DepthBuffer.Alignment >= KB(512)) { - if (MakeTiles(pScrn, &(pI830->DepthBuffer), FENCE_YMAJOR)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Activating tiled memory for the depth buffer.\n"); - pI830->depth_tiled = FENCE_YMAJOR; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MakeTiles failed for the depth buffer.\n"); - } - }} + "Activating tiled memory for the depth buffer.\n"); + pI830->depth_tiled = FENCE_YMAJOR; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MakeTiles failed for the depth buffer.\n"); + } + } +} #endif /* XF86DRI */ static Bool BindMemRange(ScrnInfoPtr pScrn, I830MemRange *mem) { - if (!mem) - return FALSE; + if (!mem) + return FALSE; - if (mem->Key == -1) - return TRUE; + if (mem->Key == -1) + return TRUE; - return xf86BindGARTMemory(pScrn->scrnIndex, mem->Key, mem->Offset); + return xf86BindGARTMemory(pScrn->scrnIndex, mem->Key, mem->Offset); } Bool I830BindAGPMemory(ScrnInfoPtr pScrn) { - I830Ptr pI830 = I830PTR(pScrn); + I830Ptr pI830 = I830PTR(pScrn); - DPRINTF(PFX, - "I830BindAGPMemory: StolenOnly is %s, pI830->GttBound is %s\n", - BOOLTOSTRING(pI830->StolenOnly), BOOLTOSTRING(pI830->GttBound)); + DPRINTF(PFX, + "I830BindAGPMemory: StolenOnly is %s, pI830->GttBound is %s\n", + BOOLTOSTRING(pI830->StolenOnly), BOOLTOSTRING(pI830->GttBound)); - if (pI830->StolenOnly == TRUE) - return TRUE; + if (pI830->StolenOnly == TRUE) + return TRUE; - if (xf86AgpGARTSupported() && !pI830->GttBound) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; + if (xf86AgpGARTSupported() && !pI830->GttBound) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; - if (!xf86AcquireGART(pScrn->scrnIndex)) - return FALSE; + if (!xf86AcquireGART(pScrn->scrnIndex)) + return FALSE; #if REMAP_RESERVED - /* Rebind the pre-allocated region. */ - BindMemRange(pScrn, &(pI830->Dummy)); + /* Rebind the pre-allocated region. */ + BindMemRange(pScrn, &(pI830->Dummy)); #endif - if (!BindMemRange(pScrn, &(pI830->StolenPool.Allocated))) - return FALSE; - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - if (!BindMemRange(pScrn, &(pI830->FrontBuffer2))) + if (!BindMemRange(pScrn, &(pI830->StolenPool.Allocated))) + return FALSE; + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) + if (!BindMemRange(pScrn, &(pI830->FrontBuffer2))) + return FALSE; + if (!BindMemRange(pScrn, &(pI830->FrontBuffer))) return FALSE; - if (!BindMemRange(pScrn, &(pI830->FrontBuffer))) - return FALSE; - for (i = 0; i < xf86_config->num_crtc; i++) { - I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; + for (i = 0; i < xf86_config->num_crtc; i++) { + I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; - if (!BindMemRange(pScrn, &intel_crtc->cursor_mem)) + if (!BindMemRange(pScrn, &intel_crtc->cursor_mem)) + return FALSE; + if (!BindMemRange(pScrn, &intel_crtc->cursor_mem_argb)) + return FALSE; + } + if (!BindMemRange(pScrn, &(pI830->LpRing->mem))) return FALSE; - if (!BindMemRange(pScrn, &intel_crtc->cursor_mem_argb)) - return FALSE; - } - if (!BindMemRange(pScrn, &(pI830->LpRing->mem))) - return FALSE; - if (!BindMemRange(pScrn, &(pI830->Scratch))) - return FALSE; - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - if (!BindMemRange(pScrn, &(pI830->Scratch2))) + if (!BindMemRange(pScrn, &(pI830->Scratch))) return FALSE; + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) + if (!BindMemRange(pScrn, &(pI830->Scratch2))) + return FALSE; #ifdef I830_XV - if (pI830->XvEnabled) { - if (!BindMemRange(pScrn, pI830->OverlayMem)) - return FALSE; - if (pI830->LinearAlloc) - if (!BindMemRange(pScrn, &(pI830->LinearMem))) - return FALSE; + if (pI830->XvEnabled) { + if (!BindMemRange(pScrn, pI830->OverlayMem)) + return FALSE; + if (pI830->LinearAlloc) + if (!BindMemRange(pScrn, &(pI830->LinearMem))) + return FALSE; } #endif #ifdef XF86DRI - if (pI830->directRenderingEnabled) { - if (!BindMemRange(pScrn, &(pI830->ContextMem))) - return FALSE; - if (!BindMemRange(pScrn, &(pI830->BackBuffer))) - return FALSE; - if (!BindMemRange(pScrn, &(pI830->DepthBuffer))) - return FALSE; - if ((pI830->mmModeFlags & I830_KERNEL_TEX) && - !BindMemRange(pScrn, &(pI830->TexMem))) - return FALSE; + if (pI830->directRenderingEnabled) { + if (!BindMemRange(pScrn, &(pI830->ContextMem))) + return FALSE; + if (!BindMemRange(pScrn, &(pI830->BackBuffer))) + return FALSE; + if (!BindMemRange(pScrn, &(pI830->DepthBuffer))) + return FALSE; + if ((pI830->mmModeFlags & I830_KERNEL_TEX) && + !BindMemRange(pScrn, &(pI830->TexMem))) + return FALSE; } #endif #ifdef I830_USE_EXA - if (pI830->useEXA) { - if (!BindMemRange(pScrn, &(pI830->Offscreen))) - return FALSE; - if (IS_I965G(pI830) && !BindMemRange(pScrn, &(pI830->EXAStateMem))) - return FALSE; - } + if (pI830->useEXA) { + if (!BindMemRange(pScrn, &(pI830->Offscreen))) + return FALSE; + if (IS_I965G(pI830) && !BindMemRange(pScrn, &(pI830->EXAStateMem))) + return FALSE; + } #endif - pI830->GttBound = 1; - } + pI830->GttBound = 1; + } - return TRUE; + return TRUE; } static Bool UnbindMemRange(ScrnInfoPtr pScrn, I830MemRange *mem) { - if (!mem) - return FALSE; + if (!mem) + return FALSE; - if (mem->Key == -1) - return TRUE; + if (mem->Key == -1) + return TRUE; - return xf86UnbindGARTMemory(pScrn->scrnIndex, mem->Key); + return xf86UnbindGARTMemory(pScrn->scrnIndex, mem->Key); } Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn) { - I830Ptr pI830 = I830PTR(pScrn); + I830Ptr pI830 = I830PTR(pScrn); - DPRINTF(PFX, - "I830UnbindAGPMemory: StolenOnly is %s, pI830->GttBound is %s\n", - BOOLTOSTRING(pI830->StolenOnly), BOOLTOSTRING(pI830->GttBound)); + DPRINTF(PFX, + "I830UnbindAGPMemory: StolenOnly is %s, pI830->GttBound is %s\n", + BOOLTOSTRING(pI830->StolenOnly), BOOLTOSTRING(pI830->GttBound)); - if (pI830->StolenOnly == TRUE) - return TRUE; + if (pI830->StolenOnly == TRUE) + return TRUE; - if (xf86AgpGARTSupported() && pI830->GttBound) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; + if (xf86AgpGARTSupported() && pI830->GttBound) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; #if REMAP_RESERVED - /* "unbind" the pre-allocated region. */ - UnbindMemRange(pScrn, &(pI830->Dummy)); + /* "unbind" the pre-allocated region. */ + UnbindMemRange(pScrn, &(pI830->Dummy)); #endif - if (!UnbindMemRange(pScrn, &(pI830->StolenPool.Allocated))) - return FALSE; - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer2))) + if (!UnbindMemRange(pScrn, &(pI830->StolenPool.Allocated))) + return FALSE; + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) + if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer2))) + return FALSE; + if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer))) return FALSE; - if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer))) - return FALSE; - for (i = 0; i < xf86_config->num_crtc; i++) { - I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; + for (i = 0; i < xf86_config->num_crtc; i++) { + I830CrtcPrivatePtr intel_crtc = + xf86_config->crtc[i]->driver_private; - if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem)) - return FALSE; - if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem_argb)) - return FALSE; - } + if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem)) + return FALSE; + if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem_argb)) + return FALSE; + } - if (!UnbindMemRange(pScrn, &(pI830->LpRing->mem))) - return FALSE; - if (!UnbindMemRange(pScrn, &(pI830->Scratch))) - return FALSE; - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - if (!UnbindMemRange(pScrn, &(pI830->Scratch2))) + if (!UnbindMemRange(pScrn, &(pI830->LpRing->mem))) return FALSE; -#ifdef I830_XV - if (pI830->XvEnabled) { - if (!UnbindMemRange(pScrn, pI830->OverlayMem)) + if (!UnbindMemRange(pScrn, &(pI830->Scratch))) return FALSE; - if (pI830->LinearAlloc) - if (!UnbindMemRange(pScrn, &(pI830->LinearMem))) - return FALSE; - } + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) + if (!UnbindMemRange(pScrn, &(pI830->Scratch2))) + return FALSE; +#ifdef I830_XV + if (pI830->XvEnabled) { + if (!UnbindMemRange(pScrn, pI830->OverlayMem)) + return FALSE; + if (pI830->LinearAlloc) + if (!UnbindMemRange(pScrn, &(pI830->LinearMem))) + return FALSE; + } #endif #ifdef XF86DRI - if (pI830->directRenderingEnabled) { - if (!UnbindMemRange(pScrn, &(pI830->ContextMem))) - return FALSE; - if (!UnbindMemRange(pScrn, &(pI830->BackBuffer))) - return FALSE; - if (!UnbindMemRange(pScrn, &(pI830->DepthBuffer))) - return FALSE; - if ((pI830->mmModeFlags & I830_KERNEL_TEX) && - !UnbindMemRange(pScrn, &(pI830->TexMem))) - return FALSE; - } + if (pI830->directRenderingEnabled) { + if (!UnbindMemRange(pScrn, &(pI830->ContextMem))) + return FALSE; + if (!UnbindMemRange(pScrn, &(pI830->BackBuffer))) + return FALSE; + if (!UnbindMemRange(pScrn, &(pI830->DepthBuffer))) + return FALSE; + if ((pI830->mmModeFlags & I830_KERNEL_TEX) && + !UnbindMemRange(pScrn, &(pI830->TexMem))) + return FALSE; + } #endif #ifdef I830_USE_EXA - if (pI830->useEXA) { - if (!UnbindMemRange(pScrn, &(pI830->Offscreen))) - return FALSE; - if (IS_I965G(pI830) && !UnbindMemRange(pScrn, &(pI830->EXAStateMem))) - return FALSE; - } + if (pI830->useEXA) { + if (!UnbindMemRange(pScrn, &(pI830->Offscreen))) + return FALSE; + if (IS_I965G(pI830) && !UnbindMemRange(pScrn, + &(pI830->EXAStateMem))) + return FALSE; + } #endif - if (!xf86ReleaseGART(pScrn->scrnIndex)) - return FALSE; + if (!xf86ReleaseGART(pScrn->scrnIndex)) + return FALSE; - pI830->GttBound = 0; - } + pI830->GttBound = 0; + } - return TRUE; + return TRUE; } long I830CheckAvailableMemory(ScrnInfoPtr pScrn) { - AgpInfoPtr agpinf; - int maxPages; + AgpInfoPtr agpinf; + int maxPages; - if (!xf86AgpGARTSupported() || - !xf86AcquireGART(pScrn->scrnIndex) || - (agpinf = xf86GetAGPInfo(pScrn->scrnIndex)) == NULL || - !xf86ReleaseGART(pScrn->scrnIndex)) - return -1; + if (!xf86AgpGARTSupported() || + !xf86AcquireGART(pScrn->scrnIndex) || + (agpinf = xf86GetAGPInfo(pScrn->scrnIndex)) == NULL || + !xf86ReleaseGART(pScrn->scrnIndex)) + return -1; - maxPages = agpinf->totalPages - agpinf->usedPages; - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "%s: %d kB available\n", - "I830CheckAvailableMemory", maxPages * 4); + maxPages = agpinf->totalPages - agpinf->usedPages; + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "%s: %d kB available\n", + "I830CheckAvailableMemory", maxPages * 4); - return maxPages * 4; + return maxPages * 4; } #ifdef I830_USE_XAA @@ -1962,28 +2006,28 @@ i830_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length, RemoveLinearCallbackProcPtr removeCB, pointer privData) { - FBLinearPtr linear; - int max_size; + FBLinearPtr linear; + int max_size; - linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, - removeCB, privData); - if (linear != NULL) - return linear; + linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, + removeCB, privData); + if (linear != NULL) + return linear; - /* The above allocation didn't succeed, so purge unlocked stuff and try - * again. - */ - xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity, - PRIORITY_EXTREME); + /* The above allocation didn't succeed, so purge unlocked stuff and try + * again. + */ + xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity, + PRIORITY_EXTREME); - if (max_size < length) - return NULL; + if (max_size < length) + return NULL; - xf86PurgeUnlockedOffscreenAreas(pScreen); + xf86PurgeUnlockedOffscreenAreas(pScreen); - linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, - removeCB, privData); + linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB, + removeCB, privData); - return linear; + return linear; } #endif -- cgit v1.2.3 From d3ac440e127c8a7716062852cd3b5e7943e289e4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 22 Feb 2007 10:41:09 -0800 Subject: Rework the video memory allocation. The previous allocator worked in multiple passes, with (at least) one of setting up allocations, another to attempt to adjust those for tiling, and then a pass to set up the offsets and fix them in memory. The new allocator is simpler, allocating memory immediately if possible, setting up tiling up front, and choosing offsets immediately. AGP memory is only allocated to back actual memory used, saving some memory that would have been allocated for padding previous. It will also allow dynamic freeing and reallocation of memory, which will be useful for framebuffer resizing. --- src/i810_reg.h | 2 + src/i830.h | 175 +++-- src/i830_accel.c | 12 +- src/i830_cursor.c | 17 +- src/i830_display.c | 6 +- src/i830_dri.c | 42 +- src/i830_driver.c | 441 ++++------- src/i830_exa.c | 5 +- src/i830_memory.c | 2162 ++++++++++++++++++++-------------------------------- src/i830_video.c | 23 +- src/i830_xaa.c | 26 +- src/i965_render.c | 4 +- 12 files changed, 1163 insertions(+), 1752 deletions(-) diff --git a/src/i810_reg.h b/src/i810_reg.h index 455c226a..46d473d7 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -488,6 +488,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define I915G_FENCE_SIZE_32M 0x00000500 #define I915G_FENCE_SIZE_64M 0x00000600 #define I915G_FENCE_SIZE_128M 0x00000700 +#define I965_FENCE_X_MAJOR 0x00000000 +#define I965_FENCE_Y_MAJOR 0x00000002 #define FENCE_PITCH_1 0x00000000 #define FENCE_PITCH_2 0x00000010 #define FENCE_PITCH_4 0x00000020 diff --git a/src/i830.h b/src/i830.h index f52f1496..f779978c 100644 --- a/src/i830.h +++ b/src/i830.h @@ -113,40 +113,58 @@ typedef CARD8(*I830ReadIndexedByteFunc)(I830Ptr pI830, IOADDRESS addr, typedef void (*I830WriteByteFunc)(I830Ptr pI830, IOADDRESS addr, CARD8 value); typedef CARD8(*I830ReadByteFunc)(I830Ptr pI830, IOADDRESS addr); -/* Linear region allocated in framebuffer. */ -typedef struct _I830MemPool *I830MemPoolPtr; -typedef struct _I830MemRange *I830MemRangePtr; -typedef struct _I830MemRange { - long Start; - long End; - long Size; - unsigned long Physical; - unsigned long Offset; /* Offset of AGP-allocated portion */ - unsigned long Alignment; - int Key; - I830MemPoolPtr Pool; -} I830MemRange; - -typedef struct _I830MemPool { - I830MemRange Total; - I830MemRange Free; - I830MemRange Fixed; - I830MemRange Allocated; -} I830MemPool; +/** Record of a linear allocation in the aperture. */ +typedef struct _i830_memory i830_memory; +struct _i830_memory { + /** Offset of the allocation in card VM */ + unsigned long offset; + /** End of the allocation in card VM */ + unsigned long end; + /** + * Requested size of the allocation: doesn't count padding. + * + * Any bound memory will cover offset to (offset + size). + */ + unsigned long size; + /** + * Physical (or more properly, bus) address of the allocation. + * Only set if requested during allocation. + */ + unsigned long bus_addr; + /** AGP memory handle */ + int key; + /** + * Whether or not the AGP memory (if any) is currently bound. + */ + Bool bound; + /** + * Offset that the AGP-allocated memory (if any) is to be bound to. + * + * This is either @offset or pI830->stolen_size + */ + unsigned long agp_offset; + + /** Description of the allocation, for logging */ + char *name; + + /** @{ + * Memory allocator linked list pointers + */ + i830_memory *next; + i830_memory *prev; + /** @} */ + +}; typedef struct { int tail_mask; - I830MemRange mem; + i830_memory *mem; unsigned char *virtual_start; int head; int tail; int space; } I830RingBuffer; -typedef struct { - unsigned int Fence[FENCE_NEW_NR * 2]; -} I830RegRec, *I830RegPtr; - typedef struct { int lastInstance; int refCount; @@ -206,8 +224,8 @@ typedef struct _I830CrtcPrivateRec { ExaOffscreenArea *rotate_mem_exa; #endif - I830MemRange cursor_mem; - I830MemRange cursor_mem_argb; + i830_memory *cursor_mem; + i830_memory *cursor_mem_argb; } I830CrtcPrivateRec, *I830CrtcPrivatePtr; #define I830CrtcPrivate(c) ((I830CrtcPrivatePtr) (c)->driver_private) @@ -249,36 +267,26 @@ typedef struct _I830Rec { /* These are set in PreInit and never changed. */ long FbMapSize; - long TotalVideoRam; - I830MemRange StolenMemory; /* pre-allocated memory */ - /* These change according to what has been allocated. */ - long FreeMemory; - I830MemRange MemoryAperture; - I830MemPool StolenPool; - long allocatedMemory; + i830_memory *memory_list; /**< Linked list of video memory allocations */ + long stolen_size; /**< bytes of pre-bound stolen memory */ + int gtt_acquired; /**< whether we currently own the AGP */ - /* Regions allocated either from the above pools, or from agpgart. */ - /* for single and dual head configurations */ - I830MemRange FrontBuffer; - I830MemRange FrontBuffer2; - I830MemRange Scratch; - I830MemRange Scratch2; + i830_memory *front_buffer; + i830_memory *front_buffer_2; + i830_memory *xaa_scratch; + i830_memory *xaa_scratch_2; #ifdef I830_USE_EXA - I830MemRange Offscreen; - I830MemRange EXAStateMem; /* specific exa state for G965 */ + i830_memory *exa_offscreen; + i830_memory *exa_965_state; #endif /* Regions allocated either from the above pools, or from agpgart. */ I830RingBuffer *LpRing; -#if REMAP_RESERVED - I830MemRange Dummy; -#endif - #ifdef I830_XV /* For Xvideo */ - I830MemRange *OverlayMem; - I830MemRange LinearMem; + i830_memory *overlay_regs; + i830_memory *xaa_linear; #endif unsigned long LinearAlloc; XF86ModReqInfo shadowReq; /* to test for later libshadow */ @@ -288,11 +296,13 @@ typedef struct _I830Rec { CreateScreenResourcesProcPtr CreateScreenResources; int *used3D; - I830MemRange ContextMem; + i830_memory *logical_context; #ifdef XF86DRI - I830MemRange BackBuffer; - I830MemRange DepthBuffer; - I830MemRange TexMem; + i830_memory *back_buffer; + i830_memory *depth_buffer; + i830_memory *textures; /**< Compatibility texture memory */ + i830_memory *memory_manager; /**< DRI memory manager aperture */ + int TexGranularity; int drmMinor; Bool have3DWindows; @@ -330,13 +340,21 @@ typedef struct _I830Rec { unsigned int BR[20]; - int GttBound; - unsigned char **ScanlineColorExpandBuffers; int NumScanlineColorExpandBuffers; int nextColorExpandBuf; - I830RegRec ModeReg; + /** + * Values to be programmed into the fence registers. + * + * Pre-965, this is a list of FENCE_NR (8) CARD32 registers that + * contain their start, size, and pitch. On the 965, it is a list of + * FENCE_NEW_NR CARD32s for the start and pitch fields (low 32 bits) of + * the fence registers followed by FENCE_NEW_NR CARD32s for the end fields + * (high 32 bits) of the fence registers. + */ + unsigned int fence[FENCE_NEW_NR * 2]; + unsigned int next_fence; Bool useEXA; Bool noAccel; @@ -407,7 +425,6 @@ typedef struct _I830Rec { /* Broken-out options. */ OptionInfoPtr Options; - /* Stolen memory support */ Bool StolenOnly; Bool swfSaved; @@ -499,7 +516,6 @@ typedef struct _I830Rec { } I830Rec; #define I830PTR(p) ((I830Ptr)((p)->driverPrivate)) -#define I830REGPTR(p) (&(I830PTR(p)->ModeReg)) #define I830_SELECT_FRONT 0 #define I830_SELECT_BACK 1 @@ -528,9 +544,6 @@ extern void i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on); #ifdef XF86DRI extern Bool I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags); -extern Bool I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags); -extern Bool I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags); -extern Bool I830AllocateTextureMemory(ScrnInfoPtr pScrn, const int flags); extern void I830SetupMemoryTiling(ScrnInfoPtr pScrn); extern Bool I830DRIScreenInit(ScreenPtr pScreen); extern Bool I830CheckDRIAvailable(ScrnInfoPtr pScrn); @@ -561,26 +574,17 @@ extern void I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, extern void I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h); -extern void I830ResetAllocations(ScrnInfoPtr pScrn, const int flags); +Bool i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, + unsigned long size); +void i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, + const char *prefix); +void i830_reset_allocations(ScrnInfoPtr pScrn); extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn); -extern long I830GetExcessMemoryAllocations(ScrnInfoPtr pScrn); -extern Bool I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags); -extern Bool I830DoPoolAllocation(ScrnInfoPtr pScrn, I830MemPool *pool); -extern Bool I830FixupOffsets(ScrnInfoPtr pScrn); -extern Bool I830BindAGPMemory(ScrnInfoPtr pScrn); -extern Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn); -extern unsigned long I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result, - I830MemPool *pool, long size, - unsigned long alignment, int flags); -extern void I830FreeVidMem(ScrnInfoPtr pScrn, I830MemRange *range); - -extern void I830PrintAllRegisters(I830RegPtr i830Reg); -extern void I830ReadAllRegisters(I830Ptr pI830, I830RegPtr i830Reg); - -extern void I830ChangeFrontbuffer(ScrnInfoPtr pScrn,int buffer); +Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn, const int flags); +Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn, const int flags); + extern Bool I830IsPrimary(ScrnInfoPtr pScrn); -extern Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem); extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name); @@ -607,6 +611,9 @@ extern void i830MarkSync(ScrnInfoPtr pScrn); extern void i830WaitSync(ScrnInfoPtr pScrn); /* i830_memory.c */ +Bool i830_bind_all_memory(ScrnInfoPtr pScrn); +Bool i830_unbind_all_memory(ScrnInfoPtr pScrn); + Bool I830BindAGPMemory(ScrnInfoPtr pScrn); Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn); #ifdef I830_USE_XAA @@ -656,18 +663,8 @@ extern const int I830PatternROP[16]; extern const int I830CopyROP[16]; /* Flags for memory allocation function */ -#define FROM_ANYWHERE 0x00000000 -#define FROM_POOL_ONLY 0x00000001 -#define FROM_NEW_ONLY 0x00000002 -#define FROM_MASK 0x0000000f - -#define ALLOCATE_AT_TOP 0x00000010 -#define ALLOCATE_AT_BOTTOM 0x00000020 -#define FORCE_GAPS 0x00000040 - -#define NEED_PHYSICAL_ADDR 0x00000100 -#define ALIGN_BOTH_ENDS 0x00000200 -#define FORCE_LOW 0x00000400 +#define NEED_PHYSICAL_ADDR 0x00000001 +#define ALIGN_BOTH_ENDS 0x00000002 #define ALLOC_NO_TILING 0x00001000 #define ALLOC_INITIAL 0x00002000 diff --git a/src/i830_accel.c b/src/i830_accel.c index db3168a8..49a9c134 100644 --- a/src/i830_accel.c +++ b/src/i830_accel.c @@ -117,7 +117,7 @@ I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis) ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) - ring->space += ring->mem.Size; + ring->space += ring->mem->size; iters++; now = GetTimeInMillis(); @@ -195,9 +195,9 @@ I830Sync(ScrnInfoPtr pScrn) ADVANCE_LP_RING(); } - I830WaitLpRing(pScrn, pI830->LpRing->mem.Size - 8, 0); + I830WaitLpRing(pScrn, pI830->LpRing->mem->size - 8, 0); - pI830->LpRing->space = pI830->LpRing->mem.Size - 8; + pI830->LpRing->space = pI830->LpRing->mem->size - 8; pI830->nextColorExpandBuf = 0; } @@ -226,10 +226,10 @@ I830SelectBuffer(ScrnInfoPtr pScrn, int buffer) switch (buffer) { #ifdef XF86DRI case I830_SELECT_BACK: - pI830->bufferOffset = pI830->BackBuffer.Start; + pI830->bufferOffset = pI830->back_buffer->offset; break; case I830_SELECT_DEPTH: - pI830->bufferOffset = pI830->DepthBuffer.Start; + pI830->bufferOffset = pI830->depth_buffer->offset; break; #endif default: @@ -252,7 +252,7 @@ I830RefreshRing(ScrnInfoPtr pScrn) pI830->LpRing->tail = INREG(LP_RING + RING_TAIL); pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); if (pI830->LpRing->space < 0) - pI830->LpRing->space += pI830->LpRing->mem.Size; + pI830->LpRing->space += pI830->LpRing->mem->size; i830MarkSync(pScrn); } diff --git a/src/i830_cursor.c b/src/i830_cursor.c index 70a8d52b..0cfd2292 100644 --- a/src/i830_cursor.c +++ b/src/i830_cursor.c @@ -88,20 +88,20 @@ I830SetPipeCursorBase (xf86CrtcPtr crtc) I830Ptr pI830 = I830PTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int cursor_base = (pipe == 0 ? CURSOR_A_BASE : CURSOR_B_BASE); - I830MemRange *cursor_mem; + i830_memory *cursor_mem; if (pipe >= xf86_config->num_crtc) FatalError("Bad pipe number for cursor base setting\n"); if (pI830->CursorIsARGB) - cursor_mem = &intel_crtc->cursor_mem_argb; + cursor_mem = intel_crtc->cursor_mem_argb; else - cursor_mem = &intel_crtc->cursor_mem; + cursor_mem = intel_crtc->cursor_mem; if (pI830->CursorNeedsPhysical) { - OUTREG(cursor_base, cursor_mem->Physical); + OUTREG(cursor_base, cursor_mem->bus_addr); } else { - OUTREG(cursor_base, cursor_mem->Start); + OUTREG(cursor_base, cursor_mem->offset); } } @@ -281,7 +281,7 @@ I830CRTCLoadCursorImage(xf86CrtcPtr crtc, unsigned char *src) ScrnInfoPtr pScrn = crtc->scrn; I830Ptr pI830 = I830PTR(pScrn); I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - CARD8 *pcurs = (CARD8 *) (pI830->FbBase + intel_crtc->cursor_mem.Start); + CARD8 *pcurs = (CARD8 *) (pI830->FbBase + intel_crtc->cursor_mem->offset); int x, y; DPRINTF(PFX, "I830LoadCursorImage\n"); @@ -372,7 +372,7 @@ static Bool I830UseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs) for (i = 0; i < xf86_config->num_crtc; i++) { I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; - if (!intel_crtc->cursor_mem_argb.Start) + if (!intel_crtc->cursor_mem_argb->offset) return FALSE; } @@ -389,7 +389,8 @@ static void I830CRTCLoadCursorARGB (xf86CrtcPtr crtc, CursorPtr pCurs) { I830Ptr pI830 = I830PTR(crtc->scrn); I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - CARD32 *dst = (CARD32 *) (pI830->FbBase + intel_crtc->cursor_mem_argb.Start); + CARD32 *dst = (CARD32 *) (pI830->FbBase + + intel_crtc->cursor_mem_argb->offset); CARD32 *image = (CARD32 *)pCurs->bits->argb; int x, y, w, h; diff --git a/src/i830_display.c b/src/i830_display.c index 2e847051..a09d96ae 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -345,10 +345,10 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y) if (crtc->rotatedData != NULL) { Start = (char *)crtc->rotatedData - (char *)pI830->FbBase; } else if (I830IsPrimary(pScrn)) { - Start = pI830->FrontBuffer.Start; + Start = pI830->front_buffer->offset; } else { I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - Start = pI8301->FrontBuffer2.Start; + Start = pI8301->front_buffer_2->offset; } if (IS_I965G(pI830)) { @@ -1012,7 +1012,7 @@ i830_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height) "Couldn't allocate shadow memory for rotated CRTC\n"); return NULL; } - rotate_offset = pI830->FrontBuffer.Start + + rotate_offset = pI830->front_buffer->offset + intel_crtc->rotate_mem_xaa->offset * pI830->cpp; } #endif /* I830_USE_XAA */ diff --git a/src/i830_dri.c b/src/i830_dri.c index 70e7e491..9e3f3786 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -145,17 +145,17 @@ I830InitDma(ScrnInfoPtr pScrn) memset(&info, 0, sizeof(drmI830Init)); info.func = I830_INIT_DMA; - info.ring_start = ring->mem.Start + pI830->LinearAddr; - info.ring_end = ring->mem.End + pI830->LinearAddr; - info.ring_size = ring->mem.Size; + info.ring_start = ring->mem->offset + pI830->LinearAddr; + info.ring_end = ring->mem->end + pI830->LinearAddr; + info.ring_size = ring->mem->size; info.mmio_offset = (unsigned int)pI830DRI->regs; info.sarea_priv_offset = sizeof(XF86DRISAREARec); - info.front_offset = pI830->FrontBuffer.Start; - info.back_offset = pI830->BackBuffer.Start; - info.depth_offset = pI830->DepthBuffer.Start; + info.front_offset = pI830->front_buffer->offset; + info.back_offset = pI830->back_buffer->offset; + info.depth_offset = pI830->depth_buffer->offset; info.w = pScrn->virtualX; info.h = pScrn->virtualY; info.pitch = pI830->displayWidth; @@ -509,7 +509,7 @@ I830DRIScreenInit(ScreenPtr pScreen) pDRIInfo->ddxDriverPatchVersion = I830_PATCHLEVEL; #if 1 /* Remove this soon - see bug 5714 */ pDRIInfo->frameBufferPhysicalAddress = (char *) pI830->LinearAddr + - pI830->FrontBuffer.Start; + pI830->front_buffer->offset; pDRIInfo->frameBufferSize = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * pI830->cpp); #else @@ -829,8 +829,8 @@ I830DRIDoMappings(ScreenPtr pScreen) (int)pI830DRI->regs); if (drmAddMap(pI830->drmSubFD, - (drm_handle_t)pI830->LpRing->mem.Start + pI830->LinearAddr, - pI830->LpRing->mem.Size, DRM_AGP, 0, + (drm_handle_t)pI830->LpRing->mem->offset + pI830->LinearAddr, + pI830->LpRing->mem->size, DRM_AGP, 0, (drmAddress) &pI830->ring_map) < 0) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); @@ -1325,10 +1325,10 @@ I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf) OUT_RING(br13); OUT_RING((pbox->y1 << 16) | pbox->x1); OUT_RING((pbox->y2 << 16) | pbox->x2); - OUT_RING(pI830->BackBuffer.Start); + OUT_RING(pI830->back_buffer->offset); OUT_RING((pbox->y1 << 16) | pbox->x1); OUT_RING(br13 & 0xffff); - OUT_RING(pI830->FrontBuffer.Start); + OUT_RING(pI830->front_buffer->offset); ADVANCE_LP_RING(); } } @@ -1360,10 +1360,10 @@ I830EnablePageFlip(ScreenPtr pScreen) OUT_RING(br13); OUT_RING(0); OUT_RING((pScrn->virtualY << 16) | pScrn->virtualX); - OUT_RING(pI830->BackBuffer.Start); + OUT_RING(pI830->back_buffer->offset); OUT_RING(0); OUT_RING(br13 & 0xffff); - OUT_RING(pI830->FrontBuffer.Start); + OUT_RING(pI830->front_buffer->offset); ADVANCE_LP_RING(); pSAREAPriv->pf_active = 1; @@ -1448,8 +1448,8 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) sarea->depth_tiled = pI830->depth_tiled; sarea->rotated_tiled = FALSE; - sarea->front_offset = pI830->FrontBuffer.Start; - /* Don't use FrontBuffer.Size here as it includes the pixmap cache area + sarea->front_offset = pI830->front_buffer->offset; + /* Don't use front_buffer->size here as it includes the pixmap cache area * Instead, calculate the entire framebuffer. */ sarea->front_size = pI830->displayWidth * pScrn->virtualY * pI830->cpp; @@ -1460,12 +1460,12 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) sarea->width = pScreen->width; sarea->height = pScreen->height; - sarea->back_offset = pI830->BackBuffer.Start; - sarea->back_size = pI830->BackBuffer.Size; - sarea->depth_offset = pI830->DepthBuffer.Start; - sarea->depth_size = pI830->DepthBuffer.Size; - sarea->tex_offset = pI830->TexMem.Start; - sarea->tex_size = pI830->TexMem.Size; + sarea->back_offset = pI830->back_buffer->offset; + sarea->back_size = pI830->back_buffer->size; + sarea->depth_offset = pI830->depth_buffer->offset; + sarea->depth_size = pI830->depth_buffer->size; + sarea->tex_offset = pI830->textures->offset; + sarea->tex_size = pI830->textures->size; sarea->log_tex_granularity = pI830->TexGranularity; sarea->pitch = pScrn->displayWidth; sarea->virtualX = pScrn->virtualX; diff --git a/src/i830_driver.c b/src/i830_driver.c index e46c0572..50fe2a6d 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -534,7 +534,7 @@ I830MapMem(ScrnInfoPtr pScrn) return FALSE; if (I830IsPrimary(pScrn)) - pI830->LpRing->virtual_start = pI830->FbBase + pI830->LpRing->mem.Start; + pI830->LpRing->virtual_start = pI830->FbBase + pI830->LpRing->mem->offset; return TRUE; } @@ -755,9 +755,6 @@ PreInitCleanup(ScrnInfoPtr pScrn) if (pI830->LpRing) xfree(pI830->LpRing); pI830->LpRing = NULL; - if (pI830->OverlayMem) - xfree(pI830->OverlayMem); - pI830->OverlayMem = NULL; if (pI830->overlayOn) xfree(pI830->overlayOn); pI830->overlayOn = NULL; @@ -836,6 +833,13 @@ I830ReduceMMSize(ScrnInfoPtr pScrn, unsigned long newSize, } #endif +/** + * This is called per zaphod head (so usually just once) to do initialization + * before the Screen is created. + * + * This code generally covers probing, module loading, option handling, + * initial memory layout measurement, card mapping, and RandR setup. + */ static Bool I830PreInit(ScrnInfoPtr pScrn, int flags) { @@ -846,12 +850,12 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) rgb defaultWeight = { 0, 0, 0 }; EntityInfoPtr pEnt; I830EntPtr pI830Ent = NULL; - int mem; + int sys_mem; int flags24; int i; char *s; pointer pVBEModule = NULL; - Bool enable; + Bool enable, allocation_done; const char *chipname; int num_pipe; int max_width, max_height; @@ -1187,41 +1191,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n", num_pipe, num_pipe > 1 ? "s" : ""); - /* - * Get the pre-allocated (stolen) memory size. - */ - pI830->StolenMemory.Size = I830DetectMemory(pScrn); - pI830->StolenMemory.Start = 0; - pI830->StolenMemory.End = pI830->StolenMemory.Size; - - /* Find the maximum amount of agpgart memory available. */ - if (I830IsPrimary(pScrn)) { - mem = I830CheckAvailableMemory(pScrn); - pI830->StolenOnly = FALSE; - } else { - /* videoRam isn't used on the second head, but faked */ - mem = pI830->entityPrivate->pScrn_1->videoRam; - pI830->StolenOnly = TRUE; - } - - if (mem <= 0) { - if (pI830->StolenMemory.Size <= 0) { - /* Shouldn't happen. */ - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "/dev/agpgart is either not available, or no memory " - "is available\nfor allocation, " - "and no pre-allocated memory is available.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "/dev/agpgart is either not available, or no memory " - "is available\nfor allocation. " - "Using pre-allocated memory only.\n"); - mem = 0; - pI830->StolenOnly = TRUE; - } - if (xf86ReturnOptValBool(pI830->Options, OPTION_NOACCEL, FALSE)) { pI830->noAccel = TRUE; } @@ -1358,8 +1327,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } RestoreHWState(pScrn); - pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; - /* XXX This should go away, replaced by xf86Crtc.c support for it */ pI830->rotation = RR_Rotate_0; @@ -1384,12 +1351,21 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } else pI830->checkDevices = FALSE; + pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; + + pI830->stolen_size = I830DetectMemory(pScrn); + /* * The "VideoRam" config file parameter specifies the maximum amount of * memory that will be used/allocated. When not present, we allow the * driver to allocate as much memory as it wishes to satisfy its - * allocations, but if agpgart support isn't available (StolenOnly == TRUE), - * it gets limited to the amount of pre-allocated ("stolen") memory. + * allocations, but if agpgart support isn't available, it gets limited + * to the amount of pre-allocated ("stolen") memory. + * + * Note that in using this value for allocator initialization, we're + * limiting aperture allocation to the VideoRam option, rather than limiting + * actual memory allocation, so alignment and things will cause less than + * VideoRam to be actually used. */ if (!pI830->pEnt->device->videoRam) { from = X_DEFAULT; @@ -1399,55 +1375,59 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pScrn->videoRam = pI830->pEnt->device->videoRam; } - /* Make sure it's on a page boundary */ - if (pScrn->videoRam & 3) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VideoRam reduced to %d KB " - "(page aligned - was %d KB)\n", - pScrn->videoRam & ~3, pScrn->videoRam); - pScrn->videoRam &= ~3; - } - - DPRINTF(PFX, - "Available memory: %dk\n" - "Requested memory: %dk\n", mem, pScrn->videoRam); - - - if (mem + (pI830->StolenMemory.Size / 1024) < pScrn->videoRam) { - pScrn->videoRam = mem + (pI830->StolenMemory.Size / 1024); - from = X_PROBED; - if (mem + (pI830->StolenMemory.Size / 1024) < - pI830->pEnt->device->videoRam) { + sys_mem = I830CheckAvailableMemory(pScrn); + if (sys_mem == -1) { + if (pScrn->videoRam > pI830->stolen_size / KB(1)) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRAM reduced to %d kByte " - "(limited to available sysmem)\n", pScrn->videoRam); + "/dev/agpgart is either not available, or no memory " + "is available\nfor allocation. " + "Using pre-allocated memory only.\n"); + pScrn->videoRam = pI830->stolen_size / KB(1); + } + pI830->StolenOnly = TRUE; + } else { + if (sys_mem + (pI830->stolen_size / 1024) < pScrn->videoRam) { + pScrn->videoRam = sys_mem + (pI830->stolen_size / 1024); + from = X_PROBED; + if (sys_mem + (pI830->stolen_size / 1024) < + pI830->pEnt->device->videoRam) + { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VideoRAM reduced to %d kByte " + "(limited to available sysmem)\n", pScrn->videoRam); + } } } if (pScrn->videoRam > pI830->FbMapSize / 1024) { pScrn->videoRam = pI830->FbMapSize / 1024; - if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) + if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRam reduced to %d kByte (limited to aperture size)\n", + "VideoRam reduced to %d kByte (limited to aperture " + "size)\n", pScrn->videoRam); + } } - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Pre-allocated VideoRam: %ld kByte\n", - pI830->StolenMemory.Size / 1024); - xf86DrvMsg(pScrn->scrnIndex, from, "Potential VideoRam: %d kByte\n", - pScrn->videoRam); - - pI830->TotalVideoRam = KB(pScrn->videoRam); + /* Make sure it's on a page boundary */ + if (pScrn->videoRam & 3) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VideoRam reduced to %d KB " + "(page aligned - was %d KB)\n", + pScrn->videoRam & ~3, pScrn->videoRam); + pScrn->videoRam &= ~3; + } - /* - * If the requested videoRam amount is less than the stolen memory size, - * reduce the stolen memory size accordingly. - */ - if (pI830->StolenMemory.Size > pI830->TotalVideoRam) { - pI830->StolenMemory.Size = pI830->TotalVideoRam; - pI830->StolenMemory.End = pI830->TotalVideoRam; + if (!i830_allocator_init(pScrn, 0, pScrn->videoRam * KB(1))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't initialize video memory allocator\n"); + PreInitCleanup(pScrn); + return FALSE; } + xf86DrvMsg(pScrn->scrnIndex, + pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT, + "VideoRam: %d KB\n", pScrn->videoRam); + if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES, &(pI830->CacheLines))) { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n", @@ -1502,12 +1482,10 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) /* Alloc our pointers for the primary head */ if (I830IsPrimary(pScrn)) { - pI830->LpRing = xalloc(sizeof(I830RingBuffer)); - pI830->OverlayMem = xalloc(sizeof(I830MemRange)); + pI830->LpRing = xcalloc(1, sizeof(I830RingBuffer)); pI830->overlayOn = xalloc(sizeof(Bool)); pI830->used3D = xalloc(sizeof(int)); - if (!pI830->LpRing || - !pI830->OverlayMem || !pI830->overlayOn || !pI830->used3D) { + if (!pI830->LpRing || !pI830->overlayOn || !pI830->used3D) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not allocate primary data structures.\n"); PreInitCleanup(pScrn); @@ -1527,9 +1505,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) if (IS_I965G(pI830)) pI830->CursorNeedsPhysical = FALSE; - /* Force ring buffer to be in low memory for all chipsets */ - pI830->NeedRingBufferLow = TRUE; - /* * XXX If we knew the pre-initialised GTT format for certain, we could * probably figure out the physical address even in the StolenOnly case. @@ -1548,21 +1523,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->SWCursor = TRUE; } - /* - * Reduce the maximum videoram available for video modes by the ring buffer, - * minimum scratch space and HW cursor amounts. - */ - if (!pI830->SWCursor) { - pScrn->videoRam -= (HWCURSOR_SIZE / 1024); - pScrn->videoRam -= (HWCURSOR_SIZE_ARGB / 1024); - } - if (!pI830->XvDisabled) - pScrn->videoRam -= (OVERLAY_SIZE / 1024); - if (!pI830->noAccel) { - pScrn->videoRam -= (PRIMARY_RINGBUFFER_SIZE / 1024); - pScrn->videoRam -= (MIN_SCRATCH_BUFFER_SIZE / 1024); - } - if (!xf86RandR12PreInit (pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n"); @@ -1579,23 +1539,19 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->disableTiling = FALSE; +#if defined(XF86DRI) /* * If DRI is potentially usable, check if there is enough memory available * for it, and if there's also enough to allow tiling to be enabled. */ -#if defined(XF86DRI) if (!I830CheckDRIAvailable(pScrn)) { pI830->directRenderingDisabled = TRUE; pI830->mmSize = 0; - } else if (pScrn->videoRam > pI830->FbMapSize / 1024 - pI830->mmSize) { - I830ReduceMMSize(pScrn, pI830->FbMapSize - KB(pScrn->videoRam), - "to make room for video memory"); } if (I830IsPrimary(pScrn) && !pI830->directRenderingDisabled) { int savedDisplayWidth = pScrn->displayWidth; - int memNeeded = 0; Bool tiled = FALSE; #ifdef I830_XV @@ -1612,12 +1568,14 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) ~(tile_pixels - 1); tiled = TRUE; } else { - /* Good pitches to allow tiling. Don't care about pitches < 1024. */ + /* Good pitches to allow tiling. Don't care about pitches < 1024 + * pixels. + */ static const int pitches[] = { - KB(1), - KB(2), - KB(4), - KB(8), + 1024, + 2048, + 4096, + 8192, 0 }; @@ -1630,120 +1588,72 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } } + allocation_done = FALSE; /* * If the displayWidth is a tilable pitch, test if there's enough * memory available to enable tiling. */ savedMMSize = pI830->mmSize; if (tiled) { - retry_dryrun: - I830ResetAllocations(pScrn, 0); - if (I830Allocate2DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_INITIAL) && - I830Allocate3DMemory(pScrn, ALLOCATE_DRY_RUN)) { - memNeeded = I830GetExcessMemoryAllocations(pScrn); - if (memNeeded > 0 || pI830->MemoryAperture.Size < 0) { - if (memNeeded > 0) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%d kBytes additional video memory is " - "required to\n\tenable tiling mode for DRI.\n", - (memNeeded + 1023) / 1024); - } - if (pI830->MemoryAperture.Size < 0) { - if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) { - I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE, - "to make room in AGP aperture for tiling."); - goto retry_dryrun; - } - /* XXX */ - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Allocation with DRI tiling enabled would " - "exceed the\n" - "\tmemory aperture size (%ld kB) by %ld kB.\n" - "\tReduce VideoRam amount to avoid this!\n", - pI830->FbMapSize / 1024, - -pI830->MemoryAperture.Size / 1024); - } - pScrn->displayWidth = savedDisplayWidth; - pI830->allowPageFlip = FALSE; - } else if (pScrn->displayWidth != savedDisplayWidth) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Increasing the scanline pitch to allow tiling mode " - "(%d -> %d).\n", - savedDisplayWidth, pScrn->displayWidth); +retry_dryrun: + i830_reset_allocations(pScrn); + if (!i830_allocate_2d_memory(pScrn, + ALLOCATE_DRY_RUN | ALLOC_INITIAL) || + !i830_allocate_3d_memory(pScrn, ALLOCATE_DRY_RUN)) + { + /* Failure to set up allocations, so try reducing the DRI memory + * manager's size if we haven't yet. + */ + if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) { + I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE, + "to make room for tiling."); + goto retry_dryrun; } - } else { - memNeeded = 0; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Unexpected dry run allocation failure (1).\n"); + /* Otherwise, disable tiling. */ + pScrn->displayWidth = savedDisplayWidth; + pI830->allowPageFlip = FALSE; + } else if (pScrn->displayWidth != savedDisplayWidth) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Increasing the scanline pitch to allow tiling mode " + "(%d -> %d).\n", + savedDisplayWidth, pScrn->displayWidth); + allocation_done = TRUE; } } - if (memNeeded > 0 || pI830->MemoryAperture.Size < 0) { + if (!allocation_done) { /* * Tiling can't be enabled. Check if there's enough memory for DRI * without tiling. */ pI830->mmSize = savedMMSize; pI830->disableTiling = TRUE; - retry_dryrun2: - I830ResetAllocations(pScrn, 0); - if (I830Allocate2DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_INITIAL) && - I830Allocate3DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_NO_TILING)) { - memNeeded = I830GetExcessMemoryAllocations(pScrn); - if (memNeeded > 0 || pI830->MemoryAperture.Size < 0) { - if (memNeeded > 0) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%d kBytes additional video memory is required " - "to enable DRI.\n", - (memNeeded + 1023) / 1024); - } - if (pI830->MemoryAperture.Size < 0) { - if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) { - I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE, - "to save AGP aperture space for video memory."); - goto retry_dryrun2; - } - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Allocation with DRI enabled would " - "exceed the\n" - "\tmemory aperture size (%ld kB) by %ld kB.\n" - "\tReduce VideoRam amount to avoid this!\n", - pI830->FbMapSize / 1024, - -pI830->MemoryAperture.Size / 1024); - } - pI830->mmSize = 0; - pI830->directRenderingDisabled = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DRI.\n"); +retry_dryrun2: + i830_reset_allocations(pScrn); + if (!i830_allocate_2d_memory(pScrn, + ALLOCATE_DRY_RUN | ALLOC_INITIAL) || + !i830_allocate_3d_memory(pScrn, ALLOCATE_DRY_RUN)) + { + /* Failure to set up allocations, so try reducing the DRI memory + * manager's size if we haven't yet. + */ + if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) { + I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE, + "to save AGP aperture space for video " + "memory."); + goto retry_dryrun2; } - } else { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Unexpected dry run allocation failure (2).\n"); + "Not enough video memory. Disabling DRI."); + pI830->mmSize = 0; + pI830->directRenderingDisabled = TRUE; + } else { + allocation_done = TRUE; } } } else #endif pI830->disableTiling = TRUE; /* no DRI - so disableTiling */ - if (pI830->pEnt->device->videoRam == 0) { - int default_videoram; - - /* Now that we've sized the allocations, reduce our default VideoRam - * allocation from the aperture size to just what we need to cover our - * allocations. Only, put in some slop for alignment and such. - */ - default_videoram = pI830->StolenPool.Total.Size + pI830->allocatedMemory; - default_videoram += KB(512); /* slop */ - /* align to 1MB increments */ - default_videoram = (default_videoram + MB(1) - 1) / MB(1) * MB(1); - - if (default_videoram < KB(pScrn->videoRam)) { - pScrn->videoRam = default_videoram / KB(1); - pI830->TotalVideoRam = KB(pScrn->videoRam); - } - } - xf86DrvMsg(pScrn->scrnIndex, - pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT, - "VideoRam: %d KB\n", pScrn->videoRam); - if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support DRI with frame buffer width > 2048.\n"); @@ -1934,18 +1844,18 @@ SetFenceRegs(ScrnInfoPtr pScrn) if (IS_I965G(pI830)) { for (i = 0; i < FENCE_NEW_NR; i++) { - OUTREG(FENCE_NEW + i * 8, pI830->ModeReg.Fence[i]); - OUTREG(FENCE_NEW + 4 + i * 8, pI830->ModeReg.Fence[i+FENCE_NEW_NR]); + OUTREG(FENCE_NEW + i * 8, pI830->fence[i]); + OUTREG(FENCE_NEW + 4 + i * 8, pI830->fence[i+FENCE_NEW_NR]); if (I810_DEBUG & DEBUG_VERBOSE_VGA) { - ErrorF("Fence Start Register : %x\n", pI830->ModeReg.Fence[i]); - ErrorF("Fence End Register : %x\n", pI830->ModeReg.Fence[i+FENCE_NEW_NR]); + ErrorF("Fence Start Register : %x\n", pI830->fence[i]); + ErrorF("Fence End Register : %x\n", pI830->fence[i+FENCE_NEW_NR]); } } } else { for (i = 0; i < FENCE_NR; i++) { - OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]); + OUTREG(FENCE + i * 4, pI830->fence[i]); if (I810_DEBUG & DEBUG_VERBOSE_VGA) - ErrorF("Fence Register : %x\n", pI830->ModeReg.Fence[i]); + ErrorF("Fence Register : %x\n", pI830->fence[i]); } } } @@ -1970,25 +1880,22 @@ SetRingRegs(ScrnInfoPtr pScrn) OUTREG(LP_RING + RING_TAIL, 0); OUTREG(LP_RING + RING_HEAD, 0); - if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) != - pI830->LpRing->mem.Start) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "I830SetRingRegs: Ring buffer start (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK); - } + assert((pI830->LpRing->mem->offset & I830_RING_START_MASK) == + pI830->LpRing->mem->offset); + /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK; + itemp = pI830->LpRing->mem->offset; OUTREG(LP_RING + RING_START, itemp); - if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) != - pI830->LpRing->mem.Size - 4096) { + if (((pI830->LpRing->mem->size - 4096) & I830_RING_NR_PAGES) != + pI830->LpRing->mem->size - 4096) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Size - 4096, + "mask (%x)\n", pI830->LpRing->mem->size - 4096, I830_RING_NR_PAGES); } /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES; + itemp = (pI830->LpRing->mem->size - 4096) & I830_RING_NR_PAGES; itemp |= (RING_NO_REPORT | RING_VALID); OUTREG(LP_RING + RING_LEN, itemp); I830RefreshRing(pScrn); @@ -2246,13 +2153,12 @@ static void InitRegisterRec(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - I830RegPtr i830Reg = &pI830->ModeReg; int i; if (!I830IsPrimary(pScrn)) return; for (i = 0; i < 8; i++) - i830Reg->Fence[i] = 0; + pI830->fence[i] = 0; } static void @@ -2361,14 +2267,12 @@ IntelEmitInvarientState(ScrnInfoPtr pScrn) } #endif - ctx_addr = pI830->ContextMem.Start; - /* Align to a 2k boundry */ - ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048; - + ctx_addr = pI830->logical_context->offset; + assert((pI830->logical_context->offset & 2047) == 0); { BEGIN_LP_RING(2); OUT_RING(MI_SET_CONTEXT); - OUT_RING(ctx_addr | + OUT_RING(pI830->logical_context->offset | CTXT_NO_RESTORE | CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE); ADVANCE_LP_RING(); @@ -2525,14 +2429,11 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (I830IsPrimary(pScrn)) { if (!pI830->LpRing) pI830->LpRing = xalloc(sizeof(I830RingBuffer)); - if (!pI830->OverlayMem) - pI830->OverlayMem = xalloc(sizeof(I830MemRange)); if (!pI830->overlayOn) pI830->overlayOn = xalloc(sizeof(Bool)); if (!pI830->used3D) pI830->used3D = xalloc(sizeof(int)); - if (!pI830->LpRing || - !pI830->OverlayMem || !pI830->overlayOn || !pI830->used3D) { + if (!pI830->LpRing || !pI830->overlayOn || !pI830->used3D) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not allocate primary data structures.\n"); return FALSE; @@ -2546,7 +2447,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!I830IsPrimary(pScrn)) { pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); pI830->LpRing = pI8301->LpRing; - pI830->OverlayMem = pI8301->OverlayMem; + pI830->overlay_regs = pI8301->overlay_regs; pI830->overlayOn = pI8301->overlayOn; pI830->used3D = pI8301->used3D; } @@ -2579,14 +2480,14 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #endif if (I830IsPrimary(pScrn)) { - I830ResetAllocations(pScrn, 0); + i830_reset_allocations(pScrn); - if (!I830Allocate2DMemory(pScrn, ALLOC_INITIAL)) + if (!i830_allocate_2d_memory(pScrn, ALLOC_INITIAL)) return FALSE; } if (!pI830->noAccel) { - if (pI830->LpRing->mem.Size == 0) { + if (pI830->LpRing->mem->size == 0) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling acceleration because the ring buffer " "allocation failed.\n"); @@ -2601,7 +2502,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) "needs 2D acceleration.\n"); pI830->XvEnabled = FALSE; } - if (pI830->OverlayMem->Physical == 0) { + if (pI830->overlay_regs == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling Xv because the overlay register buffer " "allocation failed.\n"); @@ -2639,8 +2540,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (pI830->directRenderingEnabled) { pI830->directRenderingEnabled = - I830Allocate3DMemory(pScrn, - pI830->disableTiling ? ALLOC_NO_TILING : 0); + i830_allocate_3d_memory(pScrn, + pI830->disableTiling ? ALLOC_NO_TILING : 0); if (!pI830->directRenderingEnabled) I830DRICloseScreen(pScreen); } @@ -2649,27 +2550,18 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->directRenderingEnabled = FALSE; #endif - /* + /* XXX: * After the 3D allocations have been done, see if there's any free space * that can be added to the framebuffer allocation. */ if (I830IsPrimary(pScrn)) { - I830Allocate2DMemory(pScrn, 0); - - DPRINTF(PFX, "assert(if(!I830DoPoolAllocation(pScrn, pI830->StolenPool)))\n"); - if (!I830DoPoolAllocation(pScrn, &(pI830->StolenPool))) - return FALSE; - - DPRINTF(PFX, "assert( if(!I830FixupOffsets(pScrn)) )\n"); - if (!I830FixupOffsets(pScrn)) - return FALSE; + i830_allocate_2d_memory(pScrn, 0); } + i830_describe_allocations(pScrn, 1, ""); #ifdef XF86DRI - if (pI830->directRenderingEnabled) { - I830SetupMemoryTiling(pScrn); + if (pI830->directRenderingEnabled) pI830->directRenderingEnabled = I830DRIDoMappings(pScreen); - } #endif DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n"); @@ -2679,9 +2571,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn->memPhysBase = (unsigned long)pI830->FbBase; if (I830IsPrimary(pScrn)) { - pScrn->fbOffset = pI830->FrontBuffer.Start; + pScrn->fbOffset = pI830->front_buffer->offset; } else { - pScrn->fbOffset = pI8301->FrontBuffer2.Start; + pScrn->fbOffset = pI8301->front_buffer_2->offset; } pI830->xoffset = (pScrn->fbOffset / pI830->cpp) % pScrn->displayWidth; @@ -2704,13 +2596,13 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (pI830->LinearAlloc && xf86InitFBManagerLinear(pScreen, - pI830->LinearMem.Offset / pI830->cpp, - pI830->LinearMem.Size / pI830->cpp)) + pI830->xaa_linear->offset / pI830->cpp, + pI830->xaa_linear->size / pI830->cpp)) { xf86DrvMsg(scrnIndex, X_INFO, "Using %ld bytes of offscreen memory for linear " - "(offset=0x%lx)\n", pI830->LinearMem.Size, - pI830->LinearMem.Offset); + "(offset=0x%lx)\n", pI830->xaa_linear->size, + pI830->xaa_linear->offset); } } else { if (!I830InitFBManager(pScreen, &(pI8301->FbMemBox2))) { @@ -2877,27 +2769,24 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->suspended = FALSE; #ifdef XF86DRI_MM - if (pI830->directRenderingEnabled && (pI830->mmModeFlags & I830_KERNEL_MM)) { - unsigned long aperEnd = ROUND_DOWN_TO(pI830->FbMapSize, GTT_PAGE_SIZE) - / GTT_PAGE_SIZE; - unsigned long aperStart = ROUND_TO(pI830->FbMapSize - KB(pI830->mmSize), GTT_PAGE_SIZE) - / GTT_PAGE_SIZE; - - if (aperEnd < aperStart || aperEnd - aperStart < I830_MM_MINPAGES) { + if (pI830->directRenderingEnabled && (pI830->mmModeFlags & I830_KERNEL_MM)) + { + if (pI830->memory_manager == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Too little AGP aperture space for DRM memory manager.\n" - "\tPlease increase AGP aperture size from BIOS configuration screen\n" - "\tor decrease the amount of video RAM using option \"VideoRam\".\n" + "\tPlease increase AGP aperture size from BIOS configuration screen.\n" "\tDisabling DRI.\n"); pI830->directRenderingOpen = FALSE; I830DRICloseScreen(pScreen); pI830->directRenderingEnabled = FALSE; } else { #ifndef XSERVER_LIBDRM_MM - if (I830DrmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart, + if (I830DrmMMInit(pI830->drmSubFD, pI830->memory_manager->offset, + pI830->memory_manager->size, DRM_BO_MEM_TT)) { #else - if (drmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart, + if (drmMMInit(pI830->drmSubFD, pI830->memory_manager->offset, + pI830->memory_manager->size, DRM_BO_MEM_TT)) { #endif xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -2906,12 +2795,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->directRenderingOpen = FALSE; I830DRICloseScreen(pScreen); pI830->directRenderingEnabled = FALSE; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Initialized DRM memory manager, %ld AGP pages\n" - "\tat AGP offset 0x%lx\n", - aperEnd - aperStart, - aperStart); } } } @@ -2968,7 +2851,7 @@ I830LeaveVT(int scrnIndex, int flags) if (!I830IsPrimary(pScrn)) { I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - if (!pI8301->GttBound) { + if (!pI8301->gtt_acquired) { return; } } @@ -3002,7 +2885,7 @@ I830LeaveVT(int scrnIndex, int flags) i830DumpRegs (pScrn); if (I830IsPrimary(pScrn)) - I830UnbindAGPMemory(pScrn); + i830_unbind_all_memory(pScrn); if (pI830->AccelInfoRec) pI830->AccelInfoRec->NeedToSync = FALSE; } @@ -3038,7 +2921,7 @@ I830EnterVT(int scrnIndex, int flags) #endif if (I830IsPrimary(pScrn)) - if (!I830BindAGPMemory(pScrn)) + if (!i830_bind_all_memory(pScrn)) return FALSE; if (i830_check_error_state(pScrn)) { @@ -3223,8 +3106,6 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen) xfree(pI830->LpRing); pI830->LpRing = NULL; - xfree(pI830->OverlayMem); - pI830->OverlayMem = NULL; xfree(pI830->overlayOn); pI830->overlayOn = NULL; xfree(pI830->used3D); diff --git a/src/i830_exa.c b/src/i830_exa.c index 42552d44..37fd2842 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -318,8 +318,9 @@ I830EXAInit(ScreenPtr pScreen) pI830->EXADriverPtr->exa_major = 2; pI830->EXADriverPtr->exa_minor = 1; pI830->EXADriverPtr->memoryBase = pI830->FbBase; - pI830->EXADriverPtr->offScreenBase = pI830->Offscreen.Start; - pI830->EXADriverPtr->memorySize = pI830->Offscreen.End; + pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset; + pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset + + pI830->exa_offscreen->size; DPRINTF(PFX, "EXA Mem: memoryBase 0x%x, end 0x%x, offscreen base 0x%x, memorySize 0x%x\n", pI830->EXADriverPtr->memoryBase, diff --git a/src/i830_memory.c b/src/i830_memory.c index 1b2af120..93429fba 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -50,6 +50,51 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Alan Hourihane */ +/** + * @file i830_memory.c + * + * This is the video memory allocator. Our memory allocation is different from + * other graphics chips, where you have a fixed amount of graphics memory + * available that you want to put to the best use. Instead, we have almost no + * memory pre-allocated, and we have to choose an appropriate amount of sytem + * memory to use. + * + * The allocations we might do: + * + * - Ring buffer + * - HW cursor 1 + * - HW cursor 2 + * - HW ARGB cursor 1 + * - HW ARGB cursor 2 + * - Overlay registers + * - XAA linear allocator (optional) + * - EXA 965 state buffer + * - XAA scratch (screen 1) + * - XAA scratch (screen 2, only in zaphod mode) + * - Front buffer (screen 1, more is better for XAA) + * - Front buffer (screen 2, only in zaphod mode, more is better for XAA) + * - Back/depth buffer (3D only) + * - Compatibility texture pool (optional, more is always better) + * - New texture pool (optional, more is always better. aperture allocation + * only) + * - EXA offscreen pool (more is always better) + * + * We also want to be able to resize the front/back/depth buffers, and then + * resize the EXA and texture memory pools appropriately. + * + * The user may request a specific amount of memory to be used + * (pI830->pEnt->videoRam != 0), in which case allocations have to fit within + * that much aperture. If not, the individual allocations will be + * automatically sized, and will be fit within the maximum aperture size. + * Only the actual memory used (not alignment padding) will get actual AGP + * memory allocated. + * + * Given that the allocations listed are generally a page or more than a page, + * our allocator will only return page-aligned offsets, simplifying the memory + * binding process. For smaller allocations, the acceleration architecture's + * linear allocator is preferred. + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -62,383 +107,541 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "i830.h" #include "i810_reg.h" -static int nextTile = 0; -static unsigned int tileGeneration = -1; +#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) + +enum tile_format { + TILING_NONE, + TILING_XMAJOR, + TILING_YMAJOR +}; +static void i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset, + unsigned int pitch, unsigned int size, + enum tile_format tile_format); + +/** + * Returns the fence size for a tiled area of the given size. + */ static unsigned long -GetBestTileAlignment(unsigned long size) +i830_get_fence_size(ScrnInfoPtr pScrn, unsigned long size) { + I830Ptr pI830 = I830PTR(pScrn); unsigned long i; + unsigned long start; - for (i = KB(512); i < size; i <<= 1) - ; + if (IS_I965G(pI830)) { + /* The 965 can have fences at any page boundary. */ + return ALIGN(size, GTT_PAGE_SIZE); + } else { + /* Align the size to a power of two greater than the smallest fence + * size. + */ + if (IS_I9XX(pI830)) + start = MB(1); + else + start = KB(512); - if (i > MB(64)) - i = MB(64); + for (i = start; i < size; i <<= 1) + ; - return i; + return i; + } } -/* - * Allocate memory from the given pool. Grow the pool if needed and if - * possible. - */ -static unsigned long -AllocFromPool(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool, - long size, unsigned long alignment, int flags) +static Bool +i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) { I830Ptr pI830 = I830PTR(pScrn); - long needed, start, end; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - if (!result || !pool || !size) - return 0; - - /* Calculate how much space is needed. */ - if (alignment <= GTT_PAGE_SIZE) - needed = size; - else { - if (flags & ALLOCATE_AT_BOTTOM) { - start = ROUND_TO(pool->Free.Start, alignment); - if (flags & ALIGN_BOTH_ENDS) - end = ROUND_TO(start + size, alignment); - else - end = start + size; - needed = end - pool->Free.Start; - } else { /* allocate at top */ - if (flags & ALIGN_BOTH_ENDS) - end = ROUND_DOWN_TO(pool->Free.End, alignment); - else - end = pool->Free.End; - - start = ROUND_DOWN_TO(end - size, alignment); - needed = end - start; - } + if (mem == NULL || mem->key == -1 || mem->bound || !pI830->gtt_acquired) + return TRUE; + + if (xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset)) { + mem->bound = TRUE; + return TRUE; + } else { + return FALSE; } - if (needed > pool->Free.Size) { - long extra; - /* See if the pool can be grown. */ - if (pI830->StolenOnly && !dryrun) - return 0; - extra = needed - pool->Free.Size; - extra = ROUND_TO_PAGE(extra); - if (extra > pI830->FreeMemory) { - if (dryrun) - pI830->FreeMemory = extra; - else - return 0; - } - if (!dryrun && ((long)extra > pI830->MemoryAperture.Size)) - return 0; + return TRUE; +} - pool->Free.Size += extra; - pool->Free.End += extra; - pool->Total.Size += extra; - pool->Total.End += extra; - pI830->FreeMemory -= extra; - pI830->MemoryAperture.Start += extra; - pI830->MemoryAperture.Size -= extra; - } - if (flags & ALLOCATE_AT_BOTTOM) { - result->Start = ROUND_TO(pool->Free.Start, alignment); - pool->Free.Start += needed; - result->End = pool->Free.Start; +static Bool +i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem) +{ + if (mem == NULL || mem->key == -1 || !mem->bound) + return TRUE; + + if (xf86UnbindGARTMemory(pScrn->scrnIndex, mem->key)) { + mem->bound = FALSE; + return TRUE; } else { - result->Start = ROUND_DOWN_TO(pool->Free.End - size, alignment); - pool->Free.End -= needed; - result->End = result->Start + needed; + return FALSE; } - pool->Free.Size = pool->Free.End - pool->Free.Start; - result->Size = result->End - result->Start; - result->Pool = pool; - result->Alignment = alignment; - return needed; } -static unsigned long -AllocFromAGP(ScrnInfoPtr pScrn, I830MemRange *result, long size, - unsigned long alignment, int flags) +static void +i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem) +{ + i830_unbind_memory(pScrn, mem); + + /* Disconnect from the list of allocations */ + if (mem->prev != NULL) + mem->prev->next = mem->next; + if (mem->next != NULL) + mem->next->prev = mem->prev; + + /* Free any AGP memory. */ + i830_unbind_memory(pScrn, mem); + + if (mem->key != -1) { + xf86DeallocateGARTMemory(pScrn->scrnIndex, mem->key); + mem->key = -1; + } + + xfree(mem->name); + xfree(mem); +} + +/* Resets the state of the aperture allocator, freeing all memory that had + * been allocated. + */ +void +i830_reset_allocations(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - unsigned long start, end; - unsigned long newApStart, newApEnd; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; - if (!result || !size) - return 0; + /* While there is any memory between the start and end markers, free it. */ + while (pI830->memory_list->next->next != NULL) + i830_free_memory(pScrn, pI830->memory_list->next); - if ((flags & ALLOCATE_AT_BOTTOM) && pI830->StolenMemory.Size != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "AllocFromAGP(): can't allocate from " - "bottom when there is stolen memory\n"); - return 0; + /* Null out the pointers for all the allocations we just freed. This is + * kind of gross, but at least it's just one place now. + */ + for (i = 0; i < xf86_config->num_crtc; i++) { + I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; + + intel_crtc->cursor_mem = NULL; + intel_crtc->cursor_mem_argb = NULL; } - if (size > pI830->FreeMemory) { - if (dryrun) - pI830->FreeMemory = size; - else - return 0; + pI830->front_buffer = NULL; + pI830->front_buffer_2 = NULL; + pI830->xaa_scratch = NULL; + pI830->xaa_scratch_2 = NULL; + pI830->exa_offscreen = NULL; + pI830->exa_965_state = NULL; + pI830->overlay_regs = NULL; + pI830->xaa_linear = NULL; + pI830->logical_context = NULL; + pI830->back_buffer = NULL; + pI830->depth_buffer = NULL; + pI830->textures = NULL; + pI830->memory_manager = NULL; + pI830->LpRing->mem = NULL; +} + +/** + * Initialize's the driver's video memory allocator to allocate in the + * given range. + */ +Bool +i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, + unsigned long size) +{ + I830Ptr pI830 = I830PTR(pScrn); + i830_memory *start, *end; + + start = xcalloc(1, sizeof(*start)); + if (start == NULL) + return FALSE; + start->name = xstrdup("start marker"); + if (start->name == NULL) { + xfree(start); + return FALSE; + } + end = xcalloc(1, sizeof(*end)); + if (end == NULL) { + xfree(start->name); + xfree(start); + return FALSE; + } + end->name = xstrdup("end marker"); + if (end->name == NULL) { + xfree(start->name); + xfree(start); + xfree(end); + return FALSE; } - /* Calculate offset */ - if (flags & ALLOCATE_AT_BOTTOM) { - start = ROUND_TO(pI830->MemoryAperture.Start, alignment); - if (flags & ALIGN_BOTH_ENDS) - end = ROUND_TO(start + size, alignment); - else - end = start + size; - newApStart = end; - newApEnd = pI830->MemoryAperture.End; - } else { + start->key = -1; + start->offset = offset; + start->end = start->offset; + start->size = 0; + start->next = end; + end->key = -1; + end->offset = offset + size; + end->end = end->offset; + end->size = 0; + end->prev = start; + + pI830->memory_list = start; + + return TRUE; +} + +/* Allocate aperture space for the given size and alignment, and returns the + * memory allocation. + * + * Allocations are a minimum of a page, and will be at least page-aligned. + */ +static i830_memory * +i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name, + long size, unsigned long alignment, int flags) +{ + I830Ptr pI830 = I830PTR(pScrn); + i830_memory *mem, *scan; + + mem = xcalloc(1, sizeof(*mem)); + if (mem == NULL) + return NULL; + + /* No memory allocated to back the region */ + mem->key = -1; + + mem->name = xstrdup(name); + if (mem->name == NULL) { + xfree(mem); + return NULL; + } + mem->size = size; + + if (alignment < GTT_PAGE_SIZE) + alignment = GTT_PAGE_SIZE; + + for (scan = pI830->memory_list; scan->next != NULL; scan = scan->next) { + mem->offset = ROUND_TO(scan->end, alignment); + mem->end = mem->offset + size; if (flags & ALIGN_BOTH_ENDS) - end = ROUND_DOWN_TO(pI830->MemoryAperture.End, alignment); - else - end = pI830->MemoryAperture.End; - start = ROUND_DOWN_TO(end - size, alignment); - newApStart = pI830->MemoryAperture.Start; - newApEnd = start; + mem->end = ROUND_TO(mem->end, alignment); + if (mem->end <= scan->next->offset) + break; + } + if (scan->next == NULL) { + /* Reached the end of the list, and didn't find space */ + xfree(mem->name); + xfree(mem); + return NULL; } + /* Insert new allocation into the list */ + mem->prev = scan; + mem->next = scan->next; + scan->next = mem; + mem->next->prev = scan; - if (!dryrun) { - if (newApStart > newApEnd) - return 0; + return mem; +} - if (flags & NEED_PHYSICAL_ADDR) { - result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2, - &(result->Physical)); - } else { - result->Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, - NULL); - } +/** + * Allocates the AGP memory necessary for the part of a memory allocation not + * already covered by the stolen memory. + * + * The memory is automatically bound if we have the VT. + */ +static Bool +i830_allocate_agp_memory(ScrnInfoPtr pScrn, i830_memory *mem, int flags) +{ + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size; + + if (mem->key != -1) + return TRUE; + + if (mem->offset + mem->size <= pI830->stolen_size) + return TRUE; + + if (mem->offset < pI830->stolen_size) + mem->agp_offset = pI830->stolen_size; + else + mem->agp_offset = mem->offset; + + size = mem->size - (mem->agp_offset - mem->offset); + + if (flags & NEED_PHYSICAL_ADDR) + mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2, + &mem->bus_addr); + else + mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL); + if (mem->key == -1 || ((flags & NEED_PHYSICAL_ADDR) && mem->bus_addr == 0)) + { + return FALSE; + } - if (result->Key == -1) - return 0; + if (!i830_bind_memory(pScrn, mem)) { + return FALSE; } - pI830->allocatedMemory += size; - pI830->MemoryAperture.Start = newApStart; - pI830->MemoryAperture.End = newApEnd; - pI830->MemoryAperture.Size = newApEnd - newApStart; - pI830->FreeMemory -= size; - result->Start = start; - result->End = start + size; - result->Size = size; - result->Offset = start; - result->Alignment = alignment; - result->Pool = NULL; - - return size; + return TRUE; } -void -I830FreeVidMem(ScrnInfoPtr pScrn, I830MemRange *range) + +/* Allocates video memory at the given size and alignment. + * + * The memory will be bound automatically when the driver is in control of the + * VT. + */ +static i830_memory * +i830_allocate_memory(ScrnInfoPtr pScrn, const char *name, + unsigned long size, unsigned long alignment, int flags) { - I830Ptr pI830 = I830PTR(pScrn); + i830_memory *mem; - if (!range || range->Size == 0) - return; + mem = i830_allocate_aperture(pScrn, name, size, alignment, flags); + if (mem == NULL) + return NULL; - if (range->Key != -1) - xf86DeallocateGARTMemory(pScrn->scrnIndex, range->Key); + if (!i830_allocate_agp_memory(pScrn, mem, flags)) { + i830_free_memory(pScrn, mem); + return NULL; + } - if (range->Pool) { - /* - * This code essentially resets what I830DoPoolAllocation() did. - * And if things are freed in the wrong order this can break wildly! - * USE CAUTION when changing anything here... - */ - I830MemPool *Pool = range->Pool; - Pool->Total.End = pI830->StolenMemory.End; + return mem; +} - if (pI830->StolenOnly) - Pool->Free.End += range->Size; - else - Pool->Free.End = Pool->Total.End; +/* Allocate a tiled region with the given size and pitch. + * + * As is, we might miss out on tiling some allocations on older hardware with + * large framebuffer size and a small aperture size, where the first + * allocations use a large alignment even though we've got fences to spare, and + * the later allocations can't find enough aperture space left. We could do + * some search across all allocation options to fix this, probably, but that + * would be another rewrite. + */ +static i830_memory * +i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name, + unsigned long size, unsigned long pitch, + unsigned long alignment, int flags, + enum tile_format tile_format) +{ + I830Ptr pI830 = I830PTR(pScrn); + unsigned long aper_size; + unsigned long aper_align; + i830_memory *mem; + int fence_divide, i; - if (Pool->Free.End < Pool->Free.Start) { - Pool->Free.End = Pool->Free.Start; - } + if (tile_format == TILING_NONE) + return i830_allocate_memory(pScrn, name, size, alignment, flags); - Pool->Free.Size = Pool->Free.End - Pool->Free.Start; - Pool->Total.Size = Pool->Total.End - Pool->Total.Start; + /* Check for maximum tiled region size */ + if (IS_I9XX(pI830)) { + if (size > MB(128)) + return NULL; + } else { + if (size > MB(64)) + return NULL; + } - if (!pI830->StolenOnly) { - pI830->FreeMemory -= Pool->Free.Size; - pI830->MemoryAperture.Start -= (range->Size - Pool->Free.Size); - pI830->MemoryAperture.Size += (range->Size - Pool->Free.Size); - } + aper_size = i830_get_fence_size(pScrn, size); + if (IS_I965G(pI830)) { + aper_align = GTT_PAGE_SIZE; } else { - if (range->Alignment == GTT_PAGE_SIZE) - pI830->MemoryAperture.End = range->End; - else { - pI830->MemoryAperture.End = range->End - range->Size + - range->Alignment; + /* The offset has to be aligned to at least the size of the fence + * region. + */ + aper_align = aper_size; + } + if (aper_align < alignment) + aper_align = alignment; + + fence_divide = 1; + mem = i830_allocate_aperture(pScrn, name, aper_size, aper_align, flags); + if (mem == NULL && !IS_I965G(pI830)) { + /* For the older hardware with stricter fencing limits, if we + * couldn't allocate with the large alignment, try relaxing the + * alignment requirements and using more fences to cover the area. + */ + for (fence_divide = 2; fence_divide <= 4 && mem == NULL; + fence_divide *= 2) + { + /* Check that it's not too small for fencing. */ + if (i830_get_fence_size(pScrn, aper_align / fence_divide) != + aper_align / fence_divide) + { + break; + } + + mem = i830_allocate_aperture(pScrn, name, aper_size, + aper_align / fence_divide, flags); } - pI830->MemoryAperture.Size = pI830->MemoryAperture.End - - pI830->MemoryAperture.Start; } - if (!pI830->StolenOnly) - pI830->FreeMemory += range->Size; - pI830->allocatedMemory -= range->Size; + if (mem == NULL) + return NULL; + + /* Make sure we've got enough free fence regs. It's pretty hard to run + * out, luckily, with 8 even on older hardware and us only tiling + * front/back/depth buffers. + */ + if (pI830->next_fence + fence_divide > + (IS_I965G(pI830) ? FENCE_NEW_NR : FENCE_NR)) + { + i830_free_memory(pScrn, mem); + return NULL; + } + + /* Allocate any necessary AGP memory to back this allocation */ + if (!i830_allocate_agp_memory(pScrn, mem, flags)) { + i830_free_memory(pScrn, mem); + return NULL; + } + + /* Set up the fence registers. */ + for (i = 0; i < fence_divide; i++) { + i830_set_fence(pScrn, pI830->next_fence++, + mem->offset + mem->size * i / fence_divide, pitch, + mem->size / fence_divide, tile_format); + } + + mem->size = size; + + return mem; +} + +static void +i830_describe_tiling(ScrnInfoPtr pScrn, int verbosity, const char *prefix, + i830_memory *mem, unsigned int tiling_mode) +{ + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%s%s is %stiled\n", prefix, mem->name, + (tiling_mode == FENCE_LINEAR) ? "not " : ""); } -unsigned long -I830AllocVidMem(ScrnInfoPtr pScrn, I830MemRange *result, I830MemPool *pool, - long size, unsigned long alignment, int flags) +void +i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) { I830Ptr pI830 = I830PTR(pScrn); - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + i830_memory *mem; + + if (pI830->memory_list == NULL) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sMemory allocator not initialized\n", prefix); + return; + } + + if (pI830->memory_list->next->next == NULL) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sNo memory allocations\n", prefix); + return; + } + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sMemory allocation layout:\n", prefix); - if (!result) - return 0; + for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) { - /* Make sure these are initialised. */ - result->Size = 0; - result->Key = -1; + if (mem->offset >= pI830->stolen_size && + mem->prev->offset <= pI830->stolen_size) + { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%s0x%08lx: end of stolen memory\n", + prefix, pI830->stolen_size); + } - if (!size) { - return 0; + if (mem->bus_addr == 0) { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%s0x%08lx-0x%08lx: %s (%ld kB)\n", prefix, + mem->offset, mem->end - 1, mem->name, + mem->size / 1024); + } else { + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%s0x%08lx-0x%08lx: %s (%ld kB, %08lx physical)\n", + prefix, + mem->offset, mem->end - 1, mem->name, + mem->size / 1024, mem->bus_addr); + } } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%s0x%08lx: end of aperture\n", + prefix, pI830->FbMapSize); - switch (flags & FROM_MASK) { - case FROM_POOL_ONLY: - return AllocFromPool(pScrn, result, pool, size, alignment, flags); - case FROM_NEW_ONLY: - if (!dryrun && (pI830->StolenOnly || (pI830->FreeMemory <= 0))) - return 0; - return AllocFromAGP(pScrn, result, size, alignment, flags); - case FROM_ANYWHERE: - if ((!(flags & ALLOCATE_AT_BOTTOM) && (pI830->FreeMemory >= size)) || - (flags & NEED_PHYSICAL_ADDR)) - return AllocFromAGP(pScrn, result, size, alignment, flags); - else - return AllocFromPool(pScrn, result, pool, size, alignment, flags); - default: - /* Shouldn't happen. */ - return 0; + if (pI830->front_buffer != NULL) { + i830_describe_tiling(pScrn, verbosity, prefix, pI830->front_buffer, + pI830->front_tiled); + } + if (pI830->back_buffer != NULL) { + i830_describe_tiling(pScrn, verbosity, prefix, pI830->back_buffer, + pI830->back_tiled); + } + if (pI830->depth_buffer != NULL) { + i830_describe_tiling(pScrn, verbosity, prefix, pI830->depth_buffer, + pI830->depth_tiled); } } static Bool -AllocateRingBuffer(ScrnInfoPtr pScrn, int flags) +i830_allocate_ringbuffer(ScrnInfoPtr pScrn, int flags) { I830Ptr pI830 = I830PTR(pScrn); - unsigned long size, alloced; Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - - /* Clear ring buffer info */ - memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); - pI830->LpRing->mem.Key = -1; - if (pI830->noAccel) + if (pI830->noAccel || pI830->LpRing->mem != NULL) return TRUE; - /* Ring buffer */ - size = PRIMARY_RINGBUFFER_SIZE; - if (flags & FORCE_LOW) - flags |= FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM; - else - flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP; - - alloced = I830AllocVidMem(pScrn, &(pI830->LpRing->mem), - &(pI830->StolenPool), size, - GTT_PAGE_SIZE, flags); - if (alloced < size) { + pI830->LpRing->mem = i830_allocate_memory(pScrn, "ring buffer", + PRIMARY_RINGBUFFER_SIZE, + GTT_PAGE_SIZE, 0); + if (pI830->LpRing->mem == NULL) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate Ring Buffer space\n"); } return FALSE; } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the ring buffer at 0x%lx\n", s, - alloced / 1024, pI830->LpRing->mem.Start); - pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; + + pI830->LpRing->tail_mask = pI830->LpRing->mem->size - 1; return TRUE; } #ifdef I830_XV -/* - * Note, the FORCE_LOW flag is currently not used or supported. +/** + * Allocate space for overlay registers and XAA linear allocator (if + * requested) */ static Bool -AllocateOverlay(ScrnInfoPtr pScrn, int flags) +i830_allocate_overlay(ScrnInfoPtr pScrn, int flags) { I830Ptr pI830 = I830PTR(pScrn); - unsigned long size, alloced; Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - /* Clear overlay info */ - memset(pI830->OverlayMem, 0, sizeof(I830MemRange)); - pI830->OverlayMem->Key = -1; - - if (!pI830->XvEnabled) + /* Only allocate if overlay is going to be enabled. */ + if (!pI830->XvEnabled || IS_I965G(pI830)) return TRUE; - /* - * The overlay register space needs a physical address in - * system memory. We get this from the agpgart module using - * a special memory type. - */ - - size = OVERLAY_SIZE; - if (flags & FORCE_LOW) - flags |= FROM_POOL_ONLY | ALLOCATE_AT_BOTTOM | NEED_PHYSICAL_ADDR; - else - flags |= FROM_ANYWHERE | ALLOCATE_AT_TOP | NEED_PHYSICAL_ADDR; - - alloced = I830AllocVidMem(pScrn, pI830->OverlayMem, - &(pI830->StolenPool), size, GTT_PAGE_SIZE, - flags); - - /* - * XXX For testing only. Don't enable this unless you know how to set - * physBase. - */ - if (flags & FORCE_LOW) { - ErrorF("AllocateOverlay() doesn't support setting FORCE_LOW\n"); - return FALSE; - } - - if (!dryrun && (alloced < size)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate Overlay register space.\n"); - /* This failure isn't fatal. */ - } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for Overlay registers at 0x%lx " - "(0x%08lx).\n", s, - alloced / 1024, pI830->OverlayMem->Start, - pI830->OverlayMem->Physical); + if (!IS_I965G(pI830)) { + pI830->overlay_regs = i830_allocate_memory(pScrn, "overlay registers", + OVERLAY_SIZE, GTT_PAGE_SIZE, + NEED_PHYSICAL_ADDR); + if (pI830->overlay_regs == NULL) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate Overlay register space.\n"); + /* This failure isn't fatal. */ + } + } } - /* Clear linearmem info */ - if (pI830->LinearAlloc) { - memset(&(pI830->LinearMem), 0, sizeof(I830MemRange)); - pI830->LinearMem.Key = -1; - - size = KB(pI830->LinearAlloc); - alloced = I830AllocVidMem(pScrn, &(pI830->LinearMem), - &(pI830->StolenPool), - size, GTT_PAGE_SIZE, - FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { + if (!pI830->useEXA && pI830->LinearAlloc) { + pI830->xaa_linear = i830_allocate_memory(pScrn, "XAA linear memory", + KB(pI830->LinearAlloc), + GTT_PAGE_SIZE, 0); + if (pI830->xaa_linear == NULL) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate linear buffer space\n"); } - } else - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the linear buffer at " - "0x%lx\n", s, - alloced / 1024, pI830->LinearMem.Start); + } } return TRUE; @@ -479,22 +682,6 @@ IsTileable(ScrnInfoPtr pScrn, int pitch) } } -static unsigned long -GetFreeSpace(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - unsigned long extra = 0; - - /* First check for free space in StolenPool. */ - if (pI830->StolenPool.Free.Size > 0) - extra = pI830->StolenPool.Free.Size; - /* Next check for unallocated space. */ - if (pI830->FreeMemory > 0) - extra += pI830->FreeMemory; - - return extra; -} - /* This is the 2D rendering vertical coordinate limit. We can ignore * the 3D rendering limits in our 2d pixmap cache allocation, because XAA * doesn't do any 3D rendering to/from the cache lines when using an offset @@ -512,24 +699,23 @@ GetFreeSpace(ScrnInfoPtr pScrn) * \param pI830 I830Ptr for the screen being allocated. * \param FbMemBox */ -static Bool -I830AllocateFramebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, - I830MemRange *FrontBuffer, I830MemPool *StolenPool, - Bool secondary, const int flags) +static i830_memory * +i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, + Bool secondary, int flags) { Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - unsigned long minspace, avail, lineSize; + unsigned int pitch = pScrn->displayWidth * pI830->cpp; + unsigned long minspace, avail; int cacheLines, maxCacheLines; int verbosity = dryrun ? 4 : 1; const char *s = dryrun ? "[dryrun] " : ""; - Bool tileable; - int align, alignflags; - long size, alloced, fb_height; + int align; + long size, fb_height; + char *name; + i830_memory *front_buffer = NULL; /* Clear everything first. */ memset(FbMemBox, 0, sizeof(*FbMemBox)); - memset(FrontBuffer, 0, sizeof(*FrontBuffer)); - FrontBuffer->Key = -1; /* We'll allocate the fb such that the root window will fit regardless of * rotation. @@ -549,18 +735,16 @@ I830AllocateFramebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, * enough for the virtual screen size, plus some pixmap cache * space if we're using XAA. */ - - lineSize = pScrn->displayWidth * pI830->cpp; - minspace = lineSize * pScrn->virtualY; + minspace = pitch * pScrn->virtualY; avail = pScrn->videoRam * 1024; if (!pI830->useEXA) { - maxCacheLines = (avail - minspace) / lineSize; + maxCacheLines = (avail - minspace) / pitch; /* This shouldn't happen. */ if (maxCacheLines < 0) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Internal Error: " - "maxCacheLines < 0 in I830Allocate2DMemory()\n"); + "maxCacheLines < 0 in i830_allocate_2d_memory()\n"); maxCacheLines = 0; } if (maxCacheLines > (MAX_2D_HEIGHT - pScrn->virtualY)) @@ -571,11 +755,11 @@ I830AllocateFramebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, } else { int size; - size = 3 * lineSize * pScrn->virtualY; + size = 3 * pitch * pScrn->virtualY; size += 1920 * 1088 * 2 * 2; size = ROUND_TO_PAGE(size); - cacheLines = (size + lineSize - 1) / lineSize; + cacheLines = (size + pitch - 1) / pitch; } if (cacheLines > maxCacheLines) cacheLines = maxCacheLines; @@ -592,125 +776,96 @@ I830AllocateFramebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, cacheLines = 0; } - tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip && - IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); - if (tileable) { + size = pitch * (fb_height + cacheLines); + size = ROUND_TO_PAGE(size); + + name = secondary ? "secondary front buffer" : "front buffer"; + + /* Attempt to allocate it tiled first if we have page flipping on. */ + if (!flags & ALLOC_NO_TILING && pI830->allowPageFlip && + IsTileable(pScrn, pitch)) + { + /* XXX: probably not the case on 965 */ if (IS_I9XX(pI830)) align = MB(1); else align = KB(512); - alignflags = ALIGN_BOTH_ENDS; - } else { - align = KB(64); - alignflags = 0; + front_buffer = i830_allocate_memory_tiled(pScrn, name, size, + pitch, align, + flags, TILING_XMAJOR); + pI830->front_tiled = FENCE_XMAJOR; } - size = lineSize * (fb_height + cacheLines); - size = ROUND_TO_PAGE(size); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sInitial %sframebuffer allocation size: %ld kByte\n", - s, secondary ? "secondary " : "", - size / 1024); - alloced = I830AllocVidMem(pScrn, FrontBuffer, - StolenPool, size, align, - flags | alignflags | - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); - if (alloced < size) { + /* If not, attempt it linear */ + if (front_buffer == NULL) { + front_buffer = i830_allocate_memory(pScrn, name, size, KB(64), flags); + pI830->front_tiled = FENCE_LINEAR; + } + + if (front_buffer == NULL) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " "%sframebuffer. Is your VideoRAM set too low?\n", secondary ? "secondary " : ""); } - return FALSE; + return NULL; } - return TRUE; + return front_buffer; } static Bool -I830AllocateCursorBuffers(xf86CrtcPtr crtc, const int flags) +i830_allocate_cursor_buffers(xf86CrtcPtr crtc, int flags) { ScrnInfoPtr pScrn = crtc->scrn; I830CrtcPrivatePtr intel_crtc = crtc->driver_private; I830Ptr pI830 = I830PTR(pScrn); Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - long size, alloced; - int cursFlags = 0; - - /* Clear cursor info */ - memset(&intel_crtc->cursor_mem, 0, sizeof(I830MemRange)); - intel_crtc->cursor_mem.Key = -1; - memset(&intel_crtc->cursor_mem_argb, 0, sizeof(I830MemRange)); - intel_crtc->cursor_mem_argb.Key = -1; + long size; if (pI830->SWCursor) return FALSE; - /* - * Mouse cursor -- The i810-i830 need a physical address in system + /* Mouse cursor -- The i810-i830 need a physical address in system * memory from which to upload the cursor. We get this from * the agpgart module using a special memory type. */ size = HWCURSOR_SIZE; - cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP; if (pI830->CursorNeedsPhysical) - cursFlags |= NEED_PHYSICAL_ADDR; + flags |= NEED_PHYSICAL_ADDR; - alloced = I830AllocVidMem(pScrn, &intel_crtc->cursor_mem, - &pI830->StolenPool, size, - GTT_PAGE_SIZE, flags | cursFlags); - if (alloced < size || - (pI830->CursorNeedsPhysical && !intel_crtc->cursor_mem.Physical)) - { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate HW cursor space.\n"); - return FALSE; - } - } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for HW cursor at 0x%lx", s, - alloced / 1024, intel_crtc->cursor_mem.Start); - if (pI830->CursorNeedsPhysical) { - xf86ErrorFVerb(verbosity, " (0x%08lx)", - intel_crtc->cursor_mem.Physical); + if (intel_crtc->cursor_mem == NULL) { + intel_crtc->cursor_mem = i830_allocate_memory(pScrn, "HW cursor", + size, GTT_PAGE_SIZE, + flags); + if (intel_crtc->cursor_mem == NULL) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate HW cursor space.\n"); + } + return FALSE; } - xf86ErrorFVerb(verbosity, "\n"); } - /* Allocate the ARGB cursor space. Its success is optional -- we won't set - * SWCursor if it fails. - */ - size = HWCURSOR_SIZE_ARGB; - cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP; - if (pI830->CursorNeedsPhysical) - cursFlags |= NEED_PHYSICAL_ADDR; - - alloced = I830AllocVidMem(pScrn, &intel_crtc->cursor_mem_argb, - &pI830->StolenPool, size, - GTT_PAGE_SIZE, flags | cursFlags); - if (alloced < size || - (pI830->CursorNeedsPhysical && !intel_crtc->cursor_mem_argb.Physical)) - { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate HW (ARGB) cursor space.\n"); - } - } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for HW (ARGB) cursor at 0x%lx", s, - alloced / 1024, intel_crtc->cursor_mem_argb.Start); - if (pI830->CursorNeedsPhysical) { - xf86ErrorFVerb(verbosity, " (0x%08lx)", - intel_crtc->cursor_mem_argb.Physical); + if (intel_crtc->cursor_mem_argb == NULL) { + /* Allocate the ARGB cursor space. Its success is optional -- we won't + * set SWCursor if it fails. + */ + intel_crtc->cursor_mem_argb = i830_allocate_memory(pScrn, + "HW ARGB cursor", + HWCURSOR_SIZE_ARGB, + GTT_PAGE_SIZE, + flags); + if (intel_crtc->cursor_mem_argb == NULL) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate HW (ARGB) cursor space.\n"); + } } - xf86ErrorFVerb(verbosity, "\n"); } - return FALSE; + return TRUE; } /* @@ -718,18 +873,16 @@ I830AllocateCursorBuffers(xf86CrtcPtr crtc, const int flags) * ring buffer, scratch memory, HW cursor. */ Bool -I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) +i830_allocate_2d_memory(ScrnInfoPtr pScrn, const int flags) { I830Ptr pI830 = I830PTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - long size, alloced; + unsigned int pitch = pScrn->displayWidth * pI830->cpp; + long size; Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - Bool tileable; - int align, alignflags, i; + int i; - DPRINTF(PFX, "I830Allocate2DMemory: inital is %s\n", + DPRINTF(PFX, "i830_allocate_2d_memory: inital is %s\n", BOOLTOSTRING(flags & ALLOC_INITIAL)); if (!pI830->StolenOnly && @@ -738,88 +891,70 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "AGP GART support is either not available or cannot " "be used.\n" - "\tMake sure your kernel has agpgart support or has " - "the\n" - "\tagpgart module loaded.\n"); + "\tMake sure your kernel has agpgart support or has\n" + "\tthe agpgart module loaded.\n"); } return FALSE; } + /* Allocate the ring buffer first, so it ends up in stolen mem. */ + i830_allocate_ringbuffer(pScrn, flags); - /* - * The I830 is slightly different from the I830/I815, it has no - * dcache and it has stolen memory by default in its gtt. All - * additional memory must go after it. - */ - - DPRINTF(PFX, - "size == %luk (%lu bytes == pScrn->videoRam)\n" - "pI830->StolenSize == %luk (%lu bytes)\n", - pScrn->videoRam, pScrn->videoRam * 1024, - pI830->StolenPool.Free.Size / 1024, - pI830->StolenPool.Free.Size); - - if (flags & ALLOC_INITIAL) { - if (pI830->NeedRingBufferLow) - AllocateRingBuffer(pScrn, flags | FORCE_LOW); - - /* Unfortunately this doesn't run on the DRY_RUN pass because our - * second head hasn't been created yet..... */ - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { - I830EntPtr pI830Ent = pI830->entityPrivate; - I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2); - - if (!I830AllocateFramebuffer(pI830Ent->pScrn_2, pI8302, - &pI830->FbMemBox2, - &pI830->FrontBuffer2, - &pI830->StolenPool, - TRUE, flags)) - { - return FALSE; - } - } - if (!I830AllocateFramebuffer(pScrn, pI830, &pI830->FbMemBox, - &pI830->FrontBuffer, &pI830->StolenPool, - FALSE, flags)) - { - return FALSE; + /* Next, allocate other fixed-size allocations we have. */ + if (!pI830->SWCursor) { + /* Allocate cursor memory */ + for (i = 0; i < xf86_config->num_crtc; i++) { + if (!i830_allocate_cursor_buffers(xf86_config->crtc[i], flags) && + !pI830->SWCursor) + { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Disabling HW cursor because the cursor memory " + "allocation failed.\n"); + pI830->SWCursor = TRUE; + break; + } } + } + +#ifdef I830_XV + /* Allocate overlay register space and optional XAA linear allocator + * space. The second head in zaphod mode will share the space. + */ + if (I830IsPrimary(pScrn)) + i830_allocate_overlay(pScrn, flags); +#endif #ifdef I830_USE_EXA - if (pI830->useEXA) { + if (pI830->useEXA) { + if (pI830->exa_offscreen == NULL) { /* Default EXA to having 3 screens worth of offscreen memory space * (for pixmaps), plus a double-buffered, 1920x1088 video's worth. + * + * XXX: It would be nice to auto-size it larger if the user + * specified a larger size, or to fit along with texture and FB + * memory if a low videoRam is specified. */ - size = 3 * pScrn->displayWidth * pI830->cpp * pScrn->virtualY; + size = 3 * pitch * pScrn->virtualY; size += 1920 * 1088 * 2 * 2; size = ROUND_TO_PAGE(size); - alloced = I830AllocVidMem(pScrn, &(pI830->Offscreen), - &(pI830->StolenPool), size, 1, - flags | - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); - if (alloced < size) { + pI830->exa_offscreen = i830_allocate_memory(pScrn, "exa offscreen", + size, 1, flags); + if (pI830->exa_offscreen == NULL) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " "offscreen memory. Not enough VRAM?\n"); } return FALSE; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Successful allocation of " - "EXA offscreen memory at 0x%lx, size %ld KB\n", - pI830->Offscreen.Start, pI830->Offscreen.Size/1024); } } - if (pI830->useEXA && IS_I965G(pI830)) { - memset(&(pI830->EXAStateMem), 0, sizeof(I830MemRange)); - pI830->EXAStateMem.Key = -1; - size = ROUND_TO_PAGE(EXA_LINEAR_EXTRA); - align = GTT_PAGE_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->EXAStateMem), - &(pI830->StolenPool), size, align, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { + + if (IS_I965G(pI830) && pI830->exa_965_state == NULL) { + pI830->exa_965_state = + i830_allocate_memory(pScrn, "exa G965 state buffer", + EXA_LINEAR_EXTRA, GTT_PAGE_SIZE, + flags); + if (pI830->exa_965_state == NULL) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "G965: Failed to allocate exa state buffer " @@ -827,228 +962,85 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) } return FALSE; } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the G965 exa state buffer " - "at 0x%lx - 0x%lx.\n", s, - alloced / 1024, pI830->EXAStateMem.Start, - pI830->EXAStateMem.End); } -#endif - } else { - long lineSize; - long extra = 0; - long maxFb = 0; - - /* - * XXX Need to "free" up any 3D allocations if the DRI ended up - * and make them available for 2D. The best way to do this would - * be position all of those regions contiguously at the end of the - * StolenPool. - */ - extra = GetFreeSpace(pScrn); - - if (extra == 0) - return TRUE; - - maxFb = pI830->FrontBuffer.Size + extra; - lineSize = pScrn->displayWidth * pI830->cpp; - maxFb = ROUND_DOWN_TO(maxFb, lineSize); - if (maxFb > lineSize * MAX_2D_HEIGHT) - maxFb = lineSize * MAX_2D_HEIGHT; - if (0/*maxFb > pI830->FrontBuffer.Size*/) { - unsigned long oldsize; - /* - * Sanity check -- the fb should be the last thing allocated at - * the bottom of the stolen pool. - */ - if (pI830->StolenPool.Free.Start != pI830->FrontBuffer.End) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Internal error in I830Allocate2DMemory():\n\t" - "Framebuffer isn't the last allocation at the " - "bottom of StolenPool\n\t(%lx != %lx).\n", - pI830->FrontBuffer.End, - pI830->StolenPool.Free.Start); - return FALSE; - } - /* - * XXX Maybe should have a "Free" function. This should be - * the only place where a region is resized, and we know that - * the fb is always at the bottom of the aperture/stolen pool, - * and is the only region that is allocated bottom-up. - * Allowing for more general realloction would require a smarter - * allocation system. - */ - oldsize = pI830->FrontBuffer.Size; - pI830->StolenPool.Free.Size += pI830->FrontBuffer.Size; - pI830->StolenPool.Free.Start -= pI830->FrontBuffer.Size; - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sUpdated framebuffer allocation size from %ld " - "to %ld kByte\n", s, oldsize / 1024, maxFb / 1024); - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sUpdated pixmap cache from %ld scanlines to %ld " - "scanlines\n", s, - oldsize / lineSize - pScrn->virtualY, - maxFb / lineSize - pScrn->virtualY); - pI830->FbMemBox.y2 = maxFb / lineSize; - tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip && - IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); - if (tileable) { - if (IS_I9XX(pI830)) - align = MB(1); - else - align = KB(512); - alignflags = ALIGN_BOTH_ENDS; - } else { - align = KB(64); - alignflags = 0; - } - alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer), - &(pI830->StolenPool), maxFb, align, - flags | alignflags | - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); - if (alloced < maxFb) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to re-allocate framebuffer\n"); - } - return FALSE; - } - } - return TRUE; } +#endif /* I830_USE_EXA */ -#if REMAP_RESERVED - /* - * Allocate a dummy page to pass when attempting to rebind the - * pre-allocated region. - */ - if (!dryrun) { - memset(&(pI830->Dummy), 0, sizeof(pI830->Dummy)); - pI830->Dummy.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, - NULL); - pI830->Dummy.Offset = 0; - } -#endif + if (flags & ALLOC_INITIAL) { - if (!pI830->SWCursor && !dryrun) { - for (i = 0; i < xf86_config->num_crtc; i++) { - if (!I830AllocateCursorBuffers(xf86_config->crtc[i], flags) && - pI830->SWCursor) - { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Disabling HW cursor because the cursor memory " - "allocation failed.\n"); - pI830->SWCursor = TRUE; - break; - } + /* Unfortunately this doesn't run on the DRY_RUN pass because our + * second head hasn't been created yet..... */ + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { + I830EntPtr pI830Ent = pI830->entityPrivate; + I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2); + + pI830->front_buffer_2 = + i830_allocate_framebuffer(pI830Ent->pScrn_2, pI8302, + &pI830->FbMemBox2, + TRUE, flags); + if (pI830->front_buffer_2 == NULL) + return FALSE; } + pI830->front_buffer = + i830_allocate_framebuffer(pScrn, pI830, &pI830->FbMemBox, + FALSE, flags); + if (pI830->front_buffer == NULL) + return FALSE; } -#ifdef I830_XV - AllocateOverlay(pScrn, flags); -#endif - - if (!pI830->NeedRingBufferLow) - AllocateRingBuffer(pScrn, flags); - - /* Clear scratch info */ - memset(&(pI830->Scratch), 0, sizeof(I830MemRange)); - pI830->Scratch.Key = -1; - memset(&(pI830->Scratch2), 0, sizeof(I830MemRange)); - pI830->Scratch2.Key = -1; - - if (!pI830->noAccel) { - size = MAX_SCRATCH_BUFFER_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->Scratch), - &(pI830->StolenPool), - size, GTT_PAGE_SIZE, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { - size = MIN_SCRATCH_BUFFER_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->Scratch), - &(pI830->StolenPool), size, - GTT_PAGE_SIZE, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - } - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate scratch buffer space\n"); + if (!pI830->noAccel && !pI830->useEXA) { + if (pI830->xaa_scratch == NULL) { + pI830->xaa_scratch = + i830_allocate_memory(pScrn, "xaa scratch", + MAX_SCRATCH_BUFFER_SIZE, GTT_PAGE_SIZE, + flags); + if (pI830->xaa_scratch == NULL) { + pI830->xaa_scratch = + i830_allocate_memory(pScrn, "xaa scratch", + MIN_SCRATCH_BUFFER_SIZE, + GTT_PAGE_SIZE, + flags); + if (pI830->xaa_scratch == NULL) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate scratch buffer " + "space\n"); + } + return FALSE; + } } - return FALSE; } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the scratch buffer at 0x%lx\n", - s, alloced / 1024, pI830->Scratch.Start); /* Let's allocate another scratch buffer for the second head */ /* Again, this code won't execute on the dry run pass */ - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { - size = MAX_SCRATCH_BUFFER_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->Scratch2), - &(pI830->StolenPool), - size, GTT_PAGE_SIZE, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { - size = MIN_SCRATCH_BUFFER_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->Scratch2), - &(pI830->StolenPool), size, - GTT_PAGE_SIZE, - flags | FROM_ANYWHERE | - ALLOCATE_AT_TOP); - } - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate second scratch buffer " - "space\n"); + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2 && + pI830->xaa_scratch_2 == NULL) + { + pI830->xaa_scratch_2 = + i830_allocate_memory(pScrn, "xaa scratch 2", + MAX_SCRATCH_BUFFER_SIZE, GTT_PAGE_SIZE, + flags); + if (pI830->xaa_scratch_2 == NULL) { + pI830->xaa_scratch_2 = + i830_allocate_memory(pScrn, "xaa scratch 2", + MIN_SCRATCH_BUFFER_SIZE, + GTT_PAGE_SIZE, + flags); + if (pI830->xaa_scratch_2 == NULL) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate secondary scratch " + "buffer space\n"); + } + return FALSE; } - return FALSE; } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the second scratch buffer " - "at 0x%lx\n", s, - alloced / 1024, pI830->Scratch2.Start); } } return TRUE; } -void -I830ResetAllocations(ScrnInfoPtr pScrn, const int flags) -{ - I830Ptr pI830 = I830PTR(pScrn); - - pI830->MemoryAperture.Start = pI830->StolenMemory.End; - pI830->MemoryAperture.End = pI830->FbMapSize; - pI830->MemoryAperture.Size = pI830->FbMapSize - pI830->StolenMemory.Size; -#ifdef XF86DRI - if (!pI830->directRenderingDisabled) { - pI830->MemoryAperture.End -= KB(pI830->mmSize); - pI830->MemoryAperture.Size -= KB(pI830->mmSize); - } -#endif - pI830->StolenPool.Fixed = pI830->StolenMemory; - pI830->StolenPool.Total = pI830->StolenMemory; - pI830->StolenPool.Free = pI830->StolenPool.Total; - pI830->FreeMemory = pI830->TotalVideoRam - pI830->StolenPool.Total.Size; - pI830->allocatedMemory = 0; -} - -long -I830GetExcessMemoryAllocations(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - long allocated; - - allocated = pI830->StolenPool.Total.Size + pI830->allocatedMemory; - if (allocated > pI830->TotalVideoRam) - return allocated - pI830->TotalVideoRam; - else - return 0; -} - #ifdef XF86DRI static unsigned int myLog2(unsigned int n) @@ -1062,16 +1054,13 @@ myLog2(unsigned int n) return log2; } -Bool -I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags) +static Bool +i830_allocate_backbuffer(ScrnInfoPtr pScrn, const int flags) { I830Ptr pI830 = I830PTR(pScrn); - unsigned long size, alloced, align = 0; - Bool tileable; + unsigned int pitch = pScrn->displayWidth * pI830->cpp; + unsigned long size; Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - int lines; int height; if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) @@ -1079,152 +1068,106 @@ I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags) else height = pScrn->virtualX; - /* Back Buffer */ - memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); - pI830->BackBuffer.Key = -1; - tileable = !(flags & ALLOC_NO_TILING) && - IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); - if (tileable) { - /* Make the height a multiple of the tile height (16) */ - lines = (height + 15) / 16 * 16; - } else { - lines = height; + /* Try to allocate on the best tile-friendly boundaries. */ + if (!(flags & ALLOC_NO_TILING) && IsTileable(pScrn, pitch)) + { + size = ROUND_TO_PAGE(pitch * ALIGN(height, 16)); + pI830->back_buffer = + i830_allocate_memory_tiled(pScrn, "back buffer", + size, pitch, GTT_PAGE_SIZE, + flags | ALIGN_BOTH_ENDS, + TILING_XMAJOR); + pI830->back_tiled = FENCE_XMAJOR; } - size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp); - /* - * Try to allocate on the best tile-friendly boundaries. - */ - alloced = 0; - if (tileable) { - align = GetBestTileAlignment(size); - for (align = GetBestTileAlignment(size); - align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) - { - alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer), - &(pI830->StolenPool), size, align, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP | - ALIGN_BOTH_ENDS); - if (alloced >= size) - break; - } + /* Otherwise, just allocate it linear */ + if (pI830->back_buffer == NULL) { + size = ROUND_TO_PAGE(pitch * height); + pI830->back_buffer = i830_allocate_memory(pScrn, "back buffer", + size, GTT_PAGE_SIZE, + flags | ALIGN_BOTH_ENDS); + pI830->back_tiled = FENCE_LINEAR; } - if (alloced < size) { - /* Give up on trying to tile */ - tileable = FALSE; - size = ROUND_TO_PAGE(pScrn->displayWidth * height * pI830->cpp); - align = GTT_PAGE_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->BackBuffer), - &(pI830->StolenPool), size, align, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - } - if (alloced < size) { + + if (pI830->back_buffer == NULL) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate back buffer space.\n"); } return FALSE; } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the back buffer at 0x%lx.\n", s, - alloced / 1024, pI830->BackBuffer.Start); return TRUE; } -Bool -I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags) +static Bool +i830_allocate_depthbuffer(ScrnInfoPtr pScrn, const int flags) { I830Ptr pI830 = I830PTR(pScrn); - unsigned long size, alloced, align = 0; - Bool tileable; + unsigned long size; Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - int lines; + unsigned int pitch = pScrn->displayWidth * pI830->cpp; int height; + /* XXX: this rotation stuff is bogus */ if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) height = pScrn->virtualY; else height = pScrn->virtualX; - /* Depth Buffer -- same size as the back buffer */ - memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); - pI830->DepthBuffer.Key = -1; - tileable = !(flags & ALLOC_NO_TILING) && - IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); - if (tileable) { - /* Make the height a multiple of the tile height (16) */ - lines = (height + 15) / 16 * 16; - } else { - lines = height; - } + /* First try allocating it tiled */ + if (!(flags & ALLOC_NO_TILING) && IsTileable(pScrn, pitch)) + { + size = ROUND_TO_PAGE(pitch * ALIGN(height, 16)); - size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp); - /* - * Try to allocate on the best tile-friendly boundaries. - */ - alloced = 0; - if (tileable) { - align = GetBestTileAlignment(size); - for (align = GetBestTileAlignment(size); - align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) - { - alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer), - &(pI830->StolenPool), size, align, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP | - ALIGN_BOTH_ENDS); - if (alloced >= size) - break; - } + pI830->depth_buffer = + i830_allocate_memory_tiled(pScrn, "depth buffer", size, pitch, + GTT_PAGE_SIZE, flags | ALIGN_BOTH_ENDS, + TILING_YMAJOR); + pI830->depth_tiled = FENCE_YMAJOR; } - if (alloced < size) { - /* Give up on trying to tile */ - tileable = FALSE; - size = ROUND_TO_PAGE(pScrn->displayWidth * height * pI830->cpp); - align = GTT_PAGE_SIZE; - alloced = I830AllocVidMem(pScrn, &(pI830->DepthBuffer), - &(pI830->StolenPool), size, align, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); + + /* Otherwise, allocate it linear. */ + if (pI830->depth_buffer == NULL) { + size = ROUND_TO_PAGE(pitch * height); + pI830->depth_buffer = + i830_allocate_memory(pScrn, "depth buffer", size, GTT_PAGE_SIZE, + flags); + pI830->depth_tiled = FENCE_LINEAR; } - if (alloced < size) { + + if (pI830->depth_buffer == NULL) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate depth buffer space.\n"); } return FALSE; } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the depth buffer at 0x%lx.\n", s, - alloced / 1024, pI830->DepthBuffer.Start); return TRUE; } -Bool -I830AllocateTextureMemory(ScrnInfoPtr pScrn, const int flags) +static Bool +i830_allocate_texture_memory(ScrnInfoPtr pScrn, const int flags) { I830Ptr pI830 = I830PTR(pScrn); - unsigned long size, alloced; + unsigned long size; int i; Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; - /* Allocate the remaining space for textures. */ - memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); - pI830->TexMem.Key = -1; + if (pI830->mmModeFlags & I830_KERNEL_MM) { + pI830->memory_manager = + i830_allocate_aperture(pScrn, "DRI memory manager", + pI830->mmSize, GTT_PAGE_SIZE, + flags | ALIGN_BOTH_ENDS); + /* XXX: try memory manager size backoff here? */ + if (pI830->memory_manager == NULL) + return FALSE; + } if (pI830->mmModeFlags & I830_KERNEL_TEX) { - if (dryrun && pI830->pEnt->device->videoRam == 0) { - /* If we're laying out a default-sized allocation, then don't be - * too greedy and just ask for 32MB. - */ - size = MB(32); - } else { - size = GetFreeSpace(pScrn); - } + /* XXX: auto-sizing */ + size = MB(32); if (dryrun && (size < MB(1))) size = MB(1); i = myLog2(size / I830_NR_TEX_REGIONS); @@ -1237,306 +1180,157 @@ I830AllocateTextureMemory(ScrnInfoPtr pScrn, const int flags) if (size < KB(512)) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Less than 512 kBytes for texture space (real %ld " + "Less than 512 kBytes for texture space (real %ld" "kBytes).\n", size / 1024); } return FALSE; } - alloced = I830AllocVidMem(pScrn, &(pI830->TexMem), - &(pI830->StolenPool), size, GTT_PAGE_SIZE, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { + pI830->textures = i830_allocate_memory(pScrn, "textures", size, + GTT_PAGE_SIZE, flags); + if (pI830->textures == NULL) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate texture space.\n"); } return FALSE; } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for textures at 0x%lx\n", s, - alloced / 1024, pI830->TexMem.Start); } return TRUE; } Bool -I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags) +i830_allocate_3d_memory(ScrnInfoPtr pScrn, const int flags) { I830Ptr pI830 = I830PTR(pScrn); - unsigned long size, alloced; Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; DPRINTF(PFX, "I830Allocate3DMemory\n"); /* Space for logical context. 32k is fine for right now. */ - memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); - pI830->ContextMem.Key = -1; - size = KB(32); - alloced = I830AllocVidMem(pScrn, &(pI830->ContextMem), - &(pI830->StolenPool), size, GTT_PAGE_SIZE, - flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); - if (alloced < size) { + pI830->logical_context = i830_allocate_memory(pScrn, "logical 3D context", + KB(32), GTT_PAGE_SIZE, + flags); + if (pI830->logical_context == NULL) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate logical context space.\n"); } return FALSE; } - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocated %ld kB for the logical context at 0x%lx.\n", s, - alloced / 1024, pI830->ContextMem.Start); - - if (!I830AllocateBackBuffer(pScrn, flags)) - return FALSE; - - if (!I830AllocateDepthBuffer(pScrn, flags)) - return FALSE; - if (!I830AllocateTextureMemory(pScrn, flags)) + if (!i830_allocate_backbuffer(pScrn, flags)) return FALSE; - return TRUE; -} -#endif - -/* Allocate pool space that isn't pre-allocated */ -Bool -I830DoPoolAllocation(ScrnInfoPtr pScrn, I830MemPool *pool) -{ - I830Ptr pI830 = I830PTR(pScrn); - - DPRINTF(PFX, "I830DoPoolAllocation\n"); - - if (!pool) + if (!i830_allocate_depthbuffer(pScrn, flags)) return FALSE; - /* - * Sanity check: there shouldn't be an allocation required when - * there is only stolen memory. - */ - if (pI830->StolenOnly && (pool->Total.Size > pool->Fixed.Size)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "I830DoPoolAllocation(): pool size is greater than the " - "preallocated size,\n\t" - "and there is no allocatable memory.\n"); + if (!i830_allocate_texture_memory(pScrn, flags)) return FALSE; - } - if (pool->Total.Size > pool->Fixed.Size) { - pool->Allocated.Size = pool->Total.Size - pool->Fixed.Size; - pool->Allocated.Key = xf86AllocateGARTMemory(pScrn->scrnIndex, - pool->Allocated.Size, 0, - NULL); - if (pool->Allocated.Key == -1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Pool allocation failed\n"); - return FALSE; - } - pool->Allocated.Start = pool->Fixed.End; - pool->Allocated.End = pool->Total.Size; - pool->Allocated.Offset = pool->Allocated.Start; - } else - pool->Allocated.Key = -1; return TRUE; } - -static unsigned long topOfMem = 0; - -/* - * These modify the way memory is positioned within the aperture. - * - * By default, memory allocated from the bottom or specifically within - * the pool at the bottom gets allocated from the "stolen pool", which is - * actually the stolen memory plus any extra allocated to make it a larger - * contiguous region. Memory allocated from the AGP is allocated top-down - * from the end of the aperture space. Memory allocated "from top" defaults - * to AGP if there is enough "free space". The total allocation (stolen + - * extra) doesn't exceed the orignal pScrn->videoRam amount (this isn't true - * when memory allocated from AGP gets moved into the pool by one of the - * following options. - * - * XXX Write a better description. - * - */ -#define PACK_RANGES 0 -#define POOL_RANGES 0 - -Bool -I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem) -{ -#if POOL_RANGES - I830Ptr pI830 = I830PTR(pScrn); #endif - if (!mem) - return FALSE; - - if (mem->Pool && mem->Key == -1 && mem->Start < 0) { - mem->Start = mem->Pool->Total.End + mem->Start; - mem->End = mem->Start + mem->Size; - } -#if PACK_RANGES - /* - * Map AGP-allocated areas at the top of the stolen area, resulting in - * a contiguous region in the aperture. Normally most AGP-allocated areas - * will be at the top of the aperture, making alignment requirements - * easier to achieve. This optin is primarily for debugging purposes, - * and using this option can break any special alignment requirements. - */ - if (!mem->Pool && mem->Start != 0 && mem->Key != -1 && - mem->Physical == 0 && mem->Offset != 0) - { - long diff; - if (mem->Offset != mem->Start) - ErrorF("mem %p, Offset != Start\n", mem); - diff = mem->Offset - topOfMem; - mem->Start -= diff; - mem->End -= diff; - mem->Offset -= diff; - topOfMem += mem->Size; - } -#elif POOL_RANGES - /* - * Move AGP-allocated regions (that don't need a physical address) into - * the pre-allocated pool when there's enough space to do so. Note: the - * AGP-allocated areas aren't freed. This option is primarily for - * debugging purposes, and using it can break any special alignment - * requirements. - */ - if (!mem->Pool && mem->Start >= pI830->StolenPool.Free.End && - mem->Key != -1 && mem->Physical == 0 && mem->Offset != 0 && - pI830->StolenPool.Free.Size >= mem->Size) - { - long diff; - - if (mem->Offset != mem->Start) - ErrorF("mem %p, Offset != Start\n", mem); - diff = mem->Offset - pI830->StolenPool.Free.Start; - mem->Start -= diff; - mem->End -= diff; - mem->Offset -= diff; - mem->Key = -1; - pI830->StolenPool.Free.Start += mem->Size; - pI830->StolenPool.Free.Size -= mem->Size; - } -#endif - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%p: Memory at offset 0x%08lx, size %ld kBytes\n", (void *)mem, - mem->Start, mem->Size / 1024); - return TRUE; -} - -Bool -I830FixupOffsets(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; - - DPRINTF(PFX, "I830FixupOffsets\n"); - - topOfMem = pI830->StolenPool.Total.End; - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - I830FixOffset(pScrn, &(pI830->FrontBuffer2)); - I830FixOffset(pScrn, &(pI830->FrontBuffer)); - - for (i = 0; i < xf86_config->num_crtc; i++) { - I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; - - I830FixOffset(pScrn, &intel_crtc->cursor_mem); - I830FixOffset(pScrn, &intel_crtc->cursor_mem_argb); - } - - I830FixOffset(pScrn, &(pI830->LpRing->mem)); - I830FixOffset(pScrn, &(pI830->Scratch)); - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - I830FixOffset(pScrn, &(pI830->Scratch2)); -#ifdef I830_XV - if (pI830->XvEnabled) { - I830FixOffset(pScrn, pI830->OverlayMem); - if (pI830->LinearAlloc) - I830FixOffset(pScrn, &(pI830->LinearMem)); - } -#endif -#ifdef XF86DRI - if (pI830->directRenderingEnabled) { - I830FixOffset(pScrn, &(pI830->ContextMem)); - I830FixOffset(pScrn, &(pI830->BackBuffer)); - I830FixOffset(pScrn, &(pI830->DepthBuffer)); - if (pI830->mmModeFlags & I830_KERNEL_TEX) { - I830FixOffset(pScrn, &(pI830->TexMem)); - } - } -#endif -#ifdef I830_USE_EXA - if (pI830->useEXA) { - I830FixOffset(pScrn, &(pI830->Offscreen)); - if (IS_I965G(pI830)) - I830FixOffset(pScrn, &(pI830->EXAStateMem)); - } -#endif - return TRUE; -} - #ifdef XF86DRI -/* Tiled memory is good... really, really good... +/** + * Sets up a fence area for the hardware. * - * Need to make it less likely that we miss out on this - probably - * need to move the frontbuffer away from the 'guarenteed' alignment - * of the first memory segment, or perhaps allocate a discontigous - * framebuffer to get more alignment 'sweet spots'. + * The fences control automatic tiled address swizzling for CPU access of the + * framebuffer. */ static void -SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, - unsigned int size) +i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset, + unsigned int pitch, unsigned int size, + enum tile_format tile_format) { I830Ptr pI830 = I830PTR(pScrn); - I830RegPtr i830Reg = &pI830->ModeReg; CARD32 val; CARD32 fence_mask = 0; unsigned int fence_pitch; - DPRINTF(PFX, "SetFence: %d, 0x%08x, %d, %d kByte\n", - nr, start, pitch, size / 1024); + DPRINTF(PFX, "i830_set_fence(): %d, 0x%08x, %d, %d kByte\n", + nr, offset, pitch, size / 1024); + + assert(tile_format != TILING_NONE); + + if (IS_I965G(pI830)) { + if (nr < 0 || nr >= FENCE_NEW_NR) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "i830_set_fence(): fence %d out of range\n",nr); + return; + } + + switch (tile_format) { + case TILING_XMAJOR: + pI830->fence[nr] = (((pitch / 128) - 1) << 2) | offset | 1; + pI830->fence[nr] |= I965_FENCE_X_MAJOR; + break; + case TILING_YMAJOR: + /* YMajor can be 128B aligned but the current code dictates + * otherwise. This isn't a problem apart from memory waste. + * FIXME */ + pI830->fence[nr] = (((pitch / 128) - 1) << 2) | offset | 1; + pI830->fence[nr] |= I965_FENCE_Y_MAJOR; + break; + case TILING_NONE: + break; + } + + /* XXX Is it the next page, or the last page of the fenced region? */ + pI830->fence[FENCE_NEW_NR + nr] = offset + size; + return; + } - if (nr < 0 || nr > 7) { + if (nr < 0 || nr >= FENCE_NR) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: fence %d out of range\n",nr); + "i830_set_fence(): fence %d out of range\n",nr); return; } - i830Reg->Fence[nr] = 0; + pI830->fence[nr] = 0; if (IS_I9XX(pI830)) fence_mask = ~I915G_FENCE_START_MASK; else fence_mask = ~I830_FENCE_START_MASK; - if (start & fence_mask) { + if (offset & fence_mask) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: start (0x%08x) is not %s aligned\n", - nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); + "i830_set_fence(): %d: offset (0x%08x) is not %s aligned\n", + nr, offset, (IS_I9XX(pI830)) ? "1MB" : "512k"); return; } - if (start % size) { + if (offset % size) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", - nr, start, size / 1024); + "i830_set_fence(): %d: offset (0x%08x) is not size (%dk) " + "aligned\n", + nr, offset, size / 1024); return; } if (pitch & 127) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", + "i830_set_fence(): %d: pitch (%d) not a multiple of 128 " + "bytes\n", nr, pitch); return; } - val = (start | FENCE_X_MAJOR | FENCE_VALID); + val = offset | FENCE_VALID; + + switch (tile_format) { + case TILING_XMAJOR: + val |= FENCE_X_MAJOR; + break; + case TILING_YMAJOR: + val |= FENCE_Y_MAJOR; + break; + case TILING_NONE: + break; + } if (IS_I9XX(pI830)) { switch (size) { @@ -1552,9 +1346,9 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, case MB(8): val |= I915G_FENCE_SIZE_8M; break; - case MB(16): - val |= I915G_FENCE_SIZE_16M; - break; + case MB(16): + val |= I915G_FENCE_SIZE_16M; + break; case MB(32): val |= I915G_FENCE_SIZE_32M; break; @@ -1562,8 +1356,8 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, val |= I915G_FENCE_SIZE_64M; break; default: - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: illegal size (%d kByte)\n", + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "i830_set_fence(): %d: illegal size (%d kByte)\n", nr, size / 1024); return; } @@ -1594,8 +1388,8 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, val |= FENCE_SIZE_64M; break; default: - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: illegal size (%d kByte)\n", + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "i830_set_fence(): %d: illegal size (%d kByte)\n", nr, size / 1024); return; } @@ -1620,8 +1414,8 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, val |= FENCE_PITCH_8; break; case 16: - val |= FENCE_PITCH_16; - break; + val |= FENCE_PITCH_16; + break; case 32: val |= FENCE_PITCH_32; break; @@ -1629,352 +1423,82 @@ SetFence(ScrnInfoPtr pScrn, int nr, unsigned int start, unsigned int pitch, val |= FENCE_PITCH_64; break; default: - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "SetFence: %d: illegal pitch (%d)\n", nr, pitch); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "i830_set_fence(): %d: illegal pitch (%d)\n", nr, pitch); return; } - i830Reg->Fence[nr] = val; + pI830->fence[nr] = val; } - -static Bool -MakeTiles(ScrnInfoPtr pScrn, I830MemRange *pMem, unsigned int fence) -{ - I830Ptr pI830 = I830PTR(pScrn); - int pitch, ntiles, i; - -#if 0 - /* Hack to "improve" the alignment of the front buffer. */ - while (!(pMem->Start & ~pMem->Alignment) && pMem->Alignment < 0x00400000 ) - pMem->Alignment <<= 1; #endif - if (tileGeneration != serverGeneration) { - tileGeneration = serverGeneration; - nextTile = 0; - } - - pitch = pScrn->displayWidth * pI830->cpp; - - if (IS_I965G(pI830)) { - I830RegPtr i830Reg = &pI830->ModeReg; - - switch (fence) { - case FENCE_XMAJOR: - i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | - pMem->Start | 1; - break; - case FENCE_YMAJOR: - /* YMajor can be 128B aligned but the current code dictates - * otherwise. This isn't a problem apart from memory waste. - * FIXME */ - i830Reg->Fence[nextTile] = (((pitch / 128) - 1) << 2) | - pMem->Start | 1; - i830Reg->Fence[nextTile] |= (1<<1); - break; - default: - case FENCE_LINEAR: - break; - } - - i830Reg->Fence[nextTile+FENCE_NEW_NR] = pMem->End; - nextTile++; - return TRUE; - } - - /* - * Simply try to break the region up into at most four pieces of size - * equal to the alignment. - */ - ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; - if (ntiles >= 4) { - return FALSE; - } - - for (i = 0; i < ntiles; i++, nextTile++) { - SetFence(pScrn, nextTile, pMem->Start + i * pMem->Alignment, - pitch, pMem->Alignment); - } - return TRUE; -} - -void -I830SetupMemoryTiling(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - int i; - - /* Clear out */ - if (IS_I965G(pI830)) { - for (i = 0; i < FENCE_NEW_NR*2; i++) - pI830->ModeReg.Fence[i] = 0; - } else { - for (i = 0; i < 8; i++) - pI830->ModeReg.Fence[i] = 0; - } - - nextTile = 0; - tileGeneration = -1; - - /* We currently only attempt to tile the back and depth buffers. */ - if (!pI830->directRenderingEnabled) - return; - - if (!IsTileable(pScrn, pScrn->displayWidth * pI830->cpp)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "I830SetupMemoryTiling: Not tileable 0x%x\n", - pScrn->displayWidth * pI830->cpp); - pI830->allowPageFlip = FALSE; - return; - } - - pI830->front_tiled = FENCE_LINEAR; - pI830->back_tiled = FENCE_LINEAR; - pI830->depth_tiled = FENCE_LINEAR; - - if (pI830->allowPageFlip) { - if (pI830->allowPageFlip && pI830->FrontBuffer.Alignment >= KB(512)) { - if (MakeTiles(pScrn, &(pI830->FrontBuffer), FENCE_XMAJOR)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Activating tiled memory for the front buffer\n"); - pI830->front_tiled = FENCE_XMAJOR; - } else { - pI830->allowPageFlip = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MakeTiles failed for the front buffer\n"); - } - } else { - pI830->allowPageFlip = FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Alignment bad for the front buffer\n"); - } - } - - /* - * We tried to get the best alignment during the allocation. Check - * the alignment values to tell. If well-aligned allocations were - * successful, the address range reserved is a multiple of the align - * value. - */ - if (pI830->BackBuffer.Alignment >= KB(512)) { - if (MakeTiles(pScrn, &(pI830->BackBuffer), FENCE_XMAJOR)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Activating tiled memory for the back buffer.\n"); - pI830->back_tiled = FENCE_XMAJOR; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MakeTiles failed for the back buffer.\n"); - pI830->allowPageFlip = FALSE; - } - } - - if (pI830->DepthBuffer.Alignment >= KB(512)) { - if (MakeTiles(pScrn, &(pI830->DepthBuffer), FENCE_YMAJOR)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Activating tiled memory for the depth buffer.\n"); - pI830->depth_tiled = FENCE_YMAJOR; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "MakeTiles failed for the depth buffer.\n"); - } - } -} -#endif /* XF86DRI */ - -static Bool -BindMemRange(ScrnInfoPtr pScrn, I830MemRange *mem) -{ - if (!mem) - return FALSE; - - if (mem->Key == -1) - return TRUE; - - return xf86BindGARTMemory(pScrn->scrnIndex, mem->Key, mem->Offset); -} - +/** + * Called at EnterVT to grab the AGP GART and bind our allocations. + * + * In zaphod mode, this will walk the list trying to bind twice, since each + * pI830 points to the same allocation list, but the bind_memory will just + * no-op then. + */ Bool -I830BindAGPMemory(ScrnInfoPtr pScrn) +i830_bind_all_memory(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - DPRINTF(PFX, - "I830BindAGPMemory: StolenOnly is %s, pI830->GttBound is %s\n", - BOOLTOSTRING(pI830->StolenOnly), BOOLTOSTRING(pI830->GttBound)); - - if (pI830->StolenOnly == TRUE) + if (pI830->StolenOnly == TRUE || pI830->memory_list == NULL) return TRUE; - if (xf86AgpGARTSupported() && !pI830->GttBound) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; + if (xf86AgpGARTSupported() && !pI830->gtt_acquired) { + i830_memory *mem; if (!xf86AcquireGART(pScrn->scrnIndex)) return FALSE; -#if REMAP_RESERVED - /* Rebind the pre-allocated region. */ - BindMemRange(pScrn, &(pI830->Dummy)); -#endif - - if (!BindMemRange(pScrn, &(pI830->StolenPool.Allocated))) - return FALSE; - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - if (!BindMemRange(pScrn, &(pI830->FrontBuffer2))) - return FALSE; - if (!BindMemRange(pScrn, &(pI830->FrontBuffer))) - return FALSE; - - for (i = 0; i < xf86_config->num_crtc; i++) { - I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; + pI830->gtt_acquired = TRUE; - if (!BindMemRange(pScrn, &intel_crtc->cursor_mem)) - return FALSE; - if (!BindMemRange(pScrn, &intel_crtc->cursor_mem_argb)) - return FALSE; - } - if (!BindMemRange(pScrn, &(pI830->LpRing->mem))) - return FALSE; - if (!BindMemRange(pScrn, &(pI830->Scratch))) - return FALSE; - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - if (!BindMemRange(pScrn, &(pI830->Scratch2))) - return FALSE; -#ifdef I830_XV - if (pI830->XvEnabled) { - if (!BindMemRange(pScrn, pI830->OverlayMem)) - return FALSE; - if (pI830->LinearAlloc) - if (!BindMemRange(pScrn, &(pI830->LinearMem))) - return FALSE; - } -#endif -#ifdef XF86DRI - if (pI830->directRenderingEnabled) { - if (!BindMemRange(pScrn, &(pI830->ContextMem))) - return FALSE; - if (!BindMemRange(pScrn, &(pI830->BackBuffer))) - return FALSE; - if (!BindMemRange(pScrn, &(pI830->DepthBuffer))) - return FALSE; - if ((pI830->mmModeFlags & I830_KERNEL_TEX) && - !BindMemRange(pScrn, &(pI830->TexMem))) - return FALSE; - } -#endif -#ifdef I830_USE_EXA - if (pI830->useEXA) { - if (!BindMemRange(pScrn, &(pI830->Offscreen))) - return FALSE; - if (IS_I965G(pI830) && !BindMemRange(pScrn, &(pI830->EXAStateMem))) - return FALSE; + for (mem = pI830->memory_list->next; mem->next != NULL; + mem = mem->next) + { + if (!i830_bind_memory(pScrn, mem)) { + /* This shouldn't happen */ + FatalError("Couldn't bind memory for %s\n", mem->name); + } } -#endif - pI830->GttBound = 1; } return TRUE; } -static Bool -UnbindMemRange(ScrnInfoPtr pScrn, I830MemRange *mem) -{ - if (!mem) - return FALSE; - - if (mem->Key == -1) - return TRUE; - - return xf86UnbindGARTMemory(pScrn->scrnIndex, mem->Key); -} - - +/** Called at LeaveVT, to unbind all of our AGP allocations. */ Bool -I830UnbindAGPMemory(ScrnInfoPtr pScrn) +i830_unbind_all_memory(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - DPRINTF(PFX, - "I830UnbindAGPMemory: StolenOnly is %s, pI830->GttBound is %s\n", - BOOLTOSTRING(pI830->StolenOnly), BOOLTOSTRING(pI830->GttBound)); - if (pI830->StolenOnly == TRUE) return TRUE; - if (xf86AgpGARTSupported() && pI830->GttBound) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; + if (xf86AgpGARTSupported() && pI830->gtt_acquired) { + i830_memory *mem; -#if REMAP_RESERVED - /* "unbind" the pre-allocated region. */ - UnbindMemRange(pScrn, &(pI830->Dummy)); -#endif - - if (!UnbindMemRange(pScrn, &(pI830->StolenPool.Allocated))) - return FALSE; - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer2))) - return FALSE; - if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer))) - return FALSE; - - for (i = 0; i < xf86_config->num_crtc; i++) { - I830CrtcPrivatePtr intel_crtc = - xf86_config->crtc[i]->driver_private; - - if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem)) - return FALSE; - if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem_argb)) - return FALSE; + for (mem = pI830->memory_list->next; mem->next != NULL; + mem = mem->next) + { + i830_unbind_memory(pScrn, mem); } - if (!UnbindMemRange(pScrn, &(pI830->LpRing->mem))) - return FALSE; - if (!UnbindMemRange(pScrn, &(pI830->Scratch))) - return FALSE; - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) - if (!UnbindMemRange(pScrn, &(pI830->Scratch2))) - return FALSE; -#ifdef I830_XV - if (pI830->XvEnabled) { - if (!UnbindMemRange(pScrn, pI830->OverlayMem)) - return FALSE; - if (pI830->LinearAlloc) - if (!UnbindMemRange(pScrn, &(pI830->LinearMem))) - return FALSE; - } -#endif -#ifdef XF86DRI - if (pI830->directRenderingEnabled) { - if (!UnbindMemRange(pScrn, &(pI830->ContextMem))) - return FALSE; - if (!UnbindMemRange(pScrn, &(pI830->BackBuffer))) - return FALSE; - if (!UnbindMemRange(pScrn, &(pI830->DepthBuffer))) - return FALSE; - if ((pI830->mmModeFlags & I830_KERNEL_TEX) && - !UnbindMemRange(pScrn, &(pI830->TexMem))) - return FALSE; - } -#endif -#ifdef I830_USE_EXA - if (pI830->useEXA) { - if (!UnbindMemRange(pScrn, &(pI830->Offscreen))) - return FALSE; - if (IS_I965G(pI830) && !UnbindMemRange(pScrn, - &(pI830->EXAStateMem))) - return FALSE; - } -#endif + pI830->gtt_acquired = FALSE; + if (!xf86ReleaseGART(pScrn->scrnIndex)) return FALSE; - - pI830->GttBound = 0; } return TRUE; } +/** + * Returns the amount of system memory that could potentially be allocated + * from AGP, in kB. + */ long I830CheckAvailableMemory(ScrnInfoPtr pScrn) { diff --git a/src/i830_video.c b/src/i830_video.c index 22f5bee4..92f094fa 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -184,9 +184,9 @@ void exaMoveInPixmap (PixmapPtr pPixmap); OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_CONTINUE); \ } \ if (IS_I965G(pI830)) \ - OUT_RING(pI830->OverlayMem->Start | OFC_UPDATE); \ + OUT_RING(pI830->overlay_regs->offset | OFC_UPDATE); \ else \ - OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \ + OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE); \ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \ OUT_RING(MI_NOOP); \ ADVANCE_LP_RING(); \ @@ -202,9 +202,9 @@ void exaMoveInPixmap (PixmapPtr pPixmap); OUT_RING(MI_NOOP); \ OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_FLIP_OFF); \ if (IS_I965G(pI830)) \ - OUT_RING(pI830->OverlayMem->Start | OFC_UPDATE); \ + OUT_RING(pI830->overlay_regs->offset | OFC_UPDATE); \ else \ - OUT_RING(pI830->OverlayMem->Physical | OFC_UPDATE); \ + OUT_RING(pI830->overlay_regs->bus_addr | OFC_UPDATE); \ OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); \ OUT_RING(MI_NOOP); \ ADVANCE_LP_RING(); \ @@ -496,10 +496,10 @@ I830ResetVideo(ScrnInfoPtr pScrn) I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr; I830OverlayRegPtr overlay = - (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); + (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset); OVERLAY_DEBUG("I830ResetVideo: base: %p, offset: 0x%lx, obase: %p\n", - pI830->FbBase, pI830->OverlayMem->Start, overlay); + pI830->FbBase, pI830->overlay_regs->offset, overlay); /* * Default to maximum image size in YV12 */ @@ -926,7 +926,7 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv = (I830PortPrivPtr) data; I830Ptr pI830 = I830PTR(pScrn); I830OverlayRegPtr overlay = - (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); + (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset); if (pPriv->textured) { /* XXX: Currently the brightness/saturation attributes aren't hooked up. @@ -1553,7 +1553,7 @@ I830DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr; I830OverlayRegPtr overlay = - (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); + (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset); unsigned int swidth; unsigned int mask, shift, offsety, offsetu; int tmp; @@ -2076,7 +2076,8 @@ I830AllocateMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear, int size, /* Converts an offset from XAA's linear allocator to an offset from the * start of fb. */ -#define XAA_OFFSET_TO_OFFSET(x) (pI830->FrontBuffer.Start + (x * pI830->cpp)) +#define XAA_OFFSET_TO_OFFSET(x) \ + (pI830->front_buffer->offset + (x * pI830->cpp)) /* The XFree86 linear allocator operates in units of screen pixels, * sadly. @@ -2160,7 +2161,7 @@ I830PutImage(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv = (I830PortPrivPtr) data; ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; I830OverlayRegPtr overlay = - (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); + (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset); PixmapPtr pPixmap; INT32 x1, x2, y1, y2; int srcPitch, srcPitch2 = 0, dstPitch, destId; @@ -2700,7 +2701,7 @@ I830DisplaySurface(XF86SurfacePtr surface, I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pI830Priv = GET_PORT_PRIVATE(pScrn); I830OverlayRegPtr overlay = - (I830OverlayRegPtr) (pI830->FbBase + pI830->OverlayMem->Start); + (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset); INT32 x1, y1, x2, y2; INT32 loops = 0; BoxRec dstBox; diff --git a/src/i830_xaa.c b/src/i830_xaa.c index 5ef5d3c4..f0951387 100644 --- a/src/i830_xaa.c +++ b/src/i830_xaa.c @@ -162,20 +162,20 @@ I830XAAInit(ScreenPtr pScreen) /* On the primary screen */ if (pI830->init == 0) { - if (pI830->Scratch.Size != 0) { + if (pI830->xaa_scratch->size != 0) { width = ((pScrn->displayWidth + 31) & ~31) / 8; - nr_buffers = pI830->Scratch.Size / width; - ptr = pI830->FbBase + pI830->Scratch.Start; + nr_buffers = pI830->xaa_scratch->size / width; + ptr = pI830->FbBase + pI830->xaa_scratch->offset; } } else { /* On the secondary screen */ I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - if (pI8301->Scratch2.Size != 0) { + if (pI8301->xaa_scratch_2->size != 0) { width = ((pScrn->displayWidth + 31) & ~31) / 8; - nr_buffers = pI8301->Scratch2.Size / width; + nr_buffers = pI8301->xaa_scratch_2->size / width; /* We have to use the primary screen's FbBase, as that's where - * we allocated Scratch2, so we get the correct pointer */ - ptr = pI8301->FbBase + pI8301->Scratch2.Start; + * we allocated xaa_scratch_2, so we get the correct pointer */ + ptr = pI8301->FbBase + pI8301->xaa_scratch_2->offset; } } @@ -279,11 +279,15 @@ CheckTiling(ScrnInfoPtr pScrn) if (IS_I965G(pI830)) { if (pI830->bufferOffset == pScrn->fbOffset && pI830->front_tiled == FENCE_XMAJOR) tiled = 1; - if (pI830->bufferOffset == pI830->BackBuffer.Start && pI830->back_tiled == FENCE_XMAJOR) + if (pI830->bufferOffset == pI830->back_buffer->offset && + pI830->back_tiled == FENCE_XMAJOR) { tiled = 1; + } /* not really supported as it's always YMajor tiled */ - if (pI830->bufferOffset == pI830->DepthBuffer.Start && pI830->depth_tiled == FENCE_XMAJOR) + if (pI830->bufferOffset == pI830->depth_buffer->offset && + pI830->depth_tiled == FENCE_XMAJOR) { tiled = 1; + } } return tiled; @@ -600,7 +604,7 @@ I830SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); /* We have to use the primary screen's FbBase, as that's where - * we allocated Scratch2, so we get the correct pointer */ + * we allocated xaa_scratch_2, so we get the correct pointer */ pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] - pI8301->FbBase); } @@ -700,7 +704,7 @@ I830SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); /* We have to use the primary screen's FbBase, as that's where - * we allocated Scratch2, so we get the correct pointer */ + * we allocated xaa_scratch_2, so we get the correct pointer */ pI830->BR[12] = (pI830->AccelInfoRec->ScanlineColorExpandBuffers[0] - pI8301->FbBase); } diff --git a/src/i965_render.c b/src/i965_render.c index 5c3f61d6..78f1146c 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -501,9 +501,9 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, next_offset = default_color_offset + sizeof(*default_color_state); total_state_size = next_offset; - assert(total_state_size < EXA_LINEAR_EXTRA); + assert(total_state_size < pI830->exa_965_state->size); - state_base_offset = pI830->EXAStateMem.Start; + state_base_offset = pI830->exa_965_state->offset; state_base_offset = ALIGN(state_base_offset, 64); state_base = (char *)(pI830->FbBase + state_base_offset); -- cgit v1.2.3 From 828deff6453872ef0f9fa35c08c9f95f464b1785 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 23 Feb 2007 13:16:02 -0800 Subject: Fix fence allocations on 965. --- src/i830_memory.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/i830_memory.c b/src/i830_memory.c index 93429fba..c88261ec 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -241,6 +241,10 @@ i830_reset_allocations(ScrnInfoPtr pScrn) pI830->textures = NULL; pI830->memory_manager = NULL; pI830->LpRing->mem = NULL; + + /* Reset the fence register allocation. */ + pI830->next_fence = 0; + memset(pI830->fence, 0, sizeof(pI830->fence)); } /** @@ -1278,8 +1282,8 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset, break; } - /* XXX Is it the next page, or the last page of the fenced region? */ - pI830->fence[FENCE_NEW_NR + nr] = offset + size; + /* The end marker is the address of the last page in the allocation. */ + pI830->fence[FENCE_NEW_NR + nr] = offset + size - 4096; return; } -- cgit v1.2.3 From 54198b26e87baa180208932b97f10b27d9c0fddc Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 23 Feb 2007 14:17:07 -0800 Subject: Move memory allocation to ScreenInit rather than PreInit. This lets us do memory allocation just once rather than having several passes (as long as things succeed), avoids trouble with zaphod mode, and will let us do better automatic sizing of allocations soon. --- src/i830.h | 11 +- src/i830_display.c | 4 +- src/i830_dri.c | 10 +- src/i830_driver.c | 465 +++++++++++++++++++++++++---------------------------- src/i830_memory.c | 267 +++++++++++++----------------- 5 files changed, 342 insertions(+), 415 deletions(-) diff --git a/src/i830.h b/src/i830.h index f779978c..38d49bed 100644 --- a/src/i830.h +++ b/src/i830.h @@ -291,7 +291,6 @@ typedef struct _I830Rec { unsigned long LinearAlloc; XF86ModReqInfo shadowReq; /* to test for later libshadow */ Rotation rotation; - int displayWidth; void (*PointerMoved)(int, int, int); CreateScreenResourcesProcPtr CreateScreenResources; int *used3D; @@ -579,9 +578,10 @@ Bool i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, void i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix); void i830_reset_allocations(ScrnInfoPtr pScrn); +void i830_free_3d_memory(ScrnInfoPtr pScrn); extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn); -Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn, const int flags); -Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn, const int flags); +Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn); +Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn); extern Bool I830IsPrimary(ScrnInfoPtr pScrn); @@ -666,11 +666,6 @@ extern const int I830CopyROP[16]; #define NEED_PHYSICAL_ADDR 0x00000001 #define ALIGN_BOTH_ENDS 0x00000002 -#define ALLOC_NO_TILING 0x00001000 -#define ALLOC_INITIAL 0x00002000 - -#define ALLOCATE_DRY_RUN 0x80000000 - /* Chipset registers for VIDEO BIOS memory RW access */ #define _855_DRAM_RW_CONTROL 0x58 #define _845_DRAM_RW_CONTROL 0x90 diff --git a/src/i830_display.c b/src/i830_display.c index a09d96ae..f3beb572 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -972,7 +972,7 @@ i830_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height) unsigned long rotate_offset; int align = KB(4), size; - rotate_pitch = pI830->displayWidth * pI830->cpp; + rotate_pitch = pScrn->displayWidth * pI830->cpp; size = rotate_pitch * height; #ifdef I830_USE_EXA @@ -1034,7 +1034,7 @@ i830_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) if (!data) data = i830_crtc_shadow_allocate (crtc, width, height); - rotate_pitch = pI830->displayWidth * pI830->cpp; + rotate_pitch = pScrn->displayWidth * pI830->cpp; rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen, width, height, diff --git a/src/i830_dri.c b/src/i830_dri.c index 9e3f3786..9ea86aea 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -158,9 +158,9 @@ I830InitDma(ScrnInfoPtr pScrn) info.depth_offset = pI830->depth_buffer->offset; info.w = pScrn->virtualX; info.h = pScrn->virtualY; - info.pitch = pI830->displayWidth; - info.back_pitch = pI830->displayWidth; - info.depth_pitch = pI830->displayWidth; + info.pitch = pScrn->displayWidth; + info.back_pitch = pScrn->displayWidth; + info.depth_pitch = pScrn->displayWidth; info.cpp = pI830->cpp; if (drmCommandWrite(pI830->drmSubFD, DRM_I830_INIT, @@ -1452,7 +1452,7 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) /* Don't use front_buffer->size here as it includes the pixmap cache area * Instead, calculate the entire framebuffer. */ - sarea->front_size = pI830->displayWidth * pScrn->virtualY * pI830->cpp; + sarea->front_size = pScrn->displayWidth * pScrn->virtualY * pI830->cpp; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] init sarea width,height = %d x %d (pitch %d)\n", @@ -1477,7 +1477,7 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) sarea->rotation = 0; sarea->rotated_offset = -1; sarea->rotated_size = 0; - sarea->rotated_pitch = pI830->displayWidth; + sarea->rotated_pitch = pScrn->displayWidth; success = I830DRIMapScreenRegions(pScrn, sarea); diff --git a/src/i830_driver.c b/src/i830_driver.c index 50fe2a6d..88fee86f 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -837,8 +837,8 @@ I830ReduceMMSize(ScrnInfoPtr pScrn, unsigned long newSize, * This is called per zaphod head (so usually just once) to do initialization * before the Screen is created. * - * This code generally covers probing, module loading, option handling, - * initial memory layout measurement, card mapping, and RandR setup. + * This code generally covers probing, module loading, option handling + * card mapping, and RandR setup. */ static Bool I830PreInit(ScrnInfoPtr pScrn, int flags) @@ -850,18 +850,14 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) rgb defaultWeight = { 0, 0, 0 }; EntityInfoPtr pEnt; I830EntPtr pI830Ent = NULL; - int sys_mem; int flags24; int i; char *s; pointer pVBEModule = NULL; - Bool enable, allocation_done; const char *chipname; + Bool enable; int num_pipe; int max_width, max_height; -#ifdef XF86DRI - unsigned long savedMMSize; -#endif if (pScrn->numEntities != 1) return FALSE; @@ -900,7 +896,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->SaveGeneration = -1; pI830->pEnt = pEnt; - pI830->displayWidth = 640; /* default it */ + pScrn->displayWidth = 640; /* default it */ if (pI830->pEnt->location.type != BUS_PCI) return FALSE; @@ -1293,10 +1289,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->LinearAlloc = 0; if (xf86GetOptValULong(pI830->Options, OPTION_LINEARALLOC, &(pI830->LinearAlloc))) { - if (pI830->LinearAlloc > 0) - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Allocating %luKbytes of memory\n", - pI830->LinearAlloc); - else + if (pI830->LinearAlloc < 0) pI830->LinearAlloc = 0; } @@ -1351,91 +1344,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } else pI830->checkDevices = FALSE; - pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; - pI830->stolen_size = I830DetectMemory(pScrn); - /* - * The "VideoRam" config file parameter specifies the maximum amount of - * memory that will be used/allocated. When not present, we allow the - * driver to allocate as much memory as it wishes to satisfy its - * allocations, but if agpgart support isn't available, it gets limited - * to the amount of pre-allocated ("stolen") memory. - * - * Note that in using this value for allocator initialization, we're - * limiting aperture allocation to the VideoRam option, rather than limiting - * actual memory allocation, so alignment and things will cause less than - * VideoRam to be actually used. - */ - if (!pI830->pEnt->device->videoRam) { - from = X_DEFAULT; - pScrn->videoRam = pI830->FbMapSize / KB(1); - } else { - from = X_CONFIG; - pScrn->videoRam = pI830->pEnt->device->videoRam; - } - - sys_mem = I830CheckAvailableMemory(pScrn); - if (sys_mem == -1) { - if (pScrn->videoRam > pI830->stolen_size / KB(1)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "/dev/agpgart is either not available, or no memory " - "is available\nfor allocation. " - "Using pre-allocated memory only.\n"); - pScrn->videoRam = pI830->stolen_size / KB(1); - } - pI830->StolenOnly = TRUE; - } else { - if (sys_mem + (pI830->stolen_size / 1024) < pScrn->videoRam) { - pScrn->videoRam = sys_mem + (pI830->stolen_size / 1024); - from = X_PROBED; - if (sys_mem + (pI830->stolen_size / 1024) < - pI830->pEnt->device->videoRam) - { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRAM reduced to %d kByte " - "(limited to available sysmem)\n", pScrn->videoRam); - } - } - } - - if (pScrn->videoRam > pI830->FbMapSize / 1024) { - pScrn->videoRam = pI830->FbMapSize / 1024; - if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRam reduced to %d kByte (limited to aperture " - "size)\n", - pScrn->videoRam); - } - } - - /* Make sure it's on a page boundary */ - if (pScrn->videoRam & 3) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VideoRam reduced to %d KB " - "(page aligned - was %d KB)\n", - pScrn->videoRam & ~3, pScrn->videoRam); - pScrn->videoRam &= ~3; - } - - if (!i830_allocator_init(pScrn, 0, pScrn->videoRam * KB(1))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't initialize video memory allocator\n"); - PreInitCleanup(pScrn); - return FALSE; - } - - xf86DrvMsg(pScrn->scrnIndex, - pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT, - "VideoRam: %d KB\n", pScrn->videoRam); - - if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES, - &(pI830->CacheLines))) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n", - pI830->CacheLines); - } else { - pI830->CacheLines = -1; - } - pI830->XvDisabled = !xf86ReturnOptValBool(pI830->Options, OPTION_XVIDEO, TRUE); @@ -1537,137 +1447,11 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } pScrn->currentMode = pScrn->modes; - pI830->disableTiling = FALSE; - -#if defined(XF86DRI) - /* - * If DRI is potentially usable, check if there is enough memory available - * for it, and if there's also enough to allow tiling to be enabled. - */ - - if (!I830CheckDRIAvailable(pScrn)) { - pI830->directRenderingDisabled = TRUE; - pI830->mmSize = 0; - } - - if (I830IsPrimary(pScrn) && !pI830->directRenderingDisabled) { - int savedDisplayWidth = pScrn->displayWidth; - Bool tiled = FALSE; - -#ifdef I830_XV - /* - * Set this so that the overlay allocation is factored in when - * appropriate. - */ - pI830->XvEnabled = !pI830->XvDisabled; -#endif - - if (IS_I965G(pI830)) { - int tile_pixels = 512 / pI830->cpp; - pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) & - ~(tile_pixels - 1); - tiled = TRUE; - } else { - /* Good pitches to allow tiling. Don't care about pitches < 1024 - * pixels. - */ - static const int pitches[] = { - 1024, - 2048, - 4096, - 8192, - 0 - }; - - for (i = 0; pitches[i] != 0; i++) { - if (pitches[i] >= pScrn->displayWidth) { - pScrn->displayWidth = pitches[i]; - tiled = TRUE; - break; - } - } - } - - allocation_done = FALSE; - /* - * If the displayWidth is a tilable pitch, test if there's enough - * memory available to enable tiling. - */ - savedMMSize = pI830->mmSize; - if (tiled) { -retry_dryrun: - i830_reset_allocations(pScrn); - if (!i830_allocate_2d_memory(pScrn, - ALLOCATE_DRY_RUN | ALLOC_INITIAL) || - !i830_allocate_3d_memory(pScrn, ALLOCATE_DRY_RUN)) - { - /* Failure to set up allocations, so try reducing the DRI memory - * manager's size if we haven't yet. - */ - if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) { - I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE, - "to make room for tiling."); - goto retry_dryrun; - } - /* Otherwise, disable tiling. */ - pScrn->displayWidth = savedDisplayWidth; - pI830->allowPageFlip = FALSE; - } else if (pScrn->displayWidth != savedDisplayWidth) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Increasing the scanline pitch to allow tiling mode " - "(%d -> %d).\n", - savedDisplayWidth, pScrn->displayWidth); - allocation_done = TRUE; - } - } - if (!allocation_done) { - /* - * Tiling can't be enabled. Check if there's enough memory for DRI - * without tiling. - */ - pI830->mmSize = savedMMSize; - pI830->disableTiling = TRUE; -retry_dryrun2: - i830_reset_allocations(pScrn); - if (!i830_allocate_2d_memory(pScrn, - ALLOCATE_DRY_RUN | ALLOC_INITIAL) || - !i830_allocate_3d_memory(pScrn, ALLOCATE_DRY_RUN)) - { - /* Failure to set up allocations, so try reducing the DRI memory - * manager's size if we haven't yet. - */ - if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) { - I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE, - "to save AGP aperture space for video " - "memory."); - goto retry_dryrun2; - } - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Not enough video memory. Disabling DRI."); - pI830->mmSize = 0; - pI830->directRenderingDisabled = TRUE; - } else { - allocation_done = TRUE; - } - } - } else -#endif - pI830->disableTiling = TRUE; /* no DRI - so disableTiling */ - - if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Cannot support DRI with frame buffer width > 2048.\n"); - pI830->disableTiling = TRUE; - pI830->directRenderingDisabled = TRUE; - } - if (!IS_I965G(pI830) && pScrn->virtualY > 2048) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support > 2048 vertical lines. disabling acceleration.\n"); pI830->noAccel = TRUE; } - pI830->displayWidth = pScrn->displayWidth; - /* Don't need MMIO access anymore. */ if (pI830->swfSaved) { OUTREG(SWF0, pI830->saveSWF0); @@ -2372,15 +2156,228 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) I830Ptr pI830; VisualPtr visual; I830Ptr pI8301 = NULL; + unsigned long sys_mem; + int i; + Bool allocation_done; + MessageType from; #ifdef XF86DRI Bool driDisabled; + unsigned long savedMMSize; #endif pScrn = xf86Screens[pScreen->myNum]; pI830 = I830PTR(pScrn); hwp = VGAHWPTR(pScrn); - pScrn->displayWidth = pI830->displayWidth; + pScrn->displayWidth = (pScrn->virtualX + 63) & ~63; + + /* + * The "VideoRam" config file parameter specifies the maximum amount of + * memory that will be used/allocated. When not present, we allow the + * driver to allocate as much memory as it wishes to satisfy its + * allocations, but if agpgart support isn't available, it gets limited + * to the amount of pre-allocated ("stolen") memory. + * + * Note that in using this value for allocator initialization, we're + * limiting aperture allocation to the VideoRam option, rather than limiting + * actual memory allocation, so alignment and things will cause less than + * VideoRam to be actually used. + */ + if (pI830->pEnt->device->videoRam == 0) { + from = X_DEFAULT; + pScrn->videoRam = pI830->FbMapSize / KB(1); + } else { + from = X_CONFIG; + pScrn->videoRam = pI830->pEnt->device->videoRam; + } + + /* Limit videoRam to how much we might be able to allocate from AGP */ + sys_mem = I830CheckAvailableMemory(pScrn); + if (sys_mem == -1) { + if (pScrn->videoRam > pI830->stolen_size / KB(1)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "/dev/agpgart is either not available, or no memory " + "is available\nfor allocation. " + "Using pre-allocated memory only.\n"); + pScrn->videoRam = pI830->stolen_size / KB(1); + } + pI830->StolenOnly = TRUE; + } else { + if (sys_mem + (pI830->stolen_size / 1024) < pScrn->videoRam) { + pScrn->videoRam = sys_mem + (pI830->stolen_size / 1024); + from = X_PROBED; + if (sys_mem + (pI830->stolen_size / 1024) < + pI830->pEnt->device->videoRam) + { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VideoRAM reduced to %d kByte " + "(limited to available sysmem)\n", pScrn->videoRam); + } + } + } + + /* Limit video RAM to the actual aperture size */ + if (pScrn->videoRam > pI830->FbMapSize / 1024) { + pScrn->videoRam = pI830->FbMapSize / 1024; + if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "VideoRam reduced to %d kByte (limited to aperture " + "size)\n", + pScrn->videoRam); + } + } + + /* Make sure it's on a page boundary */ + if (pScrn->videoRam & 3) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VideoRam reduced to %d KB " + "(page aligned - was %d KB)\n", + pScrn->videoRam & ~3, pScrn->videoRam); + pScrn->videoRam &= ~3; + } + + /* Set up our video memory allocator for the chosen videoRam */ + if (!i830_allocator_init(pScrn, 0, pScrn->videoRam * KB(1))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't initialize video memory allocator\n"); + PreInitCleanup(pScrn); + return FALSE; + } + + xf86DrvMsg(pScrn->scrnIndex, + pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT, + "VideoRam: %d KB\n", pScrn->videoRam); + + if (xf86GetOptValInteger(pI830->Options, OPTION_CACHE_LINES, + &(pI830->CacheLines))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Requested %d cache lines\n", + pI830->CacheLines); + } else { + pI830->CacheLines = -1; + } + + pI830->disableTiling = FALSE; + +#if defined(XF86DRI) + /* + * If DRI is potentially usable, check if there is enough memory available + * for it, and if there's also enough to allow tiling to be enabled. + */ + + if (!I830CheckDRIAvailable(pScrn)) { + pI830->directRenderingDisabled = TRUE; + pI830->mmSize = 0; + } + + if (I830IsPrimary(pScrn) && !pI830->directRenderingDisabled) { + int savedDisplayWidth = pScrn->displayWidth; + Bool tiled = FALSE; + +#ifdef I830_XV + /* + * Set this so that the overlay allocation is factored in when + * appropriate. + */ + pI830->XvEnabled = !pI830->XvDisabled; +#endif + + if (IS_I965G(pI830)) { + int tile_pixels = 512 / pI830->cpp; + pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) & + ~(tile_pixels - 1); + tiled = TRUE; + } else { + /* Good pitches to allow tiling. Don't care about pitches < 1024 + * pixels. + */ + static const int pitches[] = { + 1024, + 2048, + 4096, + 8192, + 0 + }; + + for (i = 0; pitches[i] != 0; i++) { + if (pitches[i] >= pScrn->displayWidth) { + pScrn->displayWidth = pitches[i]; + tiled = TRUE; + break; + } + } + } + + allocation_done = FALSE; + /* + * If the displayWidth is a tilable pitch, test if there's enough + * memory available to enable tiling. + */ + savedMMSize = pI830->mmSize; + if (tiled) { +retry_dryrun: + i830_reset_allocations(pScrn); + if (!i830_allocate_2d_memory(pScrn) || + !i830_allocate_3d_memory(pScrn)) + { + /* Failure to set up allocations, so try reducing the DRI memory + * manager's size if we haven't yet. + */ + if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) { + I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE, + "to make room for tiling."); + goto retry_dryrun; + } + /* Otherwise, disable tiling. */ + pScrn->displayWidth = savedDisplayWidth; + pI830->allowPageFlip = FALSE; + } else if (pScrn->displayWidth != savedDisplayWidth) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Increasing the scanline pitch to allow tiling mode " + "(%d -> %d).\n", + savedDisplayWidth, pScrn->displayWidth); + allocation_done = TRUE; + } + } + if (!allocation_done) { + /* + * Tiling can't be enabled. Check if there's enough memory for DRI + * without tiling. + */ + pI830->mmSize = savedMMSize; + pI830->disableTiling = TRUE; +retry_dryrun2: + i830_reset_allocations(pScrn); + if (!i830_allocate_2d_memory(pScrn) || + !i830_allocate_3d_memory(pScrn)) + { + /* Failure to set up allocations, so try reducing the DRI memory + * manager's size if we haven't yet. + */ + if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) { + I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE, + "to save AGP aperture space for video " + "memory."); + goto retry_dryrun2; + } + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Not enough video memory. Disabling DRI."); + pI830->mmSize = 0; + pI830->directRenderingDisabled = TRUE; + } else { + allocation_done = TRUE; + } + } + } else +#endif + pI830->disableTiling = TRUE; /* no DRI - so disableTiling */ + + if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Cannot support DRI with frame buffer width > 2048.\n"); + pI830->disableTiling = TRUE; + pI830->directRenderingDisabled = TRUE; + } + + pScrn->displayWidth = pScrn->displayWidth; #ifdef HAS_MTRR_SUPPORT { @@ -2479,13 +2476,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->XvEnabled = FALSE; #endif - if (I830IsPrimary(pScrn)) { - i830_reset_allocations(pScrn); - - if (!i830_allocate_2d_memory(pScrn, ALLOC_INITIAL)) - return FALSE; - } - if (!pI830->noAccel) { if (pI830->LpRing->mem->size == 0) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, @@ -2530,6 +2520,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DRI is disabled because it " "needs HW cursor, 2D accel and AGPGART.\n"); pI830->directRenderingEnabled = FALSE; + i830_free_3d_memory(pScrn); } } @@ -2538,26 +2529,14 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (pI830->directRenderingEnabled) pI830->directRenderingEnabled = I830DRIScreenInit(pScreen); - if (pI830->directRenderingEnabled) { - pI830->directRenderingEnabled = - i830_allocate_3d_memory(pScrn, - pI830->disableTiling ? ALLOC_NO_TILING : 0); - if (!pI830->directRenderingEnabled) - I830DRICloseScreen(pScreen); + if (!pI830->directRenderingEnabled) { + i830_free_3d_memory(pScrn); } #else pI830->directRenderingEnabled = FALSE; #endif - /* XXX: - * After the 3D allocations have been done, see if there's any free space - * that can be added to the framebuffer allocation. - */ - if (I830IsPrimary(pScrn)) { - i830_allocate_2d_memory(pScrn, 0); - } - i830_describe_allocations(pScrn, 1, ""); #ifdef XF86DRI if (pI830->directRenderingEnabled) diff --git a/src/i830_memory.c b/src/i830_memory.c index c88261ec..5603c487 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -247,6 +247,23 @@ i830_reset_allocations(ScrnInfoPtr pScrn) memset(pI830->fence, 0, sizeof(pI830->fence)); } +void +i830_free_3d_memory(ScrnInfoPtr pScrn) +{ + I830Ptr pI830 = I830PTR(pScrn); + + i830_free_memory(pScrn, pI830->logical_context); + pI830->logical_context = NULL; + i830_free_memory(pScrn, pI830->back_buffer); + pI830->back_buffer = NULL; + i830_free_memory(pScrn, pI830->depth_buffer); + pI830->depth_buffer = NULL; + i830_free_memory(pScrn, pI830->textures); + pI830->textures = NULL; + i830_free_memory(pScrn, pI830->memory_manager); + pI830->memory_manager = NULL; +} + /** * Initialize's the driver's video memory allocator to allocate in the * given range. @@ -585,10 +602,9 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) } static Bool -i830_allocate_ringbuffer(ScrnInfoPtr pScrn, int flags) +i830_allocate_ringbuffer(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); if (pI830->noAccel || pI830->LpRing->mem != NULL) return TRUE; @@ -597,10 +613,8 @@ i830_allocate_ringbuffer(ScrnInfoPtr pScrn, int flags) PRIMARY_RINGBUFFER_SIZE, GTT_PAGE_SIZE, 0); if (pI830->LpRing->mem == NULL) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate Ring Buffer space\n"); - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate Ring Buffer space\n"); return FALSE; } @@ -614,10 +628,9 @@ i830_allocate_ringbuffer(ScrnInfoPtr pScrn, int flags) * requested) */ static Bool -i830_allocate_overlay(ScrnInfoPtr pScrn, int flags) +i830_allocate_overlay(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); /* Only allocate if overlay is going to be enabled. */ if (!pI830->XvEnabled || IS_I965G(pI830)) @@ -628,11 +641,9 @@ i830_allocate_overlay(ScrnInfoPtr pScrn, int flags) OVERLAY_SIZE, GTT_PAGE_SIZE, NEED_PHYSICAL_ADDR); if (pI830->overlay_regs == NULL) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate Overlay register space.\n"); - /* This failure isn't fatal. */ - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate Overlay register space.\n"); + /* This failure isn't fatal. */ } } @@ -641,10 +652,8 @@ i830_allocate_overlay(ScrnInfoPtr pScrn, int flags) KB(pI830->LinearAlloc), GTT_PAGE_SIZE, 0); if (pI830->xaa_linear == NULL) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate linear buffer space\n"); - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate linear buffer space\n"); } } @@ -707,12 +716,9 @@ static i830_memory * i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, Bool secondary, int flags) { - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); unsigned int pitch = pScrn->displayWidth * pI830->cpp; unsigned long minspace, avail; int cacheLines, maxCacheLines; - int verbosity = dryrun ? 4 : 1; - const char *s = dryrun ? "[dryrun] " : ""; int align; long size, fb_height; char *name; @@ -770,9 +776,9 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, FbMemBox->y2 += cacheLines; - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocating at least %d scanlines for pixmap cache\n", - s, cacheLines); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Allocating %d scanlines for pixmap cache\n", + cacheLines); } else { /* For EXA, we have a separate allocation for the linear allocator * which also does the pixmap cache. @@ -786,7 +792,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, name = secondary ? "secondary front buffer" : "front buffer"; /* Attempt to allocate it tiled first if we have page flipping on. */ - if (!flags & ALLOC_NO_TILING && pI830->allowPageFlip && + if (!pI830->disableTiling && pI830->allowPageFlip && IsTileable(pScrn, pitch)) { /* XXX: probably not the case on 965 */ @@ -796,7 +802,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, align = KB(512); front_buffer = i830_allocate_memory_tiled(pScrn, name, size, pitch, align, - flags, TILING_XMAJOR); + 0, TILING_XMAJOR); pI830->front_tiled = FENCE_XMAJOR; } @@ -807,11 +813,9 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, } if (front_buffer == NULL) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " - "%sframebuffer. Is your VideoRAM set too low?\n", - secondary ? "secondary " : ""); - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " + "%sframebuffer. Is your VideoRAM set too low?\n", + secondary ? "secondary " : ""); return NULL; } @@ -819,13 +823,13 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, } static Bool -i830_allocate_cursor_buffers(xf86CrtcPtr crtc, int flags) +i830_allocate_cursor_buffers(xf86CrtcPtr crtc) { ScrnInfoPtr pScrn = crtc->scrn; I830CrtcPrivatePtr intel_crtc = crtc->driver_private; I830Ptr pI830 = I830PTR(pScrn); - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); long size; + int flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0; if (pI830->SWCursor) return FALSE; @@ -836,18 +840,14 @@ i830_allocate_cursor_buffers(xf86CrtcPtr crtc, int flags) */ size = HWCURSOR_SIZE; - if (pI830->CursorNeedsPhysical) - flags |= NEED_PHYSICAL_ADDR; if (intel_crtc->cursor_mem == NULL) { intel_crtc->cursor_mem = i830_allocate_memory(pScrn, "HW cursor", size, GTT_PAGE_SIZE, flags); if (intel_crtc->cursor_mem == NULL) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate HW cursor space.\n"); - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate HW cursor space.\n"); return FALSE; } } @@ -862,10 +862,8 @@ i830_allocate_cursor_buffers(xf86CrtcPtr crtc, int flags) GTT_PAGE_SIZE, flags); if (intel_crtc->cursor_mem_argb == NULL) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate HW (ARGB) cursor space.\n"); - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate HW (ARGB) cursor space.\n"); } } @@ -877,38 +875,32 @@ i830_allocate_cursor_buffers(xf86CrtcPtr crtc, int flags) * ring buffer, scratch memory, HW cursor. */ Bool -i830_allocate_2d_memory(ScrnInfoPtr pScrn, const int flags) +i830_allocate_2d_memory(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); unsigned int pitch = pScrn->displayWidth * pI830->cpp; long size; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); int i; - DPRINTF(PFX, "i830_allocate_2d_memory: inital is %s\n", - BOOLTOSTRING(flags & ALLOC_INITIAL)); - if (!pI830->StolenOnly && (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "AGP GART support is either not available or cannot " - "be used.\n" - "\tMake sure your kernel has agpgart support or has\n" - "\tthe agpgart module loaded.\n"); - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "AGP GART support is either not available or cannot " + "be used.\n" + "\tMake sure your kernel has agpgart support or has\n" + "\tthe agpgart module loaded.\n"); return FALSE; } /* Allocate the ring buffer first, so it ends up in stolen mem. */ - i830_allocate_ringbuffer(pScrn, flags); + i830_allocate_ringbuffer(pScrn); /* Next, allocate other fixed-size allocations we have. */ if (!pI830->SWCursor) { /* Allocate cursor memory */ for (i = 0; i < xf86_config->num_crtc; i++) { - if (!i830_allocate_cursor_buffers(xf86_config->crtc[i], flags) && + if (!i830_allocate_cursor_buffers(xf86_config->crtc[i]) && !pI830->SWCursor) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, @@ -925,7 +917,7 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn, const int flags) * space. The second head in zaphod mode will share the space. */ if (I830IsPrimary(pScrn)) - i830_allocate_overlay(pScrn, flags); + i830_allocate_overlay(pScrn); #endif #ifdef I830_USE_EXA @@ -943,12 +935,10 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn, const int flags) size = ROUND_TO_PAGE(size); pI830->exa_offscreen = i830_allocate_memory(pScrn, "exa offscreen", - size, 1, flags); + size, 1, 0); if (pI830->exa_offscreen == NULL) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " - "offscreen memory. Not enough VRAM?\n"); - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " + "offscreen memory. Not enough VRAM?\n"); return FALSE; } } @@ -956,86 +946,66 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn, const int flags) if (IS_I965G(pI830) && pI830->exa_965_state == NULL) { pI830->exa_965_state = i830_allocate_memory(pScrn, "exa G965 state buffer", - EXA_LINEAR_EXTRA, GTT_PAGE_SIZE, - flags); + EXA_LINEAR_EXTRA, GTT_PAGE_SIZE, 0); if (pI830->exa_965_state == NULL) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "G965: Failed to allocate exa state buffer " - "space.\n"); - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "G965: Failed to allocate exa state buffer " + "space.\n"); return FALSE; } } } #endif /* I830_USE_EXA */ - if (flags & ALLOC_INITIAL) { - - /* Unfortunately this doesn't run on the DRY_RUN pass because our - * second head hasn't been created yet..... */ - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { - I830EntPtr pI830Ent = pI830->entityPrivate; - I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2); + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { + I830EntPtr pI830Ent = pI830->entityPrivate; + I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2); - pI830->front_buffer_2 = - i830_allocate_framebuffer(pI830Ent->pScrn_2, pI8302, - &pI830->FbMemBox2, - TRUE, flags); - if (pI830->front_buffer_2 == NULL) - return FALSE; - } - pI830->front_buffer = - i830_allocate_framebuffer(pScrn, pI830, &pI830->FbMemBox, - FALSE, flags); - if (pI830->front_buffer == NULL) + pI830->front_buffer_2 = + i830_allocate_framebuffer(pI830Ent->pScrn_2, pI8302, + &pI830->FbMemBox2, TRUE, 0); + if (pI830->front_buffer_2 == NULL) return FALSE; } + pI830->front_buffer = + i830_allocate_framebuffer(pScrn, pI830, &pI830->FbMemBox, FALSE, 0); + if (pI830->front_buffer == NULL) + return FALSE; if (!pI830->noAccel && !pI830->useEXA) { + pI830->xaa_scratch = + i830_allocate_memory(pScrn, "xaa scratch", MAX_SCRATCH_BUFFER_SIZE, + GTT_PAGE_SIZE, 0); if (pI830->xaa_scratch == NULL) { pI830->xaa_scratch = i830_allocate_memory(pScrn, "xaa scratch", - MAX_SCRATCH_BUFFER_SIZE, GTT_PAGE_SIZE, - flags); + MIN_SCRATCH_BUFFER_SIZE, GTT_PAGE_SIZE, + 0); if (pI830->xaa_scratch == NULL) { - pI830->xaa_scratch = - i830_allocate_memory(pScrn, "xaa scratch", - MIN_SCRATCH_BUFFER_SIZE, - GTT_PAGE_SIZE, - flags); - if (pI830->xaa_scratch == NULL) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate scratch buffer " - "space\n"); - } - return FALSE; - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate scratch buffer " + "space\n"); + return FALSE; } } /* Let's allocate another scratch buffer for the second head */ /* Again, this code won't execute on the dry run pass */ - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2 && - pI830->xaa_scratch_2 == NULL) + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { pI830->xaa_scratch_2 = i830_allocate_memory(pScrn, "xaa scratch 2", MAX_SCRATCH_BUFFER_SIZE, GTT_PAGE_SIZE, - flags); + 0); if (pI830->xaa_scratch_2 == NULL) { pI830->xaa_scratch_2 = i830_allocate_memory(pScrn, "xaa scratch 2", MIN_SCRATCH_BUFFER_SIZE, - GTT_PAGE_SIZE, - flags); + GTT_PAGE_SIZE, 0); if (pI830->xaa_scratch_2 == NULL) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate secondary scratch " - "buffer space\n"); - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate secondary scratch " + "buffer space\n"); return FALSE; } } @@ -1059,12 +1029,11 @@ myLog2(unsigned int n) } static Bool -i830_allocate_backbuffer(ScrnInfoPtr pScrn, const int flags) +i830_allocate_backbuffer(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); unsigned int pitch = pScrn->displayWidth * pI830->cpp; unsigned long size; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); int height; if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) @@ -1073,13 +1042,13 @@ i830_allocate_backbuffer(ScrnInfoPtr pScrn, const int flags) height = pScrn->virtualX; /* Try to allocate on the best tile-friendly boundaries. */ - if (!(flags & ALLOC_NO_TILING) && IsTileable(pScrn, pitch)) + if (!pI830->disableTiling && IsTileable(pScrn, pitch)) { size = ROUND_TO_PAGE(pitch * ALIGN(height, 16)); pI830->back_buffer = i830_allocate_memory_tiled(pScrn, "back buffer", size, pitch, GTT_PAGE_SIZE, - flags | ALIGN_BOTH_ENDS, + ALIGN_BOTH_ENDS, TILING_XMAJOR); pI830->back_tiled = FENCE_XMAJOR; } @@ -1089,15 +1058,13 @@ i830_allocate_backbuffer(ScrnInfoPtr pScrn, const int flags) size = ROUND_TO_PAGE(pitch * height); pI830->back_buffer = i830_allocate_memory(pScrn, "back buffer", size, GTT_PAGE_SIZE, - flags | ALIGN_BOTH_ENDS); + ALIGN_BOTH_ENDS); pI830->back_tiled = FENCE_LINEAR; } if (pI830->back_buffer == NULL) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate back buffer space.\n"); - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate back buffer space.\n"); return FALSE; } @@ -1105,11 +1072,10 @@ i830_allocate_backbuffer(ScrnInfoPtr pScrn, const int flags) } static Bool -i830_allocate_depthbuffer(ScrnInfoPtr pScrn, const int flags) +i830_allocate_depthbuffer(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); unsigned long size; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); unsigned int pitch = pScrn->displayWidth * pI830->cpp; int height; @@ -1120,13 +1086,13 @@ i830_allocate_depthbuffer(ScrnInfoPtr pScrn, const int flags) height = pScrn->virtualX; /* First try allocating it tiled */ - if (!(flags & ALLOC_NO_TILING) && IsTileable(pScrn, pitch)) + if (!pI830->disableTiling && IsTileable(pScrn, pitch)) { size = ROUND_TO_PAGE(pitch * ALIGN(height, 16)); pI830->depth_buffer = i830_allocate_memory_tiled(pScrn, "depth buffer", size, pitch, - GTT_PAGE_SIZE, flags | ALIGN_BOTH_ENDS, + GTT_PAGE_SIZE, ALIGN_BOTH_ENDS, TILING_YMAJOR); pI830->depth_tiled = FENCE_YMAJOR; } @@ -1136,15 +1102,13 @@ i830_allocate_depthbuffer(ScrnInfoPtr pScrn, const int flags) size = ROUND_TO_PAGE(pitch * height); pI830->depth_buffer = i830_allocate_memory(pScrn, "depth buffer", size, GTT_PAGE_SIZE, - flags); + 0); pI830->depth_tiled = FENCE_LINEAR; } if (pI830->depth_buffer == NULL) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate depth buffer space.\n"); - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate depth buffer space.\n"); return FALSE; } @@ -1152,18 +1116,17 @@ i830_allocate_depthbuffer(ScrnInfoPtr pScrn, const int flags) } static Bool -i830_allocate_texture_memory(ScrnInfoPtr pScrn, const int flags) +i830_allocate_texture_memory(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); unsigned long size; int i; - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); if (pI830->mmModeFlags & I830_KERNEL_MM) { pI830->memory_manager = i830_allocate_aperture(pScrn, "DRI memory manager", pI830->mmSize, GTT_PAGE_SIZE, - flags | ALIGN_BOTH_ENDS); + ALIGN_BOTH_ENDS); /* XXX: try memory manager size backoff here? */ if (pI830->memory_manager == NULL) return FALSE; @@ -1172,8 +1135,6 @@ i830_allocate_texture_memory(ScrnInfoPtr pScrn, const int flags) if (pI830->mmModeFlags & I830_KERNEL_TEX) { /* XXX: auto-sizing */ size = MB(32); - if (dryrun && (size < MB(1))) - size = MB(1); i = myLog2(size / I830_NR_TEX_REGIONS); if (i < I830_LOG_MIN_TEX_REGION_SIZE) i = I830_LOG_MIN_TEX_REGION_SIZE; @@ -1182,21 +1143,17 @@ i830_allocate_texture_memory(ScrnInfoPtr pScrn, const int flags) size >>= i; size <<= i; if (size < KB(512)) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Less than 512 kBytes for texture space (real %ld" - "kBytes).\n", - size / 1024); - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Less than 512 kBytes for texture space (real %ld" + "kBytes).\n", + size / 1024); return FALSE; } pI830->textures = i830_allocate_memory(pScrn, "textures", size, - GTT_PAGE_SIZE, flags); + GTT_PAGE_SIZE, 0); if (pI830->textures == NULL) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate texture space.\n"); - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate texture space.\n"); return FALSE; } } @@ -1205,32 +1162,28 @@ i830_allocate_texture_memory(ScrnInfoPtr pScrn, const int flags) } Bool -i830_allocate_3d_memory(ScrnInfoPtr pScrn, const int flags) +i830_allocate_3d_memory(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); DPRINTF(PFX, "I830Allocate3DMemory\n"); /* Space for logical context. 32k is fine for right now. */ pI830->logical_context = i830_allocate_memory(pScrn, "logical 3D context", - KB(32), GTT_PAGE_SIZE, - flags); + KB(32), GTT_PAGE_SIZE, 0); if (pI830->logical_context == NULL) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate logical context space.\n"); - } + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate logical context space.\n"); return FALSE; } - if (!i830_allocate_backbuffer(pScrn, flags)) + if (!i830_allocate_backbuffer(pScrn)) return FALSE; - if (!i830_allocate_depthbuffer(pScrn, flags)) + if (!i830_allocate_depthbuffer(pScrn)) return FALSE; - if (!i830_allocate_texture_memory(pScrn, flags)) + if (!i830_allocate_texture_memory(pScrn)) return FALSE; return TRUE; -- cgit v1.2.3 From 7bb725dee9ef0ccdc478ed4931dc267bcb80203f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 23 Feb 2007 14:56:58 -0800 Subject: Improve logging of memory allocation passes, and clean the code up a bit. --- src/i830_driver.c | 136 +++++++++++++++++++++++++----------------------------- src/i830_memory.c | 31 +++++++------ 2 files changed, 78 insertions(+), 89 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 88fee86f..c660a354 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -812,27 +812,6 @@ i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode) pI830->writeControl(pI830, GRX, 0x18, gr18); } -#ifdef XF86DRI -static void -I830ReduceMMSize(ScrnInfoPtr pScrn, unsigned long newSize, - const char *reason) -{ - I830Ptr pI830 = I830PTR(pScrn); - - newSize = ROUND_DOWN_TO(newSize, GTT_PAGE_SIZE); - if (newSize / GTT_PAGE_SIZE > I830_MM_MINPAGES) { - pI830->mmSize = newSize / 1024; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "DRM memory manager aperture size is reduced to %d kiB\n" - "\t%s\n", pI830->mmSize, reason); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "DRM memory manager will be disabled\n\t%s\n", reason); - pI830->mmSize = 0; - } -} -#endif - /** * This is called per zaphod head (so usually just once) to do initialization * before the Screen is created. @@ -2158,7 +2137,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) I830Ptr pI8301 = NULL; unsigned long sys_mem; int i; - Bool allocation_done; + Bool allocation_done = FALSE; MessageType from; #ifdef XF86DRI Bool driDisabled; @@ -2268,7 +2247,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->mmSize = 0; } - if (I830IsPrimary(pScrn) && !pI830->directRenderingDisabled) { + if (!pI830->directRenderingDisabled) { int savedDisplayWidth = pScrn->displayWidth; Bool tiled = FALSE; @@ -2306,70 +2285,80 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } - allocation_done = FALSE; - /* - * If the displayWidth is a tilable pitch, test if there's enough - * memory available to enable tiling. + /* Attempt several rounds of allocation to get 2d and 3d memory to fit: + * + * 0: tiled, large memory manager + * 1: tiled, small memory manager + * 2: untiled, large + * 3: untiled, small */ + + pI830->disableTiling = FALSE; savedMMSize = pI830->mmSize; - if (tiled) { -retry_dryrun: - i830_reset_allocations(pScrn); - if (!i830_allocate_2d_memory(pScrn) || - !i830_allocate_3d_memory(pScrn)) - { - /* Failure to set up allocations, so try reducing the DRI memory - * manager's size if we haven't yet. - */ - if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) { - I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE, - "to make room for tiling."); - goto retry_dryrun; - } - /* Otherwise, disable tiling. */ + for (i = 0; i < 4; i++) { + if (!tiled && i < 2) + continue; + + if (i >= 2) { + /* For further allocations, disable tiling */ + pI830->disableTiling = TRUE; pScrn->displayWidth = savedDisplayWidth; pI830->allowPageFlip = FALSE; - } else if (pScrn->displayWidth != savedDisplayWidth) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Increasing the scanline pitch to allow tiling mode " - "(%d -> %d).\n", - savedDisplayWidth, pScrn->displayWidth); - allocation_done = TRUE; } - } - if (!allocation_done) { - /* - * Tiling can't be enabled. Check if there's enough memory for DRI - * without tiling. - */ - pI830->mmSize = savedMMSize; - pI830->disableTiling = TRUE; -retry_dryrun2: - i830_reset_allocations(pScrn); - if (!i830_allocate_2d_memory(pScrn) || - !i830_allocate_3d_memory(pScrn)) - { - /* Failure to set up allocations, so try reducing the DRI memory - * manager's size if we haven't yet. + + if (i & 1) { + /* For this allocation, switch to a smaller DRI memory manager + * size. */ - if (KB(pI830->mmSize) > I830_MM_MINPAGES * GTT_PAGE_SIZE) { - I830ReduceMMSize(pScrn, I830_MM_MINPAGES * GTT_PAGE_SIZE, - "to save AGP aperture space for video " - "memory."); - goto retry_dryrun2; - } - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Not enough video memory. Disabling DRI."); - pI830->mmSize = 0; - pI830->directRenderingDisabled = TRUE; + pI830->mmSize = I830_MM_MINPAGES * GTT_PAGE_SIZE; } else { + pI830->mmSize = savedMMSize; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Attempting memory allocation with %s buffers and \n" + "\t %s DRI memory manager reservation:\n", + (i & 2) ? "untiled" : "tiled", + (i & 1) ? "small" : "large"); + + if (i830_allocate_2d_memory(pScrn) && + i830_allocate_3d_memory(pScrn)) + { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Success.\n"); + if (pScrn->displayWidth != savedDisplayWidth) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Increasing the scanline pitch to allow tiling mode " + "(%d -> %d).\n", + savedDisplayWidth, pScrn->displayWidth); + } allocation_done = TRUE; + break; } + + i830_reset_allocations(pScrn); + } + + if (i == 4) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Not enough video memory. Disabling DRI.\n"); + pI830->mmSize = 0; + pI830->directRenderingDisabled = TRUE; } } else #endif pI830->disableTiling = TRUE; /* no DRI - so disableTiling */ + if (!allocation_done) { + if (!i830_allocate_2d_memory(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate video memory\n"); + return FALSE; + } + allocation_done = TRUE; + } + + i830_describe_allocations(pScrn, 1, ""); + if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support DRI with frame buffer width > 2048.\n"); @@ -2537,7 +2526,6 @@ retry_dryrun2: pI830->directRenderingEnabled = FALSE; #endif - i830_describe_allocations(pScrn, 1, ""); #ifdef XF86DRI if (pI830->directRenderingEnabled) pI830->directRenderingEnabled = I830DRIDoMappings(pScreen); diff --git a/src/i830_memory.c b/src/i830_memory.c index 5603c487..5050a7a9 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -183,6 +183,9 @@ i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem) static void i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem) { + if (mem == NULL) + return; + i830_unbind_memory(pScrn, mem); /* Disconnect from the list of allocations */ @@ -641,7 +644,7 @@ i830_allocate_overlay(ScrnInfoPtr pScrn) OVERLAY_SIZE, GTT_PAGE_SIZE, NEED_PHYSICAL_ADDR); if (pI830->overlay_regs == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate Overlay register space.\n"); /* This failure isn't fatal. */ } @@ -652,7 +655,7 @@ i830_allocate_overlay(ScrnInfoPtr pScrn) KB(pI830->LinearAlloc), GTT_PAGE_SIZE, 0); if (pI830->xaa_linear == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate linear buffer space\n"); } } @@ -937,8 +940,8 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) pI830->exa_offscreen = i830_allocate_memory(pScrn, "exa offscreen", size, 1, 0); if (pI830->exa_offscreen == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " - "offscreen memory. Not enough VRAM?\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate EXA offscreen memory."); return FALSE; } } @@ -948,9 +951,8 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) i830_allocate_memory(pScrn, "exa G965 state buffer", EXA_LINEAR_EXTRA, GTT_PAGE_SIZE, 0); if (pI830->exa_965_state == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "G965: Failed to allocate exa state buffer " - "space.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate exa state buffer for 965.\n"); return FALSE; } } @@ -982,9 +984,8 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) MIN_SCRATCH_BUFFER_SIZE, GTT_PAGE_SIZE, 0); if (pI830->xaa_scratch == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate scratch buffer " - "space\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate scratch buffer space\n"); return FALSE; } } @@ -1003,7 +1004,7 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) MIN_SCRATCH_BUFFER_SIZE, GTT_PAGE_SIZE, 0); if (pI830->xaa_scratch_2 == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate secondary scratch " "buffer space\n"); return FALSE; @@ -1063,7 +1064,7 @@ i830_allocate_backbuffer(ScrnInfoPtr pScrn) } if (pI830->back_buffer == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate back buffer space.\n"); return FALSE; } @@ -1107,7 +1108,7 @@ i830_allocate_depthbuffer(ScrnInfoPtr pScrn) } if (pI830->depth_buffer == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate depth buffer space.\n"); return FALSE; } @@ -1152,7 +1153,7 @@ i830_allocate_texture_memory(ScrnInfoPtr pScrn) pI830->textures = i830_allocate_memory(pScrn, "textures", size, GTT_PAGE_SIZE, 0); if (pI830->textures == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate texture space.\n"); return FALSE; } @@ -1172,7 +1173,7 @@ i830_allocate_3d_memory(ScrnInfoPtr pScrn) pI830->logical_context = i830_allocate_memory(pScrn, "logical 3D context", KB(32), GTT_PAGE_SIZE, 0); if (pI830->logical_context == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate logical context space.\n"); return FALSE; } -- cgit v1.2.3 From 84a7429730ddd29072d696accb9fdd8fea40731a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 23 Feb 2007 14:59:24 -0800 Subject: Always allocate logical_context, since we use it in emitting invariants. --- src/i830_memory.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/i830_memory.c b/src/i830_memory.c index 5050a7a9..74610706 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -255,8 +255,6 @@ i830_free_3d_memory(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - i830_free_memory(pScrn, pI830->logical_context); - pI830->logical_context = NULL; i830_free_memory(pScrn, pI830->back_buffer); pI830->back_buffer = NULL; i830_free_memory(pScrn, pI830->depth_buffer); @@ -915,6 +913,15 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) } } + /* Space for the X Server's 3D context. 32k is fine for right now. */ + pI830->logical_context = i830_allocate_memory(pScrn, "logical 3D context", + KB(32), GTT_PAGE_SIZE, 0); + if (pI830->logical_context == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate logical context space.\n"); + return FALSE; + } + #ifdef I830_XV /* Allocate overlay register space and optional XAA linear allocator * space. The second head in zaphod mode will share the space. @@ -1165,18 +1172,7 @@ i830_allocate_texture_memory(ScrnInfoPtr pScrn) Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn) { - I830Ptr pI830 = I830PTR(pScrn); - - DPRINTF(PFX, "I830Allocate3DMemory\n"); - - /* Space for logical context. 32k is fine for right now. */ - pI830->logical_context = i830_allocate_memory(pScrn, "logical 3D context", - KB(32), GTT_PAGE_SIZE, 0); - if (pI830->logical_context == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to allocate logical context space.\n"); - return FALSE; - } + DPRINTF(PFX, "i830_allocate_3d_memory\n"); if (!i830_allocate_backbuffer(pScrn)) return FALSE; -- cgit v1.2.3 From aeeae1b40fc012bcc01fcd2243d4993de819b7cf Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 26 Feb 2007 09:13:17 -0800 Subject: Fix a crash in startup monitor detect. --- src/i830_display.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/i830_display.c b/src/i830_display.c index f3beb572..a1660e35 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -342,7 +342,13 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y) int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE); int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); - if (crtc->rotatedData != NULL) { + if (pI830->front_buffer == NULL) { + /* During startup we may be called as part of monitor detection while + * there is no memory allocation done, so just supply a dummy base + * address. + */ + Start = 0; + } else if (crtc->rotatedData != NULL) { Start = (char *)crtc->rotatedData - (char *)pI830->FbBase; } else if (I830IsPrimary(pScrn)) { Start = pI830->front_buffer->offset; -- cgit v1.2.3 From 5732dd7221b7bb24bf21e16066f014a0c7cb6b2a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 26 Feb 2007 09:54:04 -0800 Subject: Fix some texture memory allocation issues. --- src/i830.h | 1 + src/i830_dri.c | 36 +++++++++++++++++++----------------- src/i830_driver.c | 21 +++++++++++---------- src/i830_memory.c | 4 ++-- 4 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/i830.h b/src/i830.h index 38d49bed..08d9e3ed 100644 --- a/src/i830.h +++ b/src/i830.h @@ -579,6 +579,7 @@ void i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix); void i830_reset_allocations(ScrnInfoPtr pScrn); void i830_free_3d_memory(ScrnInfoPtr pScrn); +void i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem); extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn); Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn); Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn); diff --git a/src/i830_dri.c b/src/i830_dri.c index 9ea86aea..e14880f6 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -654,21 +654,18 @@ I830DRIScreenInit(ScreenPtr pScreen) return FALSE; } pI830->drmMinor = version->version_minor; - if (!(pI830->mmModeFlags & I830_KERNEL_TEX)) { -#ifdef XF86DRI_MM - if ((version->version_major > 1) || - ((version->version_minor >= 7) && - (version->version_major == 1))) { - pI830->mmModeFlags |= I830_KERNEL_MM; - } else -#endif - { - pI830->mmModeFlags |= I830_KERNEL_TEX; - } - } else { - xf86DrvMsg(pScreen->myNum, X_INFO, - "Not enabling the DRM memory manager.\n"); - } + if (version->version_minor < 7) { + if (pI830->mmModeFlags & I830_KERNEL_MM) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "DRM version %d.%d older than required 1.7 for " + "DRM memory manager. Disabling.\n", + version->version_major, version->version_minor); + pI830->mmModeFlags &= ~I830_KERNEL_MM; + + i830_free_memory(pScrn, pI830->memory_manager); + pI830->memory_manager = NULL; + } + } drmFreeVersion(version); } } @@ -1464,8 +1461,13 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) sarea->back_size = pI830->back_buffer->size; sarea->depth_offset = pI830->depth_buffer->offset; sarea->depth_size = pI830->depth_buffer->size; - sarea->tex_offset = pI830->textures->offset; - sarea->tex_size = pI830->textures->size; + if (pI830->textures != NULL) { + sarea->tex_offset = pI830->textures->offset; + sarea->tex_size = pI830->textures->size; + } else { + sarea->tex_offset = 0; + sarea->tex_size = 0; + } sarea->log_tex_granularity = pI830->TexGranularity; sarea->pitch = pScrn->displayWidth; sarea->virtualX = pScrn->virtualX; diff --git a/src/i830_driver.c b/src/i830_driver.c index c660a354..4746c72f 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1229,8 +1229,11 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) if (!pI830->directRenderingDisabled) { Bool tmp = FALSE; - if (IS_I965G(pI830)) - pI830->mmModeFlags |= I830_KERNEL_TEX; + pI830->mmModeFlags |= I830_KERNEL_TEX; +#ifdef XF86DRI_MM + if (!IS_I965G(pI830)) + pI830->mmModeFlags |= I830_KERNEL_MM; +#endif from = X_PROBED; if (xf86GetOptValBool(pI830->Options, @@ -1242,14 +1245,12 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->mmModeFlags &= ~I830_KERNEL_TEX; } } - if (from == X_CONFIG || - (pI830->mmModeFlags & I830_KERNEL_TEX)) { - xf86DrvMsg(pScrn->scrnIndex, from, - "Will %stry to allocate texture pool " - "for old Mesa 3D driver.\n", - (pI830->mmModeFlags & I830_KERNEL_TEX) ? - "" : "not "); - } + xf86DrvMsg(pScrn->scrnIndex, from, + "Will %stry to allocate texture pool " + "for old Mesa 3D driver.\n", + (pI830->mmModeFlags & I830_KERNEL_TEX) ? + "" : "not "); + pI830->mmSize = I830_MM_MAXSIZE; from = X_INFO; if (xf86GetOptValInteger(pI830->Options, OPTION_INTELMMSIZE, diff --git a/src/i830_memory.c b/src/i830_memory.c index 74610706..3e84a900 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -180,7 +180,7 @@ i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem) } } -static void +void i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem) { if (mem == NULL) @@ -1133,7 +1133,7 @@ i830_allocate_texture_memory(ScrnInfoPtr pScrn) if (pI830->mmModeFlags & I830_KERNEL_MM) { pI830->memory_manager = i830_allocate_aperture(pScrn, "DRI memory manager", - pI830->mmSize, GTT_PAGE_SIZE, + pI830->mmSize * KB(1), GTT_PAGE_SIZE, ALIGN_BOTH_ENDS); /* XXX: try memory manager size backoff here? */ if (pI830->memory_manager == NULL) -- cgit v1.2.3 From 0bfaeaab2838184827236c5c0fcc17f06d9e1372 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 26 Feb 2007 11:11:56 -0800 Subject: Fix physical memory allocations, including description in log. --- src/i830_memory.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/i830_memory.c b/src/i830_memory.c index 3e84a900..79c1b4d2 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -344,7 +344,14 @@ i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name, alignment = GTT_PAGE_SIZE; for (scan = pI830->memory_list; scan->next != NULL; scan = scan->next) { - mem->offset = ROUND_TO(scan->end, alignment); + mem->offset = scan->end; + /* For allocations requiring physical addresses, we have to use AGP + * memory, so move the allocation up out of stolen memory. + */ + if ((flags & NEED_PHYSICAL_ADDR) && mem->offset < pI830->stolen_size) + mem->offset = pI830->stolen_size; + mem->offset = ROUND_TO(mem->offset, alignment); + mem->end = mem->offset + size; if (flags & ALIGN_BOTH_ENDS) mem->end = ROUND_TO(mem->end, alignment); @@ -381,8 +388,11 @@ i830_allocate_agp_memory(ScrnInfoPtr pScrn, i830_memory *mem, int flags) if (mem->key != -1) return TRUE; - if (mem->offset + mem->size <= pI830->stolen_size) + if (mem->offset + mem->size <= pI830->stolen_size && + !(flags & NEED_PHYSICAL_ADDR)) + { return TRUE; + } if (mem->offset < pI830->stolen_size) mem->agp_offset = pI830->stolen_size; @@ -564,7 +574,7 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) { if (mem->offset >= pI830->stolen_size && - mem->prev->offset <= pI830->stolen_size) + mem->prev->offset < pI830->stolen_size) { xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, "%s0x%08lx: end of stolen memory\n", @@ -578,7 +588,7 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) mem->size / 1024); } else { xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%s0x%08lx-0x%08lx: %s (%ld kB, %08lx physical)\n", + "%s0x%08lx-0x%08lx: %s (%ld kB, 0x%08lx physical)\n", prefix, mem->offset, mem->end - 1, mem->name, mem->size / 1024, mem->bus_addr); -- cgit v1.2.3 From 732885c08daaf17034da8f4855d0b957ec3df9d7 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 26 Feb 2007 15:04:56 -0800 Subject: Bug #9604: Align the sizes of allocations to page increments as well. Without this, the 965 DRI driver fell over when pitch * height wasn't page-size aligned. Since the allocator only allocates at page-aligned offsets anyway this shouldn't hurt us at all. --- src/i830_dri.c | 3 ++- src/i830_memory.c | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index e14880f6..f81251a5 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -1449,7 +1449,8 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) /* Don't use front_buffer->size here as it includes the pixmap cache area * Instead, calculate the entire framebuffer. */ - sarea->front_size = pScrn->displayWidth * pScrn->virtualY * pI830->cpp; + sarea->front_size = ROUND_TO_PAGE(pScrn->displayWidth * pScrn->virtualY * + pI830->cpp); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] init sarea width,height = %d x %d (pitch %d)\n", diff --git a/src/i830_memory.c b/src/i830_memory.c index 79c1b4d2..b83078a5 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -338,6 +338,8 @@ i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name, xfree(mem); return NULL; } + /* Only allocate page-sized increments. */ + size = ALIGN(size, GTT_PAGE_SIZE); mem->size = size; if (alignment < GTT_PAGE_SIZE) @@ -466,6 +468,9 @@ i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name, if (tile_format == TILING_NONE) return i830_allocate_memory(pScrn, name, size, alignment, flags); + /* Only allocate page-sized increments. */ + size = ALIGN(size, GTT_PAGE_SIZE); + /* Check for maximum tiled region size */ if (IS_I9XX(pI830)) { if (size > MB(128)) -- cgit v1.2.3 From 36bfeb890aeb17a8ee058790dd69b4e9aba644a1 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 26 Feb 2007 16:58:33 -0800 Subject: Move the initial EnterVT to after we've set up acceleration. This fixes a crash with initial rotation and EXA due to EXA not being initialized in time for the shadow pixmap setup. --- src/i830_driver.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 4746c72f..1dfd7a83 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2579,8 +2579,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } } - if (!I830EnterVT(scrnIndex, 0)) - return FALSE; if (pScrn->virtualX > pScrn->displayWidth) pScrn->displayWidth = pScrn->virtualX; @@ -2623,6 +2621,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } + if (!I830EnterVT(scrnIndex, 0)) + return FALSE; + miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); xf86SetSilkenMouse(pScreen); -- cgit v1.2.3 From 6ed28c5aa34ff1d8b99a8d4721ddac7b9cac41ed Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 26 Feb 2007 17:12:44 -0800 Subject: Fix XV issues on 965 after the allocation rework --- src/i830_driver.c | 2 +- src/i830_video.c | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 1dfd7a83..135e6fad 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2482,7 +2482,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) "needs 2D acceleration.\n"); pI830->XvEnabled = FALSE; } - if (pI830->overlay_regs == NULL) { + if (!IS_I9XX(pI830) && pI830->overlay_regs == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Disabling Xv because the overlay register buffer " "allocation failed.\n"); diff --git a/src/i830_video.c b/src/i830_video.c index 92f094fa..4c64b309 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -472,7 +472,9 @@ I830InitVideo(ScreenPtr pScreen) } /* Set up overlay video if we can do it at this depth. */ - if (!IS_I965G(pI830) && pScrn->bitsPerPixel != 8) { + if (!IS_I965G(pI830) && pScrn->bitsPerPixel != 8 && + pI830->overlay_regs != NULL) + { overlayAdaptor = I830SetupImageVideoOverlay(pScreen); if (overlayAdaptor != NULL) { adaptors[num_adaptors++] = overlayAdaptor; @@ -925,8 +927,7 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, { I830PortPrivPtr pPriv = (I830PortPrivPtr) data; I830Ptr pI830 = I830PTR(pScrn); - I830OverlayRegPtr overlay = - (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset); + I830OverlayRegPtr overlay; if (pPriv->textured) { /* XXX: Currently the brightness/saturation attributes aren't hooked up. @@ -936,6 +937,8 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, return Success; } + overlay = (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset); + if (attribute == xvBrightness) { if ((value < -128) || (value > 127)) return BadValue; @@ -2160,8 +2163,7 @@ I830PutImage(ScrnInfoPtr pScrn, I830Ptr pI830 = I830PTR(pScrn); I830PortPrivPtr pPriv = (I830PortPrivPtr) data; ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; - I830OverlayRegPtr overlay = - (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset); + I830OverlayRegPtr overlay; PixmapPtr pPixmap; INT32 x1, x2, y1, y2; int srcPitch, srcPitch2 = 0, dstPitch, destId; @@ -2170,6 +2172,11 @@ I830PutImage(ScrnInfoPtr pScrn, int pitchAlignMask; int extraLinear; + if (pPriv->textured) + overlay = NULL; + else + (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset); + #if 0 ErrorF("I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n" "width %d, height %d\n", src_x, src_y, src_w, src_h, drw_x, drw_y, -- cgit v1.2.3 From 5b765065c0bdf671b60d8a2fe512f6307f753eab Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 26 Feb 2007 17:25:57 -0800 Subject: Consolidate shared structure allocation to the start of ScreenInit. Previously, the structures would get allocated unnecessarily once, and wouldn't get reallocated in time at server regen. --- src/i830_driver.c | 77 ++++++++++++++++++------------------------------------- 1 file changed, 25 insertions(+), 52 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 135e6fad..5ba96a53 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -752,15 +752,6 @@ PreInitCleanup(ScrnInfoPtr pScrn) if (I830IsPrimary(pScrn)) { if (pI830->entityPrivate) pI830->entityPrivate->pScrn_1 = NULL; - if (pI830->LpRing) - xfree(pI830->LpRing); - pI830->LpRing = NULL; - if (pI830->overlayOn) - xfree(pI830->overlayOn); - pI830->overlayOn = NULL; - if (pI830->used3D) - xfree(pI830->used3D); - pI830->used3D = NULL; } else { if (pI830->entityPrivate) pI830->entityPrivate->pScrn_2 = NULL; @@ -1370,22 +1361,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } } - /* Alloc our pointers for the primary head */ - if (I830IsPrimary(pScrn)) { - pI830->LpRing = xcalloc(1, sizeof(I830RingBuffer)); - pI830->overlayOn = xalloc(sizeof(Bool)); - pI830->used3D = xalloc(sizeof(int)); - if (!pI830->LpRing || !pI830->overlayOn || !pI830->used3D) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Could not allocate primary data structures.\n"); - PreInitCleanup(pScrn); - return FALSE; - } - *pI830->overlayOn = FALSE; - if (pI830->entityPrivate) - pI830->entityPrivate->XvInUse = -1; - } - /* Check if the HW cursor needs physical address. */ if (IS_MOBILE(pI830) || IS_I9XX(pI830)) pI830->CursorNeedsPhysical = TRUE; @@ -2237,6 +2212,31 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->disableTiling = FALSE; + if (I830IsPrimary(pScrn)) { + /* Alloc our pointers for the primary head */ + if (!pI830->LpRing) + pI830->LpRing = xcalloc(1, sizeof(I830RingBuffer)); + if (!pI830->overlayOn) + pI830->overlayOn = xalloc(sizeof(Bool)); + if (!pI830->used3D) + pI830->used3D = xalloc(sizeof(int)); + if (!pI830->LpRing || !pI830->overlayOn || !pI830->used3D) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Could not allocate primary data structures.\n"); + return FALSE; + } + *pI830->overlayOn = FALSE; + if (pI830->entityPrivate) + pI830->entityPrivate->XvInUse = -1; + } else { + /* Make our second head point to the first heads structures */ + pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); + pI830->LpRing = pI8301->LpRing; + pI830->overlay_regs = pI8301->overlay_regs; + pI830->overlayOn = pI8301->overlayOn; + pI830->used3D = pI8301->used3D; + } + #if defined(XF86DRI) /* * If DRI is potentially usable, check if there is enough memory available @@ -2412,33 +2412,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->starting = TRUE; - /* Alloc our pointers for the primary head */ - if (I830IsPrimary(pScrn)) { - if (!pI830->LpRing) - pI830->LpRing = xalloc(sizeof(I830RingBuffer)); - if (!pI830->overlayOn) - pI830->overlayOn = xalloc(sizeof(Bool)); - if (!pI830->used3D) - pI830->used3D = xalloc(sizeof(int)); - if (!pI830->LpRing || !pI830->overlayOn || !pI830->used3D) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Could not allocate primary data structures.\n"); - return FALSE; - } - *pI830->overlayOn = FALSE; - if (pI830->entityPrivate) - pI830->entityPrivate->XvInUse = -1; - } - - /* Make our second head point to the first heads structures */ - if (!I830IsPrimary(pScrn)) { - pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - pI830->LpRing = pI8301->LpRing; - pI830->overlay_regs = pI8301->overlay_regs; - pI830->overlayOn = pI8301->overlayOn; - pI830->used3D = pI8301->used3D; - } - miClearVisualTypes(); if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), -- cgit v1.2.3 From acd9f3e28fcf5e91e09d8bdca4cc58681b1fc92a Mon Sep 17 00:00:00 2001 From: Wang Zhenyu Date: Tue, 27 Feb 2007 13:56:31 +0800 Subject: Fix typo when assign overlay reg mem pointer --- src/i830_video.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i830_video.c b/src/i830_video.c index 4c64b309..e580dab5 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -2175,7 +2175,8 @@ I830PutImage(ScrnInfoPtr pScrn, if (pPriv->textured) overlay = NULL; else - (I830OverlayRegPtr) (pI830->FbBase + pI830->overlay_regs->offset); + overlay = (I830OverlayRegPtr) (pI830->FbBase + + pI830->overlay_regs->offset); #if 0 ErrorF("I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n" -- cgit v1.2.3 From 1ac83f51ee46d65237eae1b5c767e106ac9e29bc Mon Sep 17 00:00:00 2001 From: Wang Zhenyu Date: Tue, 27 Feb 2007 13:58:47 +0800 Subject: EXA: enlarge 965 exa state buffer size Origin size seems break all render, be sure to assign enough mem. 80k works fine for me. --- src/i830.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830.h b/src/i830.h index 08d9e3ed..5cf9f0da 100644 --- a/src/i830.h +++ b/src/i830.h @@ -73,7 +73,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef I830_USE_EXA #include "exa.h" Bool I830EXAInit(ScreenPtr pScreen); -#define EXA_LINEAR_EXTRA (64*1024) +#define EXA_LINEAR_EXTRA (80*1024) #endif #ifdef I830_USE_XAA -- cgit v1.2.3 From 3e8e75e5d83a2fa7e9fc6e9a3fbb07dac548ea5a Mon Sep 17 00:00:00 2001 From: Wang Zhenyu Date: Tue, 27 Feb 2007 16:48:48 +0800 Subject: Revert "EXA: enlarge 965 exa state buffer size" This reverts commit 1ac83f51ee46d65237eae1b5c767e106ac9e29bc. oops, current exa state + kernel program size + scratch space is actually ~36KB. --- src/i830.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830.h b/src/i830.h index 5cf9f0da..08d9e3ed 100644 --- a/src/i830.h +++ b/src/i830.h @@ -73,7 +73,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef I830_USE_EXA #include "exa.h" Bool I830EXAInit(ScreenPtr pScreen); -#define EXA_LINEAR_EXTRA (80*1024) +#define EXA_LINEAR_EXTRA (64*1024) #endif #ifdef I830_USE_XAA -- cgit v1.2.3 From cd1d4b398ec91d551bdaaa26c769e5e6a9442df1 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 28 Feb 2007 09:47:38 -0800 Subject: Many fixes to mode_get, mode_set, clock limits, and register dumps on i855. This should fix a number of issues with i855s, particularly with integrated LVDS panels. --- src/i810_reg.h | 25 +++++++++- src/i830_debug.c | 85 +++++++++++++++++++++++++++------- src/i830_display.c | 133 ++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 185 insertions(+), 58 deletions(-) diff --git a/src/i810_reg.h b/src/i810_reg.h index 46d473d7..6a9c11e4 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -299,6 +299,20 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define VCLK_DIVISOR_VGA0 0x6000 #define VCLK_DIVISOR_VGA1 0x6004 #define VCLK_POST_DIV 0x6010 +/** Selects a post divisor of 4 instead of 2. */ +# define VGA1_PD_P2_DIV_4 (1 << 15) +/** Overrides the p2 post divisor field */ +# define VGA1_PD_P1_DIV_2 (1 << 13) +# define VGA1_PD_P1_SHIFT 8 +/** P1 value is 2 greater than this field */ +# define VGA1_PD_P1_MASK (0x1f << 8) +/** Selects a post divisor of 4 instead of 2. */ +# define VGA0_PD_P2_DIV_4 (1 << 7) +/** Overrides the p2 post divisor field */ +# define VGA0_PD_P1_DIV_2 (1 << 5) +# define VGA0_PD_P1_SHIFT 0 +/** P1 value is 2 greater than this field */ +# define VGA0_PD_P1_MASK (0x1f << 0) #define POST_DIV_SELECT 0x70 #define POST_DIV_1 0x00 @@ -847,9 +861,18 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ # define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ # define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ +/** + * The i830 generation, in DAC/serial mode, defines p1 as two plus this + * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set. + */ +# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 +/** + * The i830 generation, in LVDS mode, defines P1 as the bit number set within + * this field (only one bit may be set). + */ +# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 # define DPLL_FPA01_P1_POST_DIV_SHIFT 16 # define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */ -# define DPLL_FPA01_P1_POS_DIV_MASK_I830 0x001f0000 /* i830 */ # define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ # define PLL_REF_INPUT_DREFCLK (0 << 13) # define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ diff --git a/src/i830_debug.c b/src/i830_debug.c index 6716eaab..de36a045 100644 --- a/src/i830_debug.c +++ b/src/i830_debug.c @@ -102,6 +102,28 @@ DEBUGSTRING(i830_debug_fp) ((val & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT)); } +DEBUGSTRING(i830_debug_vga_pd) +{ + int vga0_p1, vga0_p2, vga1_p1, vga1_p2; + + /* XXX: i9xx version */ + + if (val & VGA0_PD_P1_DIV_2) + vga0_p1 = 2; + else + vga0_p1 = ((val & VGA0_PD_P1_MASK) >> VGA0_PD_P1_SHIFT) + 2; + vga0_p2 = (val & VGA0_PD_P2_DIV_4) ? 4 : 2; + + if (val & VGA1_PD_P1_DIV_2) + vga1_p1 = 2; + else + vga1_p1 = ((val & VGA1_PD_P1_MASK) >> VGA1_PD_P1_SHIFT) + 2; + vga1_p2 = (val & VGA1_PD_P2_DIV_4) ? 4 : 2; + + return XNFprintf("vga0 p1 = %d, p2 = %d, vga1 p1 = %d, p2 = %d", + vga0_p1, vga0_p2, vga1_p1, vga1_p2); +} + DEBUGSTRING(i830_debug_pp_status) { char *status = val & PP_ON ? "on" : "off"; @@ -140,18 +162,44 @@ DEBUGSTRING(i830_debug_dpll) char sdvoextra[20]; int p1, p2 = 0; - p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK) >> - DPLL_FPA01_P1_POST_DIV_SHIFT); - switch (val & DPLL_MODE_MASK) { - case DPLLB_MODE_DAC_SERIAL: - mode = "dac/serial"; - p2 = val & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10; - break; - case DPLLB_MODE_LVDS: - mode = "LVDS"; - p2 = val & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14; - break; + if (IS_I9XX(pI830)) { + p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK) >> + DPLL_FPA01_P1_POST_DIV_SHIFT); + switch (val & DPLL_MODE_MASK) { + case DPLLB_MODE_DAC_SERIAL: + mode = "DAC/serial"; + p2 = val & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10; + break; + case DPLLB_MODE_LVDS: + mode = "LVDS"; + p2 = val & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14; + break; + } + } else { + Bool is_lvds = (INREG(LVDS) & LVDS_PORT_EN) && (reg == DPLL_B); + + if (val & PLL_P2_DIVIDE_BY_4) + p2 = 4; + else + p2 = 2; + + if (is_lvds) { + mode = "LVDS"; + /* Map the bit number set from (1, 6) to (-1, 4). */ + p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> + DPLL_FPA01_P1_POST_DIV_SHIFT); + } else { + mode = "DAC/serial"; + if (val & PLL_P1_DIVIDE_BY_TWO) { + p1 = 2; + } else { + /* Map the number in the field to (1, 31) */ + p1 = ((val & DPLL_FPA01_P1_POST_DIV_MASK_I830) >> + DPLL_FPA01_P1_POST_DIV_SHIFT) + 2; + } + } } + switch (val & PLL_REF_INPUT_MASK) { case PLL_REF_INPUT_DREFCLK: clock = "default"; @@ -162,7 +210,12 @@ DEBUGSTRING(i830_debug_dpll) case PLL_REF_INPUT_TVCLKINBC: clock = "TV B/C"; break; + case PLLB_REF_INPUT_SPREADSPECTRUMIN: + if (reg == DPLL_B) + clock = "spread spectrum"; + break; } + if (IS_I945G(pI830) || IS_I945GM(pI830)) { sprintf(sdvoextra, ", SDVO mult %d", (int)((val & SDVO_MULTIPLIER_MASK) >> @@ -171,9 +224,9 @@ DEBUGSTRING(i830_debug_dpll) sdvoextra[0] = '\0'; } - return XNFprintf("%s, %s%s, %s mode, %s clock, p1 = %d, " + return XNFprintf("%s, %s%s, %s clock, %s mode, p1 = %d, " "p2 = %d%s%s", - enabled, dvomode, vgamode, mode, clock, p1, p2, + enabled, dvomode, vgamode, clock, mode, p1, p2, fpextra, sdvoextra); } @@ -233,9 +286,9 @@ static struct i830SnapshotRec { char *(*debug_output)(I830Ptr pI830, int reg, CARD32 val); CARD32 val; } i830_snapshot[] = { - DEFINEREG(VCLK_DIVISOR_VGA0), - DEFINEREG(VCLK_DIVISOR_VGA1), - DEFINEREG(VCLK_POST_DIV), + DEFINEREG2(VCLK_DIVISOR_VGA0, i830_debug_fp), + DEFINEREG2(VCLK_DIVISOR_VGA1, i830_debug_fp), + DEFINEREG2(VCLK_POST_DIV, i830_debug_vga_pd), DEFINEREG2(DPLL_TEST, i830_debug_dpll_test), DEFINEREG(D_STATE), DEFINEREG(DSPCLK_GATE_D), diff --git a/src/i830_display.c b/src/i830_display.c index a1660e35..e9666de0 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -85,10 +85,15 @@ typedef struct { #define I8XX_M2_MAX 16 #define I8XX_P_MIN 4 #define I8XX_P_MAX 128 +/* LVDS p1 value can go from 1 to 6, while DAC goes from 2 to 33. These + * values below get 2 added in the clock calculations. + */ #define I8XX_P1_MIN 0 -#define I8XX_P1_MAX 30 -#define I8XX_P2_SLOW 1 -#define I8XX_P2_FAST 0 +#define I8XX_P1_MAX 31 +#define I8XX_P1_LVDS_MIN -1 +#define I8XX_P1_LVDS_MAX 4 +#define I8XX_P2_SLOW 1 /* this is a bit shift amount */ +#define I8XX_P2_FAST 0 /* this is a bit shift amount */ #define I8XX_P2_SLOW_LIMIT 165000 #define I9XX_DOT_MIN 20000 @@ -116,12 +121,13 @@ typedef struct { #define I9XX_P2_LVDS_FAST 7 #define I9XX_P2_LVDS_SLOW_LIMIT 112000 -#define INTEL_LIMIT_I8XX 0 -#define INTEL_LIMIT_I9XX_SDVO_DAC 1 -#define INTEL_LIMIT_I9XX_LVDS 2 +#define INTEL_LIMIT_I8XX_DVO_DAC 0 +#define INTEL_LIMIT_I8XX_LVDS 1 +#define INTEL_LIMIT_I9XX_SDVO_DAC 2 +#define INTEL_LIMIT_I9XX_LVDS 3 static const intel_limit_t intel_limits[] = { - { + { /* INTEL_LIMIT_I8XX_DVO_DAC */ .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, @@ -133,7 +139,19 @@ static const intel_limit_t intel_limits[] = { .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, }, - { + { /* INTEL_LIMIT_I8XX_LVDS */ + .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, + .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, + .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, + .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX }, + .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX }, + .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX }, + .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX }, + .p1 = { .min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX }, + .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, + .p2_slow = I8XX_P2_FAST, .p2_fast = I8XX_P2_FAST }, + }, + { /* INTEL_LIMIT_I9XX_SDVO_DAC */ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, @@ -145,7 +163,7 @@ static const intel_limit_t intel_limits[] = { .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, }, - { + { /* INTEL_LIMIT_I9XX_LVDS */ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, @@ -168,15 +186,18 @@ static const intel_limit_t *intel_limit (xf86CrtcPtr crtc) I830Ptr pI830 = I830PTR(pScrn); const intel_limit_t *limit; - if (IS_I9XX(pI830)) - { + if (IS_I9XX(pI830)) { if (i830PipeHasType (crtc, I830_OUTPUT_LVDS)) limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS]; else limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; + } else { + if (i830PipeHasType (crtc, I830_OUTPUT_LVDS)) + limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS]; + else + limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC]; } - else - limit = &intel_limits[INTEL_LIMIT_I8XX]; + return limit; } @@ -792,7 +813,15 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, if (IS_I965G(pI830)) dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); } else { - dpll |= clock.p1 << 16; + if (is_lvds) { + /* map (-1 to 4) to ((1 << 0) to (1 << 5)). */ + dpll |= (1 << (clock.p1 + 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; + } else { + if (clock.p1 == 0) + dpll |= PLL_P1_DIVIDE_BY_TWO; + else + dpll |= clock.p1 << DPLL_FPA01_P1_POST_DIV_SHIFT; + } dpll |= clock.p2 << 23; } @@ -1250,35 +1279,59 @@ i830_crtc_clock_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc) clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT; - clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >> - DPLL_FPA01_P1_POST_DIV_SHIFT); - switch (dpll & DPLL_MODE_MASK) { - case DPLLB_MODE_DAC_SERIAL: - clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10; - break; - case DPLLB_MODE_LVDS: - clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14; - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Unknown DPLL mode %08x in programmed mode\n", - (int)(dpll & DPLL_MODE_MASK)); - return 0; - } - - /* XXX: Handle the 100Mhz refclk */ - if (IS_I9XX(pI830)) + if (IS_I9XX(pI830)) { + clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >> + DPLL_FPA01_P1_POST_DIV_SHIFT); + + switch (dpll & DPLL_MODE_MASK) { + case DPLLB_MODE_DAC_SERIAL: + clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10; + break; + case DPLLB_MODE_LVDS: + clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Unknown DPLL mode %08x in programmed mode\n", + (int)(dpll & DPLL_MODE_MASK)); + return 0; + } + + /* XXX: Handle the 100Mhz refclk */ i9xx_clock(96000, &clock); - else - i9xx_clock(48000, &clock); + } else { + Bool is_lvds = (pipe == 1) && (INREG(LVDS) & LVDS_PORT_EN); + + if (is_lvds) { + /* Map the bit number set from (1, 6) to (-1, 4). */ + clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> + DPLL_FPA01_P1_POST_DIV_SHIFT) - 2; + clock.p2 = 0; + } else { + if (dpll & PLL_P1_DIVIDE_BY_TWO) { + clock.p1 = 0; + } else { + /* Map the number in the field to (1, 31) */ + clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >> + DPLL_FPA01_P1_POST_DIV_SHIFT); + } + if (dpll & PLL_P2_DIVIDE_BY_4) + clock.p2 = 1; + else + clock.p2 = 0; + } - if (!i830PllIsValid(crtc, &clock)) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Bad clock found programmed in pipe %c\n", - pipe == 0 ? 'A' : 'B'); - i830PrintPll("", &clock); + /* XXX: Deal with other refclocks */ + i8xx_clock(48000, &clock); } + /* XXX: It would be nice to validate the clocks, but we can't reuse + * i830PllIsValid() because it relies on the xf86_config output + * configuration being accurate, which it isn't necessarily. + */ + if (0) + i830PrintPll("probed", &clock); + return clock.dot; } @@ -1299,8 +1352,6 @@ i830_crtc_mode_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc) if (mode == NULL) return NULL; - memset(mode, 0, sizeof(*mode)); - mode->Clock = i830_crtc_clock_get(pScrn, crtc); mode->HDisplay = (htot & 0xffff) + 1; mode->HTotal = ((htot & 0xffff0000) >> 16) + 1; -- cgit v1.2.3 From 1f5d1666c8386ca4597c6f2c1ec239f9d821da4c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 28 Feb 2007 16:27:55 -0800 Subject: Add a non-installed command line tool using libpciaccess to dump registers. This reuses the i830_debug.c code, so we can run that from the console or from the BIOS-based X server to debug some remaining issues. --- configure.ac | 4 ++++ src/Makefile.am | 6 +++++- src/common.h | 2 ++ src/i830_debug.c | 13 +++++++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 395e9d4e..775e87f0 100644 --- a/configure.ac +++ b/configure.ac @@ -87,6 +87,9 @@ XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) PKG_CHECK_MODULES(XORG, [xorg-server xproto xvmc fontsproto $REQUIRED_MODULES]) sdkdir=$(pkg-config --variable=sdkdir xorg-server) +PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.5.0], have_pciaccess=yes, have_pciaccess=no) +AM_CONDITIONAL(HAVE_PCIACCESS, test "x$have_pciaccess" = xyes) + # Checks for libraries. # Checks for header files. @@ -200,6 +203,7 @@ AC_OUTPUT([ src/ch7017/Makefile src/ch7xxx/Makefile src/ivch/Makefile + src/reg_dumper/Makefile src/sil164/Makefile man/Makefile ]) diff --git a/src/Makefile.am b/src/Makefile.am index adb4c42d..c65c1e73 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,7 +18,11 @@ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164 +if HAVE_PCIACCESS +REGDUMPER = reg_dumper +endif + +SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164 $(REGDUMPER) # this is obnoxious: # -module lets us name the module exactly how we want diff --git a/src/common.h b/src/common.h index 91e31b5f..8f42bde8 100644 --- a/src/common.h +++ b/src/common.h @@ -72,6 +72,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DELAY(x) do {;} while (0) #endif +#ifndef REG_DUMPER /* I830 hooks for the I810 driver setup/probe. */ extern const OptionInfoRec *I830AvailableOptions(int chipid, int busid); extern void I830InitpScrn(ScrnInfoPtr pScrn); @@ -242,6 +243,7 @@ extern int I810_DEBUG; #define DEBUG_ALWAYS_SYNC 0x80 #define DEBUG_VERBOSE_DRI 0x100 #define DEBUG_VERBOSE_BIOS 0x200 +#endif /* !REG_DUMPER */ /* Size of the mmio region. */ diff --git a/src/i830_debug.c b/src/i830_debug.c index de36a045..dccaa7ea 100644 --- a/src/i830_debug.c +++ b/src/i830_debug.c @@ -25,6 +25,11 @@ * */ +#ifdef REG_DUMPER +#include "reg_dumper/reg_dumper.h" + +#else + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -34,6 +39,10 @@ #include "i830_debug.h" #include +#endif + +#include "i810_reg.h" + #define DEBUGSTRING(func) static char *func(I830Ptr pI830, int reg, CARD32 val) DEBUGSTRING(i830_debug_xyminus1) @@ -410,6 +419,7 @@ static struct i830SnapshotRec { #undef DEFINEREG #define NUM_I830_SNAPSHOTREGS (sizeof(i830_snapshot) / sizeof(i830_snapshot[0])) +#ifndef REG_DUMPER void i830TakeRegSnapshot(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); @@ -454,6 +464,7 @@ void i830CompareRegsToSnapshot(ScrnInfoPtr pScrn, char *where) } } } +#endif /* !REG_DUMPER */ static void i830DumpIndexed (ScrnInfoPtr pScrn, char *name, int id, int val, int min, int max) { @@ -587,6 +598,7 @@ void i830DumpRegs (ScrnInfoPtr pScrn) xf86DrvMsg (pScrn->scrnIndex, X_INFO, "DumpRegsEnd\n"); } +#ifndef REG_DUMPER /* Famous last words */ void @@ -799,3 +811,4 @@ i830_check_error_state(ScrnInfoPtr pScrn) return (errors != 0); } +#endif /* !REG_DUMPER */ -- cgit v1.2.3 From d5df52be59a7dd950e73336ce5698e73480108b0 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 1 Mar 2007 08:35:13 -0800 Subject: Actually add the files for reg_dumper. --- src/reg_dumper/.gitignore | 1 + src/reg_dumper/Makefile.am | 12 +++++ src/reg_dumper/main.c | 105 ++++++++++++++++++++++++++++++++++++++++++++ src/reg_dumper/reg_dumper.h | 89 +++++++++++++++++++++++++++++++++++++ src/reg_dumper/xprintf.c | 60 +++++++++++++++++++++++++ 5 files changed, 267 insertions(+) create mode 100644 src/reg_dumper/.gitignore create mode 100644 src/reg_dumper/Makefile.am create mode 100644 src/reg_dumper/main.c create mode 100644 src/reg_dumper/reg_dumper.h create mode 100644 src/reg_dumper/xprintf.c diff --git a/src/reg_dumper/.gitignore b/src/reg_dumper/.gitignore new file mode 100644 index 00000000..1b38d5c6 --- /dev/null +++ b/src/reg_dumper/.gitignore @@ -0,0 +1 @@ +intel_reg_dumper diff --git a/src/reg_dumper/Makefile.am b/src/reg_dumper/Makefile.am new file mode 100644 index 00000000..aee26d0e --- /dev/null +++ b/src/reg_dumper/Makefile.am @@ -0,0 +1,12 @@ +noinst_PROGRAMS = intel_reg_dumper + +intel_reg_dumper_SOURCES = \ + main.c \ + reg_dumper.h \ + xprintf.c \ + ../i830_debug.c + +intel_reg_dumper_LDADD = $(PCIACCESS_LIBS) + +intel_reg_dumper_CFLAGS = $(PCIACCESS_CFLAGS) $(WARN_CFLAGS) \ + -I$(srcdir)/.. -DREG_DUMPER diff --git a/src/reg_dumper/main.c b/src/reg_dumper/main.c new file mode 100644 index 00000000..50c79236 --- /dev/null +++ b/src/reg_dumper/main.c @@ -0,0 +1,105 @@ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ + +#include +#include +#include +#include +#include +#include + +#include "reg_dumper.h" + +int main(int argc, char **argv) +{ + struct pci_device *dev; + I830Rec i830; + ScrnInfoRec scrn; + int err, mmio_bar; + + err = pci_system_init(); + if (err != 0) { + fprintf(stderr, "Couldn't initialize PCI system: %s\n", strerror(err)); + exit(1); + } + + /* Grab the graphics card */ + dev = pci_device_find_by_slot(0, 0, 2, 0); + if (dev == NULL) + errx(1, "Couldn't find graphics card"); + + if (dev->vendor_id != 0x8086) + errx(1, "Graphics card is non-intel"); + + err = pci_device_probe(dev); + if (err != 0) { + fprintf(stderr, "Couldn't probe graphics card: %s\n", strerror(err)); + exit(1); + } + + i830.PciInfo = &i830.pci_info_rec; + i830.PciInfo->chipType = dev->device_id; + + i830.pci_dev = dev; + + mmio_bar = IS_I9XX((&i830)) ? 0 : 1; + + err = pci_device_map_region(dev, mmio_bar, 1); + if (err != 0) { + fprintf(stderr, "Couldn't map MMIO region: %s\n", strerror(err)); + exit(1); + } + i830.mmio = i830.pci_dev->regions[mmio_bar].memory; + + scrn.scrnIndex = 0; + scrn.pI830 = &i830; + + i830DumpRegs(&scrn); + + return 0; +} + +void xf86DrvMsg(int scrnIndex, int severity, const char *format, ...) +{ + va_list va; + + switch (severity) { + case X_INFO: + printf("(II): "); + break; + case X_WARNING: + printf("(WW): "); + break; + case X_ERROR: + printf("(EE): "); + break; + } + + va_start(va, format); + vprintf(format, va); + va_end(va); +} diff --git a/src/reg_dumper/reg_dumper.h b/src/reg_dumper/reg_dumper.h new file mode 100644 index 00000000..a52d6622 --- /dev/null +++ b/src/reg_dumper/reg_dumper.h @@ -0,0 +1,89 @@ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ + +#include +#include +#include +#include +#include "common.h" + +/** @file + * This file defines the typedefs and stub structures necessary for us to + * use i830_debug.c mostly unmodified. + */ + +typedef uint32_t CARD32; +typedef char Bool; + +#define FALSE 0 +#define TRUE 1 + +#define X_INFO 0 +#define X_WARNING 1 +#define X_ERROR 2 + +struct pci_info_rec { + uint16_t chipType; +}; + +typedef struct _i830 { + /* Fields in common with the real pI830 */ + struct pci_info_rec *PciInfo; + + /* Fields used for setting up reg_dumper */ + struct pci_device *pci_dev; + struct pci_info_rec pci_info_rec; + volatile unsigned char *mmio; +} I830Rec, *I830Ptr; + +typedef struct _scrn { + /* Fields in common with the real pScrn */ + int scrnIndex; + + /* Fields used for setting up reg_dumper */ + I830Ptr pI830; +} ScrnInfoRec, *ScrnInfoPtr; + +#define I830PTR(pScrn) (pScrn->pI830) + +#define INREG8(reg) (*(volatile uint8_t *)((pI830)->mmio + (reg))) +#define INREG16(reg) (*(volatile uint16_t *)((pI830)->mmio + (reg))) +#define INREG(reg) (*(volatile uint32_t *)((pI830)->mmio + (reg))) +#define OUTREG8(reg, val) \ + *(volatile uint8_t *)((pI830)->mmio + (reg)) = (val) +#define OUTREG16(reg, val) \ + *(volatile uint16_t *)((pI830)->mmio + (reg)) = (val) +#define OUTREG(reg, val) \ + *(volatile uint32_t *)((pI830)->mmio + (reg)) = (val) + +#define xalloc malloc +#define xfree free +#define ErrorF printf + +char *XNFprintf(const char *format, ...); +void xf86DrvMsg(int scrnIndex, int severity, const char *format, ...); +void i830DumpRegs(ScrnInfoPtr pScrn); diff --git a/src/reg_dumper/xprintf.c b/src/reg_dumper/xprintf.c new file mode 100644 index 00000000..125ae870 --- /dev/null +++ b/src/reg_dumper/xprintf.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2004 Alexander Gottwald + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written authorization. + */ + +#include +#include +#include "reg_dumper.h" + +static char * +XNFvprintf(const char *format, va_list va) +{ + char *ret; + int size; + va_list va2; + + va_copy(va2, va); + size = vsnprintf(NULL, 0, format, va2); + va_end(va2); + + ret = (char *)malloc(size + 1); + if (ret == NULL) + return NULL; + + vsnprintf(ret, size + 1, format, va); + ret[size] = 0; + return ret; +} + +char * +XNFprintf(const char *format, ...) +{ + char *ret; + va_list va; + va_start(va, format); + ret = XNFvprintf(format, va); + va_end(va); + return ret; +} -- cgit v1.2.3 From 5a73624b9bcce0004e5b72c74667c9dd504b9c3e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 2 Mar 2007 11:03:16 -0800 Subject: Fix a crash when an ARGB cursor allocation had failed. --- src/i830_cursor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_cursor.c b/src/i830_cursor.c index 0cfd2292..85785112 100644 --- a/src/i830_cursor.c +++ b/src/i830_cursor.c @@ -372,7 +372,7 @@ static Bool I830UseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs) for (i = 0; i < xf86_config->num_crtc; i++) { I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; - if (!intel_crtc->cursor_mem_argb->offset) + if (intel_crtc->cursor_mem_argb == NULL) return FALSE; } -- cgit v1.2.3 From ca0fa875e8bb5cb778d4db7d8053ec0a5ae34ef4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 2 Mar 2007 11:46:45 -0800 Subject: Move EXA offscreen memory back after framebuffer to avoid fallbacks. Without this, the EXA code decides that the framebuffer is not in video memory because it's not located between the start of video memory and the end of EXA allocator memory. We should either have EXA let the driver decide if a pointer is in video memory, or add a new field for "end of video memory" (not just end of EXA offscreen allocation), but this fixes things for now. --- src/i830_memory.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/i830_memory.c b/src/i830_memory.c index b83078a5..5cddf173 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -945,6 +945,21 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) i830_allocate_overlay(pScrn); #endif + if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { + I830EntPtr pI830Ent = pI830->entityPrivate; + I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2); + + pI830->front_buffer_2 = + i830_allocate_framebuffer(pI830Ent->pScrn_2, pI8302, + &pI830->FbMemBox2, TRUE, 0); + if (pI830->front_buffer_2 == NULL) + return FALSE; + } + pI830->front_buffer = + i830_allocate_framebuffer(pScrn, pI830, &pI830->FbMemBox, FALSE, 0); + if (pI830->front_buffer == NULL) + return FALSE; + #ifdef I830_USE_EXA if (pI830->useEXA) { if (pI830->exa_offscreen == NULL) { @@ -981,21 +996,6 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) } #endif /* I830_USE_EXA */ - if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2) { - I830EntPtr pI830Ent = pI830->entityPrivate; - I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2); - - pI830->front_buffer_2 = - i830_allocate_framebuffer(pI830Ent->pScrn_2, pI8302, - &pI830->FbMemBox2, TRUE, 0); - if (pI830->front_buffer_2 == NULL) - return FALSE; - } - pI830->front_buffer = - i830_allocate_framebuffer(pScrn, pI830, &pI830->FbMemBox, FALSE, 0); - if (pI830->front_buffer == NULL) - return FALSE; - if (!pI830->noAccel && !pI830->useEXA) { pI830->xaa_scratch = i830_allocate_memory(pScrn, "xaa scratch", MAX_SCRATCH_BUFFER_SIZE, -- cgit v1.2.3 From fd52d635603b7093c5a2b7fa9c987cf59f9be27c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 2 Mar 2007 13:44:57 -0800 Subject: Add a WIP UploadToScreen implementation. This almost displays right. --- src/common.h | 37 ++++++++++++++++++++++++ src/i810_reg.h | 2 ++ src/i830_exa.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) diff --git a/src/common.h b/src/common.h index 8f42bde8..6e8ddbda 100644 --- a/src/common.h +++ b/src/common.h @@ -131,6 +131,43 @@ extern void I830DPRINTF_stub(const char *filename, int line, outring &= ringmask; \ } while (0) +static inline void memset_volatile(volatile void *b, int c, size_t len) +{ + int i; + + for (i = 0; i < len; i++) + ((volatile char *)b)[i] = c; +} + +static inline void memcpy_volatile(volatile void *dst, const void *src, + size_t len) +{ + int i; + + for (i = 0; i < len; i++) + ((volatile char *)dst)[i] = ((volatile char *)src)[i]; +} + +/** Copies a given number of bytes to the ring */ +#define OUT_RING_COPY(n, ptr) do { \ + if (I810_DEBUG & DEBUG_VERBOSE_RING) \ + ErrorF("OUT_RING_DATA %d bytes\n", n); \ + memcpy_volatile(virt + outring, ptr, n); \ + outring += n; \ + ringused += n; \ + outring &= ringmask; \ +} while (0) + +/** Pads the ring with a given number of zero bytes */ +#define OUT_RING_PAD(n) do { \ + if (I810_DEBUG & DEBUG_VERBOSE_RING) \ + ErrorF("OUT_RING_PAD %d bytes\n", n); \ + memset_volatile(virt + outring, 0, n); \ + outring += n; \ + ringused += n; \ + outring &= ringmask; \ +} while (0) + union intfloat { float f; unsigned int ui; diff --git a/src/i810_reg.h b/src/i810_reg.h index 6a9c11e4..d63be025 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -1906,6 +1906,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SRC_COPY_BLT_WRITE_ALPHA (1<<21) #define SRC_COPY_BLT_WRITE_RGB (1<<20) +#define XY_PAT_BLT_IMMEDIATE ((2<<29)|(0x72<<22)) + #define XY_MONO_PAT_BLT_CMD ((0x2<<29)|(0x52<<22)|0x7) #define XY_MONO_PAT_VERT_SEED ((1<<10)|(1<<9)|(1<<8)) #define XY_MONO_PAT_HORT_SEED ((1<<14)|(1<<13)|(1<<12)) diff --git a/src/i830_exa.c b/src/i830_exa.c index 37fd2842..bef8faef 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -297,6 +297,93 @@ i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform, } } +/** + * Uploads data from system memory to the framebuffer using a series of + * 8x8 pattern blits. + */ +static Bool +i830_upload_to_screen(PixmapPtr pDst, int x, int y, int w, int h, char *src, + int src_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + const int uts_width_max = 16, uts_height_max = 16; + int cpp = pDst->drawable.bitsPerPixel / 8; + int sub_x, sub_y; + CARD32 br13; + CARD32 offset; + + if (w > uts_width_max || h > uts_height_max) + I830FALLBACK("too large for upload to screen (%d,%d)", w, h); + + offset = exaGetPixmapOffset(pDst); + + br13 = exaGetPixmapPitch(pDst); + br13 |= ((I830PatternROP[GXcopy] & 0xff) << 16); + switch (pDst->drawable.bitsPerPixel) { + case 16: + br13 |= 1 << 24; + break; + case 32: + br13 |= 3 << 24; + break; + } + + for (sub_y = 0; sub_y < uts_height_max && sub_y < h; sub_y += 8) { + int sub_height; + + if (sub_y + 8 > h) + sub_height = h - sub_y; + else + sub_height = 8; + + for (sub_x = 0; sub_x < uts_width_max && sub_x < w; sub_x += 8) { + int sub_width, line; + char *src_line = src + sub_y * src_pitch + sub_x * cpp; + + if (sub_x + 8 > w) + sub_width = w - sub_x; + else + sub_width = 8; + + BEGIN_LP_RING(6 + (cpp * 8 * 8 / 4)); + + /* XXX We may need a pattern offset here for {x,y} % 8 != 0*/ + OUT_RING(XY_PAT_BLT_IMMEDIATE | + XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB | + (3 + cpp * 8 * 8 / 4)); + OUT_RING(br13); + OUT_RING(((y + sub_y) << 16) | (x + sub_x)); + OUT_RING(((y + sub_y + sub_height) << 16) | + (x + sub_x + sub_width)); + OUT_RING(offset); + + /* Write out the lines with valid data, followed by any needed + * padding + */ + for (line = 0; line < sub_height; line++) { + OUT_RING_COPY(sub_width * cpp, src_line); + src_line += src_pitch; + if (sub_width != 8) + OUT_RING_PAD((8 - sub_width) * cpp); + } + /* Write out any full padding lines to follow */ + if (sub_height != 8) + OUT_RING_PAD(8 * cpp * (8 - sub_height)); + + OUT_RING(MI_NOOP); + ADVANCE_LP_RING(); + } + } + + exaMarkSync(pDst->drawable.pScreen); + /* exaWaitSync(pDst->drawable.pScreen); */ + + return TRUE; +} + + /* * TODO: * - Dual head? @@ -421,6 +508,10 @@ I830EXAInit(ScreenPtr pScreen) pI830->EXADriverPtr->DoneComposite = i830_done_composite; } + /* UploadToScreen/DownloadFromScreen */ + if (0) + pI830->EXADriverPtr->UploadToScreen = i830_upload_to_screen; + if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EXA initialization failed; trying older version\n"); -- cgit v1.2.3 From 435d35558d8135a2c1724dfd813fb4a9a4e14178 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 3 Mar 2007 22:46:31 -0800 Subject: Update for Aaron's xserver changes. Add xf86CrtcConfigFuncs to xf86CrtcConfigInit Add canGrow option to xf86InitialConfiguration --- src/i830_driver.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 5ba96a53..3c10ffce 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -778,6 +778,18 @@ I830IsPrimary(ScrnInfoPtr pScrn) return TRUE; } +static Bool +i830_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) +{ + scrn->virtualX = width; + scrn->virtualY = height; + return TRUE; +} + +static const xf86CrtcConfigFuncsRec i830_xf86crtc_config_funcs = { + i830_xf86crtc_resize +}; + #define HOTKEY_BIOS_SWITCH 0 #define HOTKEY_DRIVER_NOTIFY 1 @@ -1091,7 +1103,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) (unsigned long)pI830->MMIOAddr); /* Allocate an xf86CrtcConfig */ - xf86CrtcConfigInit (pScrn); + xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs); xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); /* See i830_exa.c comments for why we limit the framebuffer size like this. @@ -1282,7 +1294,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) output->status = (*output->funcs->detect) (output); } - if (!xf86InitialConfiguration (pScrn)) + if (!xf86InitialConfiguration (pScrn, FALSE)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); RestoreHWState(pScrn); -- cgit v1.2.3