⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 radeon_dri.c

📁 x.org上有关ati系列显卡最新驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
 * registers to start and stop the CP are privileged, only the X server * can start/stop the engine. */static void RADEONLeaveServer(ScreenPtr pScreen){    ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];    RADEONInfoPtr  info  = RADEONPTR(pScrn);    RING_LOCALS;    /* The CP is always running, but if we've generated any CP commands     * we must flush them to the kernel module now.     */    if (info->CPInUse) {	RADEON_FLUSH_CACHE();	RADEON_WAIT_UNTIL_IDLE();	RADEONCPReleaseIndirect(pScrn);	info->CPInUse = FALSE;    }#ifdef USE_EXA    info->engineMode = EXA_ENGINEMODE_UNKNOWN;#endif}/* Contexts can be swapped by the X server if necessary.  This callback * is currently only used to perform any functions necessary when * entering or leaving the X server, and in the future might not be * necessary. */static void RADEONDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,				 DRIContextType oldContextType,				 void *oldContext,				 DRIContextType newContextType,				 void *newContext){    if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) &&	(newContextType==DRI_2D_CONTEXT)) { /* Entering from Wakeup */	RADEONEnterServer(pScreen);    }    if ((syncType==DRI_2D_SYNC) && (oldContextType==DRI_NO_CONTEXT) &&	(newContextType==DRI_2D_CONTEXT)) { /* Exiting from Block Handler */	RADEONLeaveServer(pScreen);    }}#ifdef USE_XAA/* The Radeon has depth tiling on all the time. Rely on surface regs to * translate the addresses (only works if allowColorTiling is true). *//* 16-bit depth buffer functions */#define WRITE_DEPTH16(_x, _y, d)					\    *(CARD16 *)(pointer)(buf + 2*(_x + _y*info->frontPitch)) = (d)#define READ_DEPTH16(d, _x, _y)						\    (d) = *(CARD16 *)(pointer)(buf + 2*(_x + _y*info->frontPitch))/* 32-bit depth buffer (stencil and depth simultaneously) functions */#define WRITE_DEPTHSTENCIL32(_x, _y, d)					\    *(CARD32 *)(pointer)(buf + 4*(_x + _y*info->frontPitch)) = (d)#define READ_DEPTHSTENCIL32(d, _x, _y)					\    (d) = *(CARD32 *)(pointer)(buf + 4*(_x + _y*info->frontPitch))/* Screen to screen copy of data in the depth buffer */static void RADEONScreenToScreenCopyDepth(ScrnInfoPtr pScrn,					  int xa, int ya,					  int xb, int yb,					  int w, int h){    RADEONInfoPtr  info = RADEONPTR(pScrn);    unsigned char *buf  = info->FB + info->depthOffset;    int            xstart, xend, xdir;    int            ystart, yend, ydir;    int            x, y, d;    if (xa < xb) xdir = -1, xstart = w-1, xend = 0;    else         xdir =  1, xstart = 0,   xend = w-1;    if (ya < yb) ydir = -1, ystart = h-1, yend = 0;    else         ydir =  1, ystart = 0,   yend = h-1;    switch (pScrn->bitsPerPixel) {    case 16:	for (x = xstart; x != xend; x += xdir) {	    for (y = ystart; y != yend; y += ydir) {		READ_DEPTH16(d, xa+x, ya+y);		WRITE_DEPTH16(xb+x, yb+y, d);	    }	}	break;    case 32:	for (x = xstart; x != xend; x += xdir) {	    for (y = ystart; y != yend; y += ydir) {		READ_DEPTHSTENCIL32(d, xa+x, ya+y);		WRITE_DEPTHSTENCIL32(xb+x, yb+y, d);	    }	}	break;    default:	break;    }}#endif /* USE_XAA *//* Initialize the state of the back and depth buffers */static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx){   /* NOOP.  There's no need for the 2d driver to be clearing buffers    * for the 3d client.  It knows how to do that on its own.    */}/* Copy the back and depth buffers when the X server moves a window. * * This routine is a modified form of XAADoBitBlt with the calls to * ScreenToScreenBitBlt built in. My routine has the prgnSrc as source * instead of destination. My origin is upside down so the ydir cases * are reversed. */static void RADEONDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,				 RegionPtr prgnSrc, CARD32 indx){#ifdef USE_XAA    ScreenPtr      pScreen  = pParent->drawable.pScreen;    ScrnInfoPtr    pScrn    = xf86Screens[pScreen->myNum];    RADEONInfoPtr  info     = RADEONPTR(pScrn);    BoxPtr         pboxTmp, pboxNext, pboxBase;    DDXPointPtr    pptTmp;    int            xdir, ydir;    int            screenwidth = pScrn->virtualX;    int            screenheight = pScrn->virtualY;    BoxPtr         pbox     = REGION_RECTS(prgnSrc);    int            nbox     = REGION_NUM_RECTS(prgnSrc);    BoxPtr         pboxNew1 = NULL;    BoxPtr         pboxNew2 = NULL;    DDXPointPtr    pptNew1  = NULL;    DDXPointPtr    pptNew2  = NULL;    DDXPointPtr    pptSrc   = &ptOldOrg;    int            dx       = pParent->drawable.x - ptOldOrg.x;    int            dy       = pParent->drawable.y - ptOldOrg.y;    /* XXX: Fix in EXA case. */    if (info->useEXA)	return;    /* If the copy will overlap in Y, reverse the order */    if (dy > 0) {	ydir = -1;	if (nbox > 1) {	    /* Keep ordering in each band, reverse order of bands */	    pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox);	    if (!pboxNew1) return;	    pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox);	    if (!pptNew1) {		DEALLOCATE_LOCAL(pboxNew1);		return;	    }	    pboxBase = pboxNext = pbox+nbox-1;	    while (pboxBase >= pbox) {		while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1))		    pboxNext--;		pboxTmp = pboxNext+1;		pptTmp  = pptSrc + (pboxTmp - pbox);		while (pboxTmp <= pboxBase) {		    *pboxNew1++ = *pboxTmp++;		    *pptNew1++  = *pptTmp++;		}		pboxBase = pboxNext;	    }	    pboxNew1 -= nbox;	    pbox      = pboxNew1;	    pptNew1  -= nbox;	    pptSrc    = pptNew1;	}    } else {	/* No changes required */	ydir = 1;    }    /* If the regions will overlap in X, reverse the order */    if (dx > 0) {	xdir = -1;	if (nbox > 1) {	    /* reverse order of rects in each band */	    pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox);	    pptNew2  = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox);	    if (!pboxNew2 || !pptNew2) {		DEALLOCATE_LOCAL(pptNew2);		DEALLOCATE_LOCAL(pboxNew2);		DEALLOCATE_LOCAL(pptNew1);		DEALLOCATE_LOCAL(pboxNew1);		return;	    }	    pboxBase = pboxNext = pbox;	    while (pboxBase < pbox+nbox) {		while ((pboxNext < pbox+nbox)		       && (pboxNext->y1 == pboxBase->y1))		    pboxNext++;		pboxTmp = pboxNext;		pptTmp  = pptSrc + (pboxTmp - pbox);		while (pboxTmp != pboxBase) {		    *pboxNew2++ = *--pboxTmp;		    *pptNew2++  = *--pptTmp;		}		pboxBase = pboxNext;	    }	    pboxNew2 -= nbox;	    pbox      = pboxNew2;	    pptNew2  -= nbox;	    pptSrc    = pptNew2;	}    } else {	/* No changes are needed */	xdir = 1;    }    /* pretty much a hack. */    info->dst_pitch_offset = info->backPitchOffset;    if (info->tilingEnabled)       info->dst_pitch_offset |= RADEON_DST_TILE_MACRO;    (*info->accel->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, GXcopy,					       (CARD32)(-1), -1);    for (; nbox-- ; pbox++) {	int  xa    = pbox->x1;	int  ya    = pbox->y1;	int  destx = xa + dx;	int  desty = ya + dy;	int  w     = pbox->x2 - xa + 1;	int  h     = pbox->y2 - ya + 1;	if (destx < 0)                xa -= destx, w += destx, destx = 0;	if (desty < 0)                ya -= desty, h += desty, desty = 0;	if (destx + w > screenwidth)  w = screenwidth  - destx;	if (desty + h > screenheight) h = screenheight - desty;	if (w <= 0) continue;	if (h <= 0) continue;	(*info->accel->SubsequentScreenToScreenCopy)(pScrn,						     xa, ya,						     destx, desty,						     w, h);	if (info->depthMoves) {	    RADEONScreenToScreenCopyDepth(pScrn,					  xa, ya,					  destx, desty,					  w, h);	}    }    info->dst_pitch_offset = info->frontPitchOffset;;    DEALLOCATE_LOCAL(pptNew2);    DEALLOCATE_LOCAL(pboxNew2);    DEALLOCATE_LOCAL(pptNew1);    DEALLOCATE_LOCAL(pboxNew1);    info->accel->NeedToSync = TRUE;#endif /* USE_XAA */}static void RADEONDRIInitGARTValues(RADEONInfoPtr info){    int            s, l;    info->gartOffset = 0;				/* Initialize the CP ring buffer data */    info->ringStart       = info->gartOffset;    info->ringMapSize     = info->ringSize*1024*1024 + radeon_drm_page_size;    info->ringSizeLog2QW  = RADEONMinBits(info->ringSize*1024*1024/8)-1;    info->ringReadOffset  = info->ringStart + info->ringMapSize;    info->ringReadMapSize = radeon_drm_page_size;				/* Reserve space for vertex/indirect buffers */    info->bufStart        = info->ringReadOffset + info->ringReadMapSize;    info->bufMapSize      = info->bufSize*1024*1024;				/* Reserve the rest for GART textures */    info->gartTexStart     = info->bufStart + info->bufMapSize;    s = (info->gartSize*1024*1024 - info->gartTexStart);    l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);    if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;    info->gartTexMapSize   = (s >> l) << l;    info->log2GARTTexGran  = l;}/* Set AGP transfer mode according to requests and constraints */static Bool RADEONSetAgpMode(RADEONInfoPtr info, ScreenPtr pScreen){    unsigned char *RADEONMMIO = info->MMIO;    unsigned long mode   = drmAgpGetMode(info->drmFD);	/* Default mode */    unsigned int  vendor = drmAgpVendorId(info->drmFD);    unsigned int  device = drmAgpDeviceId(info->drmFD);    mode &= ~RADEON_AGP_MODE_MASK;    if ((mode & RADEON_AGPv3_MODE) &&	(INREG(RADEON_AGP_STATUS) & RADEON_AGPv3_MODE)) {	/* only set one mode bit for AGPv3 */	switch (info->agpMode) {	case 8:          mode |= RADEON_AGPv3_8X_MODE; break;	case 4: default: mode |= RADEON_AGPv3_4X_MODE;	}	/*TODO: need to take care of other bits valid for v3 mode	 *      currently these bits are not used in all tested cards.	 */    } else {	switch (info->agpMode) {	case 4:          mode |= RADEON_AGP_4X_MODE;	case 2:          mode |= RADEON_AGP_2X_MODE;	case 1: default: mode |= RADEON_AGP_1X_MODE;	}    }    if (info->agpFastWrite &&	(vendor == PCI_VENDOR_AMD) &&	(device == PCI_CHIP_AMD761)) {	/* Disable fast write for AMD 761 chipset, since they cause	 * lockups when enabled.	 */	info->agpFastWrite = FALSE;	xf86DrvMsg(pScreen->myNum, X_WARNING,		   "[agp] Not enabling Fast Writes on AMD 761 chipset to avoid "		   "lockups");    }    if (info->agpFastWrite) mode |= RADEON_AGP_FW_MODE;    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",	       mode, vendor, device,	       info->PciInfo->vendor,	       info->PciInfo->chipType);    if (drmAgpEnable(info->drmFD, mode) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n");	drmAgpRelease(info->drmFD);	return FALSE;    }    /* Workaround for some hardware bugs */    if (info->ChipFamily < CHIP_FAMILY_R200)	OUTREG(RADEON_AGP_CNTL, INREG(RADEON_AGP_CNTL) | 0x000e0000);				/* Modify the mode if the default mode				 * is not appropriate for this				 * particular combination of graphics				 * card and AGP chipset.				 */    return TRUE;}/* Initialize Radeon's AGP registers */static void RADEONSetAgpBase(RADEONInfoPtr info){    unsigned char *RADEONMMIO = info->MMIO;    OUTREG(RADEON_AGP_BASE, drmAgpBase(info->drmFD));}/* Initialize the AGP state.  Request memory for use in AGP space, and * initialize the Radeon registers to point to that memory. */static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen){    int            ret;    if (drmAgpAcquire(info->drmFD) < 0) {	xf86DrvMsg(pScreen->myNum, X_WARNING, "[agp] AGP not available\n");	return FALSE;    }    if (!RADEONSetAgpMode(info, pScreen))	return FALSE;    RADEONDRIInitGARTValues(info);    if ((ret = drmAgpAlloc(info->drmFD, info->gartSize*1024*1024, 0, NULL,			   &info->agpMemHandle)) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -