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

📄 r128_video.c

📁 x.org上有关ati系列显卡最新驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
static voidR128CopyData420(   R128InfoPtr info,   unsigned char *src1,   unsigned char *src2,   unsigned char *src3,   unsigned char *dst1,   unsigned char *dst2,   unsigned char *dst3,   int srcPitch,   int srcPitch2,   int dstPitch,   int h,   int w){   int count;   /* Attempt data transfer with DMA and fall back to memcpy */   if (!R128DMA(info, src1, dst1, srcPitch, dstPitch, h, w)) {       count = h;       while(count--) {	   memcpy(dst1, src1, w);	   src1 += srcPitch;	   dst1 += dstPitch;       }   }   w >>= 1;   h >>= 1;   dstPitch >>= 1;   if (!R128DMA(info, src2, dst2, srcPitch2, dstPitch, h, w)) {       count = h;       while(count--) {	   memcpy(dst2, src2, w);	   src2 += srcPitch2;	   dst2 += dstPitch;       }   }   if (!R128DMA(info, src3, dst3, srcPitch2, dstPitch, h, w)) {       count = h;       while(count--) {	   memcpy(dst3, src3, w);	   src3 += srcPitch2;	   dst3 += dstPitch;       }   }}static FBLinearPtrR128AllocateMemory(   ScrnInfoPtr pScrn,   FBLinearPtr linear,   int size){   ScreenPtr pScreen;   FBLinearPtr new_linear;   if(linear) {	if(linear->size >= size)	   return linear;	if(xf86ResizeOffscreenLinear(linear, size))	   return linear;	xf86FreeOffscreenLinear(linear);   }   pScreen = screenInfo.screens[pScrn->scrnIndex];   new_linear = xf86AllocateOffscreenLinear(pScreen, size, 8,						NULL, NULL, NULL);   if(!new_linear) {	int max_size;	xf86QueryLargestOffscreenLinear(pScreen, &max_size, 8,						PRIORITY_EXTREME);	if(max_size < size)	   return NULL;	xf86PurgeUnlockedOffscreenAreas(pScreen);	new_linear = xf86AllocateOffscreenLinear(pScreen, size, 8,						NULL, NULL, NULL);   }   return new_linear;}static voidR128DisplayVideo422(    ScrnInfoPtr pScrn,    int id,    int offset,    short width, short height,    int pitch,    int left, int right, int top,    BoxPtr dstBox,    short src_w, short src_h,    short drw_w, short drw_h){    R128InfoPtr info = R128PTR(pScrn);    unsigned char *R128MMIO = info->MMIO;    R128PortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;    int v_inc, h_inc, step_by, tmp;    int p1_h_accum_init, p23_h_accum_init;    int p1_v_accum_init;    R128ECP(pScrn, pPriv);    v_inc = (src_h << 20) / drw_h;    h_inc = (src_w << (12 + pPriv->ecp_div)) / drw_w;    step_by = 1;    while(h_inc >= (2 << 12)) {	step_by++;	h_inc >>= 1;    }    /* keep everything in 16.16 */    offset += ((left >> 16) & ~7) << 1;    tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3);    p1_h_accum_init = ((tmp <<  4) & 0x000f8000) |		      ((tmp << 12) & 0xf0000000);    tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc << 2);    p23_h_accum_init = ((tmp <<  4) & 0x000f8000) |		       ((tmp << 12) & 0x70000000);    tmp = (top & 0x0000ffff) + 0x00018000;    p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 0x00000001;    left = (left >> 16) & 7;    OUTREG(R128_OV0_REG_LOAD_CNTL, 1);    while(!(INREG(R128_OV0_REG_LOAD_CNTL) & (1 << 3)));    OUTREG(R128_OV0_H_INC, h_inc | ((h_inc >> 1) << 16));    OUTREG(R128_OV0_STEP_BY, step_by | (step_by << 8));    OUTREG(R128_OV0_Y_X_START, dstBox->x1 | (dstBox->y1 << 16));    OUTREG(R128_OV0_Y_X_END,   dstBox->x2 | (dstBox->y2 << 16));    OUTREG(R128_OV0_V_INC, v_inc);    OUTREG(R128_OV0_P1_BLANK_LINES_AT_TOP, 0x00000fff | ((src_h - 1) << 16));    OUTREG(R128_OV0_VID_BUF_PITCH0_VALUE, pitch);    OUTREG(R128_OV0_P1_X_START_END, (width - 1) | (left << 16));    left >>= 1; width >>= 1;    OUTREG(R128_OV0_P2_X_START_END, (width - 1) | (left << 16));    OUTREG(R128_OV0_P3_X_START_END, (width - 1) | (left << 16));    OUTREG(R128_OV0_VID_BUF0_BASE_ADRS, offset & 0xfffffff0);    OUTREG(R128_OV0_P1_V_ACCUM_INIT, p1_v_accum_init);    OUTREG(R128_OV0_P23_V_ACCUM_INIT, 0);    OUTREG(R128_OV0_P1_H_ACCUM_INIT, p1_h_accum_init);    OUTREG(R128_OV0_P23_H_ACCUM_INIT, p23_h_accum_init);    if(id == FOURCC_UYVY)       OUTREG(R128_OV0_SCALE_CNTL, 0x41FF8C03);    else       OUTREG(R128_OV0_SCALE_CNTL, 0x41FF8B03);    OUTREG(R128_OV0_REG_LOAD_CNTL, 0);}static voidR128DisplayVideo420(    ScrnInfoPtr pScrn,    short width, short height,    int pitch,    int offset1, int offset2, int offset3,    int left, int right, int top,    BoxPtr dstBox,    short src_w, short src_h,    short drw_w, short drw_h){    R128InfoPtr info = R128PTR(pScrn);    unsigned char *R128MMIO = info->MMIO;    R128PortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;    int v_inc, h_inc, step_by, tmp, leftUV;    int p1_h_accum_init, p23_h_accum_init;    int p1_v_accum_init, p23_v_accum_init;    v_inc = (src_h << 20) / drw_h;    h_inc = (src_w << (12 + pPriv->ecp_div)) / drw_w;    step_by = 1;    while(h_inc >= (2 << 12)) {	step_by++;	h_inc >>= 1;    }    /* keep everything in 16.16 */    offset1 += (left >> 16) & ~15;    offset2 += (left >> 17) & ~15;    offset3 += (left >> 17) & ~15;    tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3);    p1_h_accum_init = ((tmp <<  4) & 0x000f8000) |		      ((tmp << 12) & 0xf0000000);    tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc << 2);    p23_h_accum_init = ((tmp <<  4) & 0x000f8000) |		       ((tmp << 12) & 0x70000000);    tmp = (top & 0x0000ffff) + 0x00018000;    p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 0x00000001;    tmp = ((top >> 1) & 0x0000ffff) + 0x00018000;    p23_v_accum_init = ((tmp << 4) & 0x01ff8000) | 0x00000001;    leftUV = (left >> 17) & 15;    left = (left >> 16) & 15;    OUTREG(R128_OV0_REG_LOAD_CNTL, 1);    while(!(INREG(R128_OV0_REG_LOAD_CNTL) & (1 << 3)));    OUTREG(R128_OV0_H_INC, h_inc | ((h_inc >> 1) << 16));    OUTREG(R128_OV0_STEP_BY, step_by | (step_by << 8));    OUTREG(R128_OV0_Y_X_START, dstBox->x1 | (dstBox->y1 << 16));    OUTREG(R128_OV0_Y_X_END,   dstBox->x2 | (dstBox->y2 << 16));    OUTREG(R128_OV0_V_INC, v_inc);    OUTREG(R128_OV0_P1_BLANK_LINES_AT_TOP, 0x00000fff | ((src_h - 1) << 16));    src_h = (src_h + 1) >> 1;    OUTREG(R128_OV0_P23_BLANK_LINES_AT_TOP, 0x000007ff | ((src_h - 1) << 16));    OUTREG(R128_OV0_VID_BUF_PITCH0_VALUE, pitch);    OUTREG(R128_OV0_VID_BUF_PITCH1_VALUE, pitch >> 1);    OUTREG(R128_OV0_P1_X_START_END, (width - 1) | (left << 16));    width >>= 1;    OUTREG(R128_OV0_P2_X_START_END, (width - 1) | (leftUV << 16));    OUTREG(R128_OV0_P3_X_START_END, (width - 1) | (leftUV << 16));    OUTREG(R128_OV0_VID_BUF0_BASE_ADRS, offset1 & 0xfffffff0);    OUTREG(R128_OV0_VID_BUF1_BASE_ADRS, (offset2 & 0xfffffff0) | 0x00000001);    OUTREG(R128_OV0_VID_BUF2_BASE_ADRS, (offset3 & 0xfffffff0) | 0x00000001);    OUTREG(R128_OV0_P1_V_ACCUM_INIT, p1_v_accum_init);    OUTREG(R128_OV0_P23_V_ACCUM_INIT, p23_v_accum_init);    OUTREG(R128_OV0_P1_H_ACCUM_INIT, p1_h_accum_init);    OUTREG(R128_OV0_P23_H_ACCUM_INIT, p23_h_accum_init);    OUTREG(R128_OV0_SCALE_CNTL, 0x41FF8A03);    OUTREG(R128_OV0_REG_LOAD_CNTL, 0);}static intR128PutImage(  ScrnInfoPtr pScrn,  short src_x, short src_y,  short drw_x, short drw_y,  short src_w, short src_h,  short drw_w, short drw_h,  int id, unsigned char* buf,  short width, short height,  Bool Sync,  RegionPtr clipBoxes, pointer data,  DrawablePtr pDraw){   R128InfoPtr info = R128PTR(pScrn);   R128PortPrivPtr pPriv = (R128PortPrivPtr)data;   INT32 xa, xb, ya, yb;   int new_size, offset, s1offset, s2offset, s3offset;   int srcPitch, srcPitch2, dstPitch;   int d1line, d2line, d3line, d1offset, d2offset, d3offset;   int top, left, npixels, nlines, bpp;   BoxRec dstBox;   CARD32 tmp;#if X_BYTE_ORDER == X_BIG_ENDIAN   unsigned char *R128MMIO = info->MMIO;   CARD32 config_cntl = INREG(R128_CONFIG_CNTL);   /* We need to disable byte swapping, or the data gets mangled */   OUTREG(R128_CONFIG_CNTL, config_cntl &	  ~(APER_0_BIG_ENDIAN_16BPP_SWAP | APER_0_BIG_ENDIAN_32BPP_SWAP));#endif   /*    * s1offset, s2offset, s3offset - byte offsets to the Y, U and V planes    *                                of the source.    *    * d1offset, d2offset, d3offset - byte offsets to the Y, U and V planes    *                                of the destination.    *    * offset - byte offset within the framebuffer to where the destination    *          is stored.    *    * d1line, d2line, d3line - byte offsets within the destination to the    *                          first displayed scanline in each plane.    *    */   if(src_w > (drw_w << 4))	drw_w = src_w >> 4;   if(src_h > (drw_h << 4))	drw_h = src_h >> 4;   /* Clip */   xa = src_x;   xb = src_x + src_w;   ya = src_y;   yb = src_y + src_h;   dstBox.x1 = drw_x;   dstBox.x2 = drw_x + drw_w;   dstBox.y1 = drw_y;   dstBox.y2 = drw_y + drw_h;   if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb,			     clipBoxes, width, height))	return Success;   dstBox.x1 -= pScrn->frameX0;   dstBox.x2 -= pScrn->frameX0;   dstBox.y1 -= pScrn->frameY0;   dstBox.y2 -= pScrn->frameY0;   bpp = pScrn->bitsPerPixel >> 3;   switch(id) {   case FOURCC_YV12:   case FOURCC_I420:	srcPitch = (width + 3) & ~3;	srcPitch2 = ((width >> 1) + 3) & ~3;	dstPitch = (width + 31) & ~31;  /* of luma */	new_size = ((dstPitch * (height + (height >> 1))) + bpp - 1) / bpp;	s1offset = 0;	s2offset = srcPitch * height;	s3offset = (srcPitch2 * (height >> 1)) + s2offset;	break;   case FOURCC_UYVY:   case FOURCC_YUY2:   default:	srcPitch = width << 1;	srcPitch2 = 0;	dstPitch = ((width << 1) + 15) & ~15;	new_size = ((dstPitch * height) + bpp - 1) / bpp;	s1offset = 0;	s2offset = 0;	s3offset = 0;	break;   }   if(!(pPriv->linear = R128AllocateMemory(pScrn, pPriv->linear,		pPriv->doubleBuffer ? (new_size << 1) : new_size)))   {	return BadAlloc;   }   pPriv->currentBuffer ^= 1;    /* copy data */   top = ya >> 16;   left = (xa >> 16) & ~1;   npixels = ((((xb + 0xffff) >> 16) + 1) & ~1) - left;   offset = pPriv->linear->offset * bpp;   if(pPriv->doubleBuffer)	offset += pPriv->currentBuffer * new_size * bpp;   switch(id) {    case FOURCC_YV12:    case FOURCC_I420:	d1line = top * dstPitch;	d2line = (height * dstPitch) + ((top >> 1) * (dstPitch >> 1));	d3line = d2line + ((height >> 1) * (dstPitch >> 1));	top &= ~1;	d1offset = (top * dstPitch) + left + offset;	d2offset = d2line + (left >> 1) + offset;	d3offset = d3line + (left >> 1) + offset;	s1offset += (top * srcPitch) + left;	tmp = ((top >> 1) * srcPitch2) + (left >> 1);	s2offset += tmp;	s3offset += tmp;	if(id == FOURCC_YV12) {	   tmp = s2offset;	   s2offset = s3offset;	   s3offset = tmp;	}	nlines = ((((yb + 0xffff) >> 16) + 1) & ~1) - top;	R128CopyData420(info, buf + s1offset, buf + s2offset, buf + s3offset,			info->FB+d1offset, info->FB+d2offset, info->FB+d3offset,			srcPitch, srcPitch2, dstPitch, nlines, npixels);	break;    case FOURCC_UYVY:    case FOURCC_YUY2:    default:	left <<= 1;	d1line = top * dstPitch;	d2line = 0;	d3line = 0;	d1offset = d1line + left + offset;	d2offset = 0;	d3offset = 0;	s1offset += (top * srcPitch) + left;	nlines = ((yb + 0xffff) >> 16) - top;	R128CopyData422(info, buf + s1offset, info->FB + d1offset,			srcPitch, dstPitch, nlines, npixels);	break;    }#if X_BYTE_ORDER == X_BIG_ENDIAN    /* restore byte swapping */    OUTREG(R128_CONFIG_CNTL, config_cntl);#endif    /* update cliplist */    if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) {	REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);	/* draw these */	xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);    }    switch(id) {     case FOURCC_YV12:     case FOURCC_I420:	R128DisplayVideo420(pScrn, width, height, dstPitch,		     offset + d1line, offset + d2line, offset + d3line,		     xa, xb, ya, &dstBox, src_w, src_h, drw_w, drw_h);	break;     case FOURCC_UYVY:     case FOURCC_YUY2:     default:	R128DisplayVideo422(pScrn, id, offset + d1line, width, height, dstPitch,		     xa, xb, ya, &dstBox, src_w, src_h, drw_w, drw_h);	break;    }    pPriv->videoStatus = CLIENT_VIDEO_ON;    info->VideoTimerCallback = R128VideoTimerCallback;    return Success;}static intR128QueryImageAttributes(    ScrnInfoPtr pScrn,    int id,    unsigned short *w, unsigned short *h,    int *pitches, int *offsets){    int size, tmp;    if(*w > MAXWIDTH) *w = MAXWIDTH;    if(*h > MAXHEIGHT) *h = MAXHEIGHT;    *w = (*w + 1) & ~1;    if(offsets) offsets[0] = 0;    switch(id) {    case FOURCC_YV12:    case FOURCC_I420:	*h = (*h + 1) & ~1;	size = (*w + 3) & ~3;	if(pitches) pitches[0] = size;	size *= *h;	if(offsets) offsets[1] = size;	tmp = ((*w >> 1) + 3) & ~3;	if(pitches) pitches[1] = pitches[2] = tmp;	tmp *= (*h >> 1);	size += tmp;	if(offsets) offsets[2] = size;	size += tmp;	break;    case FOURCC_UYVY:    case FOURCC_YUY2:    default:	size = *w << 1;	if(pitches) pitches[0] = size;	size *= *h;	break;    }    return size;}static voidR128VideoTimerCallback(ScrnInfoPtr pScrn, Time now){    R128InfoPtr info = R128PTR(pScrn);    R128PortPrivPtr pPriv = info->adaptor->pPortPrivates[0].ptr;    if(pPriv->videoStatus & TIMER_MASK) {	if(pPriv->videoStatus & OFF_TIMER) {	    if(pPriv->offTime < now) {		unsigned char *R128MMIO = info->MMIO;		OUTREG(R128_OV0_SCALE_CNTL, 0);		pPriv->videoStatus = FREE_TIMER;		pPriv->freeTime = now + FREE_DELAY;	    }	} else {  /* FREE_TIMER */	    if(pPriv->freeTime < now) {		if(pPriv->linear) {		   xf86FreeOffscreenLinear(pPriv->linear);		   pPriv->linear = NULL;		}		pPriv->videoStatus = 0;		info->VideoTimerCallback = NULL;	    }	}    } else  /* shouldn't get here */	info->VideoTimerCallback = NULL;}

⌨️ 快捷键说明

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