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

📄 radeon_dri.c

📁 ati driver
💻 C
📖 第 1 页 / 共 4 页
字号:
    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_DEPTH32(d, xa+x, ya+y);		WRITE_DEPTH32(xb+x, yb+y, d);	    }	}	break;    default:	break;    }}/* 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){    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;    /* 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;    }    (*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;	RADEONSelectBuffer(pScrn, RADEON_BACK);	(*info->accel->SubsequentScreenToScreenCopy)(pScrn,						     xa, ya,						     destx, desty,						     w, h);	if (info->depthMoves) {	    RADEONSelectBuffer(pScrn, RADEON_DEPTH);	    RADEONScreenToScreenCopyDepth(pScrn,					  xa, ya,					  destx, desty,					  w, h);	}    }    RADEONSelectBuffer(pScrn, RADEON_FRONT);    DEALLOCATE_LOCAL(pptNew2);    DEALLOCATE_LOCAL(pboxNew2);    DEALLOCATE_LOCAL(pptNew1);    DEALLOCATE_LOCAL(pboxNew1);    info->accel->NeedToSync = TRUE;}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 + DRM_PAGE_SIZE;    info->ringSizeLog2QW  = RADEONMinBits(info->ringSize*1024*1024/8)-1;    info->ringReadOffset  = info->ringStart + info->ringMapSize;    info->ringReadMapSize = 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 long vendor = drmAgpVendorId(info->drmFD);    unsigned long device = drmAgpDeviceId(info->drmFD);    mode &= ~RADEON_AGP_MODE_MASK;    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) mode |= RADEON_AGP_FW_MODE;        if ((vendor == PCI_VENDOR_AMD) &&	(device == PCI_CHIP_AMD761)) {	/* Disable fast write for AMD 761 chipset, since they cause	 * lockups when enabled.	 */	mode &= ~0x10; /* FIXME: Magic number */    }    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);	drmAgpRelease(info->drmFD);	return FALSE;    }    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[agp] %d kB allocated with handle 0x%08lx\n",	       info->gartSize*1024, info->agpMemHandle);    if (drmAgpBind(info->drmFD,		   info->agpMemHandle, info->gartOffset) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not bind\n");	drmAgpFree(info->drmFD, info->agpMemHandle);	drmAgpRelease(info->drmFD);	return FALSE;    }    if (drmAddMap(info->drmFD, info->ringStart, info->ringMapSize,		  DRM_AGP, DRM_READ_ONLY, &info->ringHandle) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR,		   "[agp] Could not add ring mapping\n");	return FALSE;    }    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[agp] ring handle = 0x%08lx\n", info->ringHandle);    if (drmMap(info->drmFD, info->ringHandle, info->ringMapSize,	       (drmAddressPtr)&info->ring) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not map ring\n");	return FALSE;    }    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[agp] Ring mapped at 0x%08lx\n",	       (unsigned long)info->ring);    if (drmAddMap(info->drmFD, info->ringReadOffset, info->ringReadMapSize,		  DRM_AGP, DRM_READ_ONLY, &info->ringReadPtrHandle) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR,		   "[agp] Could not add ring read ptr mapping\n");	return FALSE;    }    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[agp] ring read ptr handle = 0x%08lx\n",	       info->ringReadPtrHandle);    if (drmMap(info->drmFD, info->ringReadPtrHandle, info->ringReadMapSize,	       (drmAddressPtr)&info->ringReadPtr) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR,		   "[agp] Could not map ring read ptr\n");	return FALSE;    }    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[agp] Ring read ptr mapped at 0x%08lx\n",	       (unsigned long)info->ringReadPtr);    if (drmAddMap(info->drmFD, info->bufStart, info->bufMapSize,		  DRM_AGP, 0, &info->bufHandle) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR,		   "[agp] Could not add vertex/indirect buffers mapping\n");	return FALSE;    }    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[agp] vertex/indirect buffers handle = 0x%08lx\n",	       info->bufHandle);    if (drmMap(info->drmFD, info->bufHandle, info->bufMapSize,	       (drmAddressPtr)&info->buf) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR,		   "[agp] Could not map vertex/indirect buffers\n");	return FALSE;    }    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[agp] Vertex/indirect buffers mapped at 0x%08lx\n",	       (unsigned long)info->buf);    if (drmAddMap(info->drmFD, info->gartTexStart, info->gartTexMapSize,		  DRM_AGP, 0, &info->gartTexHandle) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR,		   "[agp] Could not add GART texture map mapping\n");	return FALSE;    }    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[agp] GART texture map handle = 0x%08lx\n",	       info->gartTexHandle);    if (drmMap(info->drmFD, info->gartTexHandle, info->gartTexMapSize,	       (drmAddressPtr)&info->gartTex) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR,		   "[agp] Could not map GART texture map\n");	return FALSE;    }    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[agp] GART Texture map mapped at 0x%08lx\n",	       (unsigned long)info->gartTex);    RADEONSetAgpBase(info);    return TRUE;}/* Initialize the PCI GART state.  Request memory for use in PCI space, * and initialize the Radeon registers to point to that memory. */static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen){    int  ret;    int  flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL;    ret = drmScatterGatherAlloc(info->drmFD, info->gartSize*1024*1024,				&info->pciMemHandle);    if (ret < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Out of memory (%d)\n", ret);	return FALSE;    }    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[pci] %d kB allocated with handle 0x%08lx\n",	       info->gartSize*1024, info->pciMemHandle);    RADEONDRIInitGARTValues(info);    if (drmAddMap(info->drmFD, info->ringStart, info->ringMapSize,		  DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR,		   "[pci] Could not add ring mapping\n");	return FALSE;    }    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[pci] ring handle = 0x%08lx\n", info->ringHandle);    if (drmMap(info->drmFD, info->ringHandle, info->ringMapSize,	       (drmAddressPtr)&info->ring) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR, "[pci] Could not map ring\n");	return FALSE;    }    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[pci] Ring mapped at 0x%08lx\n",	       (unsigned long)info->ring);    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[pci] Ring contents 0x%08lx\n",	       *(unsigned long *)(pointer)info->ring);    if (drmAddMap(info->drmFD, info->ringReadOffset, info->ringReadMapSize,		  DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR,		   "[pci] Could not add ring read ptr mapping\n");	return FALSE;    }    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[pci] ring read ptr handle = 0x%08lx\n",	       info->ringReadPtrHandle);    if (drmMap(info->drmFD, info->ringReadPtrHandle, info->ringReadMapSize,	       (drmAddressPtr)&info->ringReadPtr) < 0) {	xf86DrvMsg(pScreen->myNum, X_ERROR,		   "[pci] Could not map ring read ptr\n");	return FALSE;    }    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[pci] Ring read ptr mapped at 0x%08lx\n",	       (unsigned long)info->ringReadPtr);    xf86DrvMsg(pScreen->myNum, X_INFO,	       "[pci] Ring read ptr contents 0x%08lx\n",	       *(unsigned long *)(pointer)info->ringReadPtr);    if (drmAddMap(info->drmFD, info->bufStart, info->bufMapSize,		  DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) {

⌨️ 快捷键说明

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