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 + -
显示快捷键?