i830_memory.c
来自「是由intel提供的针对intel显卡915以上系列的linux驱动」· C语言 代码 · 共 1,966 行 · 第 1/4 页
C
1,966 行
xf86ErrorFVerb(verbosity, "\n"); } size = HWCURSOR_SIZE_ARGB; cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP; if (pI830->CursorNeedsPhysical) cursFlags |= NEED_PHYSICAL_ADDR; alloced = I830AllocVidMem(pScrn, pI830->CursorMemARGB, &(pI830->StolenPool), size, GTT_PAGE_SIZE, flags | cursFlags); if (alloced < size) { 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, pI830->CursorMemARGB->Start); if (pI830->CursorNeedsPhysical) xf86ErrorFVerb(verbosity, " (0x%08lx)", pI830->CursorMemARGB->Physical); xf86ErrorFVerb(verbosity, "\n"); } }#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"); } 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"); } 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;}voidI830ResetAllocations(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; pI830->StolenPool.Fixed = pI830->StolenMemory; pI830->StolenPool.Total = pI830->StolenMemory;#if ALLOCATE_ALL_BIOSMEM if (pI830->overrideBIOSMemSize && pI830->BIOSMemorySize > pI830->StolenMemory.Size) { pI830->StolenPool.Total.End = pI830->BIOSMemorySize; pI830->StolenPool.Total.Size = pI830->BIOSMemorySize; }#endif pI830->StolenPool.Free = pI830->StolenPool.Total; pI830->FreeMemory = pI830->TotalVideoRam - pI830->StolenPool.Total.Size; pI830->allocatedMemory = 0;}longI830GetExcessMemoryAllocations(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 XF86DRIstatic unsigned intmyLog2(unsigned int n){ unsigned int log2 = 1; while (n > 1) { n >>= 1; log2++; } return log2;}BoolI830AllocateBackBuffer(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->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 >= 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;}BoolI830AllocateDepthBuffer(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->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 >= 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;}BoolI830AllocateTextureMemory(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; 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;}BoolI830Allocate3DMemory(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); if (!I830AllocateBackBuffer(pScrn, flags)) return FALSE; if (!I830AllocateDepthBuffer(pScrn, flags)) return FALSE; if (!I830AllocateTextureMemory(pScrn, flags)) return FALSE; return TRUE;}#endif/* Allocate pool space that isn't pre-allocated */BoolI830DoPoolAllocation(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; /* Due to a bug in agpgart in 2.6 kernels resulting in very poor * allocation performance we need to workaround it here... */ pool->Allocated.Key = I830AllocateGARTMemory(pScrn->scrnIndex, pool->Allocated.Size, 3, NULL); if (pool->Allocated.Key == -1) pool->Allocated.Key = I830AllocateGARTMemory(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 0BoolI830FixOffset(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;}BoolI830FixupOffsets(ScrnInfoPtr pScrn){ I830Ptr pI830 = I830PTR(pScrn); DPRINTF(PFX, "I830FixupOffsets\n");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?