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

📄 radeon_accel.c

📁 x.org上有关ati系列显卡最新驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
    stop.flush = 0;    i = 0;    do {	ret = drmCommandWrite(info->drmFD, DRM_RADEON_CP_STOP, &stop,			      sizeof(drmRadeonCPStop));    } while (ret && errno == EBUSY && i++ < RADEON_IDLE_RETRY);    if (ret == 0) {	return 0;    } else if (errno != EBUSY) {	return -errno;    }    stop.idle = 0;    if (drmCommandWrite(info->drmFD, DRM_RADEON_CP_STOP,			&stop, sizeof(drmRadeonCPStop))) {	return -errno;    } else {	return 0;    }}/* Get an indirect buffer for the CP 2D acceleration commands  */drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn){    RADEONInfoPtr  info = RADEONPTR(pScrn);    drmDMAReq      dma;    drmBufPtr      buf = NULL;    int            indx = 0;    int            size = 0;    int            i = 0;    int            ret;#if 0    /* FIXME: pScrn->pScreen has not been initialized when this is first     * called from RADEONSelectBuffer via RADEONDRICPInit.  We could use     * the screen index from pScrn, which is initialized, and then get     * the screen from screenInfo.screens[index], but that is a hack.     */    dma.context = DRIGetContext(pScrn->pScreen);#else    /* This is the X server's context */    dma.context = 0x00000001;#endif    dma.send_count    = 0;    dma.send_list     = NULL;    dma.send_sizes    = NULL;    dma.flags         = 0;    dma.request_count = 1;    dma.request_size  = RADEON_BUFFER_SIZE;    dma.request_list  = &indx;    dma.request_sizes = &size;    dma.granted_count = 0;    while (1) {	do {	    ret = drmDMA(info->drmFD, &dma);	    if (ret && ret != -EBUSY) {		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,			   "%s: CP GetBuffer %d\n", __FUNCTION__, ret);	    }	} while ((ret == -EBUSY) && (i++ < RADEON_TIMEOUT));	if (ret == 0) {	    buf = &info->buffers->list[indx];	    buf->used = 0;	    if (RADEON_VERBOSE) {		xf86DrvMsg(pScrn->scrnIndex, X_INFO,			   "   GetBuffer returning %d %p\n",			   buf->idx, buf->address);	    }	    return buf;	}	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,		   "GetBuffer timed out, resetting engine...\n");	RADEONEngineReset(pScrn);	RADEONEngineRestore(pScrn);	/* Always restart the engine when doing CP 2D acceleration */	RADEONCP_RESET(pScrn, info);	RADEONCP_START(pScrn, info);    }}/* Flush the indirect buffer to the kernel for submission to the card */void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard){    RADEONInfoPtr      info   = RADEONPTR(pScrn);    drmBufPtr          buffer = info->indirectBuffer;    int                start  = info->indirectStart;    drmRadeonIndirect  indirect;    if (!buffer) return;    if (start == buffer->used && !discard) return;    if (RADEON_VERBOSE) {	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Flushing buffer %d\n",		   buffer->idx);    }    indirect.idx     = buffer->idx;    indirect.start   = start;    indirect.end     = buffer->used;    indirect.discard = discard;    drmCommandWriteRead(info->drmFD, DRM_RADEON_INDIRECT,			&indirect, sizeof(drmRadeonIndirect));    if (discard) {	info->indirectBuffer = RADEONCPGetBuffer(pScrn);	info->indirectStart  = 0;    } else {	/* Start on a double word boundary */	info->indirectStart  = buffer->used = (buffer->used + 7) & ~7;	if (RADEON_VERBOSE) {	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "   Starting at %d\n",		       info->indirectStart);	}    }}/* Flush and release the indirect buffer */void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn){    RADEONInfoPtr      info   = RADEONPTR(pScrn);    drmBufPtr          buffer = info->indirectBuffer;    int                start  = info->indirectStart;    drmRadeonIndirect  indirect;    info->indirectBuffer = NULL;    info->indirectStart  = 0;    if (!buffer) return;    if (RADEON_VERBOSE) {	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Releasing buffer %d\n",		   buffer->idx);    }    indirect.idx     = buffer->idx;    indirect.start   = start;    indirect.end     = buffer->used;    indirect.discard = 1;    drmCommandWriteRead(info->drmFD, DRM_RADEON_INDIRECT,			&indirect, sizeof(drmRadeonIndirect));}/** \brief Calculate HostDataBlit parameters from pointer and pitch * * This is a helper for the trivial HostDataBlit users that don't need to worry * about tiling etc. */voidRADEONHostDataParams(ScrnInfoPtr pScrn, CARD8 *dst, CARD32 pitch, int cpp,		     CARD32 *dstPitchOff, int *x, int *y){    RADEONInfoPtr info = RADEONPTR( pScrn );    CARD32 dstOffs = dst - info->FB + info->fbLocation;    *dstPitchOff = pitch << 16 | (dstOffs & ~RADEON_BUFFER_ALIGN) >> 10;    *y = ( dstOffs & RADEON_BUFFER_ALIGN ) / pitch;    *x = ( ( dstOffs & RADEON_BUFFER_ALIGN ) - ( *y * pitch ) ) / cpp;}/* Set up a hostdata blit to transfer data from system memory to the * framebuffer. Returns the address where the data can be written to and sets * the dstPitch and hpass variables as required. */CARD8*RADEONHostDataBlit(    ScrnInfoPtr pScrn,    unsigned int cpp,    unsigned int w,    CARD32 dstPitchOff,    CARD32 *bufPitch,    int x,    int *y,    unsigned int *h,    unsigned int *hpass){    RADEONInfoPtr info = RADEONPTR( pScrn );    CARD32 format, dwords;    CARD8 *ret;    RING_LOCALS;    if ( *h == 0 )    {	return NULL;    }    switch ( cpp )    {    case 4:	format = RADEON_GMC_DST_32BPP;	*bufPitch = 4 * w;	break;    case 2:	format = RADEON_GMC_DST_16BPP;	*bufPitch = 2 * ((w + 1) & ~1);	break;    case 1:	format = RADEON_GMC_DST_8BPP_CI;	*bufPitch = (w + 3) & ~3;	break;    default:	xf86DrvMsg( pScrn->scrnIndex, X_ERROR,		    "%s: Unsupported cpp %d!\n", __func__, cpp );	return NULL;    }#if X_BYTE_ORDER == X_BIG_ENDIAN    /* Swap doesn't work on R300 and later, it's handled during the     * copy to ind. buffer pass     */    if (info->ChipFamily < CHIP_FAMILY_R300) {        BEGIN_RING(2);	if (cpp == 2)	    OUT_RING_REG(RADEON_RBBM_GUICNTL,			 RADEON_HOST_DATA_SWAP_HDW);	else if (cpp == 1)	    OUT_RING_REG(RADEON_RBBM_GUICNTL,			 RADEON_HOST_DATA_SWAP_32BIT);	else	    OUT_RING_REG(RADEON_RBBM_GUICNTL,			 RADEON_HOST_DATA_SWAP_NONE);	ADVANCE_RING();    }#endif    /*RADEON_PURGE_CACHE();      RADEON_WAIT_UNTIL_IDLE();*/    *hpass = min( *h, ( ( RADEON_BUFFER_SIZE - 10 * 4 ) / *bufPitch ) );    dwords = *hpass * *bufPitch / 4;    BEGIN_RING( dwords + 10 );    OUT_RING( CP_PACKET3( RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT, dwords + 10 - 2 ) );    OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL	    | RADEON_GMC_DST_CLIPPING	    | RADEON_GMC_BRUSH_NONE	    | format	    | RADEON_GMC_SRC_DATATYPE_COLOR	    | RADEON_ROP3_S	    | RADEON_DP_SRC_SOURCE_HOST_DATA	    | RADEON_GMC_CLR_CMP_CNTL_DIS	    | RADEON_GMC_WR_MSK_DIS );    OUT_RING( dstPitchOff );    OUT_RING( (*y << 16) | x );    OUT_RING( ((*y + *hpass) << 16) | (x + w) );    OUT_RING( 0xffffffff );    OUT_RING( 0xffffffff );    OUT_RING( *y << 16 | x );    OUT_RING( *hpass << 16 | (*bufPitch / cpp) );    OUT_RING( dwords );    ret = ( CARD8* )&__head[__count];    __count += dwords;    ADVANCE_RING();    *y += *hpass;    *h -= *hpass;    return ret;}void RADEONCopySwap(CARD8 *dst, CARD8 *src, unsigned int size, int swap){    switch(swap) {    case RADEON_HOST_DATA_SWAP_HDW:        {	    unsigned int *d = (unsigned int *)dst;	    unsigned int *s = (unsigned int *)src;	    unsigned int nwords = size >> 2;	    for (; nwords > 0; --nwords, ++d, ++s)		*d = ((*s & 0xffff) << 16) | ((*s >> 16) & 0xffff);	    return;        }    case RADEON_HOST_DATA_SWAP_32BIT:        {	    unsigned int *d = (unsigned int *)dst;	    unsigned int *s = (unsigned int *)src;	    unsigned int nwords = size >> 2;	    for (; nwords > 0; --nwords, ++d, ++s)#ifdef __powerpc__		asm volatile("stwbrx %0,0,%1" : : "r" (*s), "r" (d));#else		*d = ((*s >> 24) & 0xff) | ((*s >> 8) & 0xff00)			| ((*s & 0xff00) << 8) | ((*s & 0xff) << 24);#endif	    return;        }    case RADEON_HOST_DATA_SWAP_16BIT:        {	    unsigned short *d = (unsigned short *)dst;	    unsigned short *s = (unsigned short *)src;	    unsigned int nwords = size >> 1;	    for (; nwords > 0; --nwords, ++d, ++s)#ifdef __powerpc__		asm volatile("stwbrx %0,0,%1" : : "r" (*s), "r" (d));#else	        *d = ((*s >> 24) & 0xff) | ((*s >> 8) & 0xff00)			| ((*s & 0xff00) << 8) | ((*s & 0xff) << 24);#endif	    return;	}    }    if (src != dst)	    memmove(dst, src, size);}/* Copies a single pass worth of data for a hostdata blit set up by * RADEONHostDataBlit(). */voidRADEONHostDataBlitCopyPass(    ScrnInfoPtr pScrn,    unsigned int cpp,    CARD8 *dst,    CARD8 *src,    unsigned int hpass,    unsigned int dstPitch,    unsigned int srcPitch){#if X_BYTE_ORDER == X_BIG_ENDIAN    RADEONInfoPtr info = RADEONPTR( pScrn );#endif    /* RADEONHostDataBlitCopy can return NULL ! */    if( (dst==NULL) || (src==NULL)) return;    if ( dstPitch == srcPitch )    {#if X_BYTE_ORDER == X_BIG_ENDIAN        if (info->ChipFamily >= CHIP_FAMILY_R300) {	    switch(cpp) {	    case 1:		RADEONCopySwap(dst, src, hpass * dstPitch,			       RADEON_HOST_DATA_SWAP_32BIT);		return;	    case 2:	        RADEONCopySwap(dst, src, hpass * dstPitch,			       RADEON_HOST_DATA_SWAP_HDW);		return;	    }	}#endif	memcpy( dst, src, hpass * dstPitch );    }    else    {	unsigned int minPitch = min( dstPitch, srcPitch );	while ( hpass-- )	{#if X_BYTE_ORDER == X_BIG_ENDIAN            if (info->ChipFamily >= CHIP_FAMILY_R300) {		switch(cpp) {		case 1:		    RADEONCopySwap(dst, src, minPitch,				   RADEON_HOST_DATA_SWAP_32BIT);		    goto next;		case 2:	            RADEONCopySwap(dst, src, minPitch,				   RADEON_HOST_DATA_SWAP_HDW);		    goto next;		}	    }#endif	    memcpy( dst, src, minPitch );#if X_BYTE_ORDER == X_BIG_ENDIAN	next:#endif	    src += srcPitch;	    dst += dstPitch;	}    }}#endifBool RADEONAccelInit(ScreenPtr pScreen){    ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];    RADEONInfoPtr  info  = RADEONPTR(pScrn);#ifdef USE_EXA    if (info->useEXA) {# ifdef XF86DRI	if (info->directRenderingEnabled) {	    if (!RADEONDrawInitCP(pScreen))		return FALSE;	} else# endif /* XF86DRI */	{	    if (!RADEONDrawInitMMIO(pScreen))		return FALSE;	}    }#endif /* USE_EXA */#ifdef USE_XAA    if (!info->useEXA) {	XAAInfoRecPtr  a;	if (!(a = info->accel = XAACreateInfoRec())) {	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "XAACreateInfoRec Error\n");	    return FALSE;	}#ifdef XF86DRI	if (info->directRenderingEnabled)	    RADEONAccelInitCP(pScreen, a);	else#endif /* XF86DRI */	    RADEONAccelInitMMIO(pScreen, a);	RADEONEngineInit(pScrn);	if (!XAAInit(pScreen, a)) {	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "XAAInit Error\n");	    return FALSE;	}    }#endif /* USE_XAA */    return TRUE;}void RADEONInit3DEngine(ScrnInfoPtr pScrn){    RADEONInfoPtr info = RADEONPTR (pScrn);#ifdef XF86DRI    if (info->directRenderingEnabled) {	RADEONSAREAPrivPtr pSAREAPriv;	pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);	pSAREAPriv->ctxOwner = DRIGetContext(pScrn->pScreen);	RADEONInit3DEngineCP(pScrn);    } else#endif	RADEONInit3DEngineMMIO(pScrn);    info->XInited3D = TRUE;}

⌨️ 快捷键说明

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