summaryrefslogtreecommitdiff
path: root/src/radeon_video.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/radeon_video.c')
-rw-r--r--src/radeon_video.c285
1 files changed, 219 insertions, 66 deletions
diff --git a/src/radeon_video.c b/src/radeon_video.c
index bdabc316..f21e3af5 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -1941,23 +1941,96 @@ static struct {
static void
RADEONCopyData(
+ ScrnInfoPtr pScrn,
unsigned char *src,
unsigned char *dst,
int srcPitch,
int dstPitch,
int h,
- int w
+ int w,
+ int bpp
){
- w <<= 1;
- while(h--) {
- memcpy(dst, src, w);
- src += srcPitch;
- dst += dstPitch;
+#ifdef XF86DRI
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ if ( info->directRenderingEnabled && info->DMAForXv )
+ {
+ CARD8 *buf;
+ CARD32 bufPitch;
+ unsigned int hpass;
+
+ /* Get the byte-swapping right for big endian systems */
+ if ( bpp == 2 )
+ {
+ w *= 2;
+ bpp = 1;
+ }
+
+ while ( buf = RADEONHostDataBlit( pScrn, bpp, w, dstPitch,
+ &bufPitch, &dst, &h, &hpass ) )
+ {
+ RADEONHostDataBlitCopyPass( buf, src, hpass, bufPitch, srcPitch );
+ src += hpass * srcPitch;
+ }
+
+ FLUSH_RING();
+
+ return;
+ }
+ else
+#endif /* XF86DRI */
+ {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ unsigned char *RADEONMMIO = info->MMIO;
+ if ( bpp == 2 )
+ {
+ OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl
+ & ~(RADEON_NONSURF_AP0_SWP_32BPP
+ | RADEON_NONSURF_AP0_SWP_16BPP));
+ }
+ else /* bpp == 4 */
+ {
+ OUTREG(RADEON_SURFACE_CNTL, (info->ModeReg.surface_cntl
+ | RADEON_NONSURF_AP0_SWP_32BPP)
+ & ~RADEON_NONSURF_AP0_SWP_16BPP);
+ }
+#endif
+
+ w *= 2;
+
+ while (h--)
+ {
+ memcpy(dst, src, w);
+ src += srcPitch;
+ dst += dstPitch;
+ }
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ /* restore byte swapping */
+ OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);
+#endif
}
}
+static void RADEON_420_422(
+ unsigned int *d,
+ unsigned char *s1,
+ unsigned char *s2,
+ unsigned char *s3,
+ unsigned int n
+)
+{
+ while ( n ) {
+ *(d++) = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
+ s1+=2; s2++; s3++;
+ n--;
+ }
+}
+
+
static void
RADEONCopyRGB24Data(
+ ScrnInfoPtr pScrn,
unsigned char *src,
unsigned char *dst,
int srcPitch,
@@ -1968,22 +2041,68 @@ RADEONCopyRGB24Data(
CARD32 *dptr;
CARD8 *sptr;
int i,j;
-
+#ifdef XF86DRI
+ RADEONInfoPtr info = RADEONPTR(pScrn);
- for(j=0;j<h;j++){
- dptr=(CARD32 *)(dst+j*dstPitch);
- sptr=src+j*srcPitch;
-
- for(i=w;i>0;i--){
- dptr[0]=((sptr[0])<<24)|((sptr[1])<<16)|(sptr[2]);
- dptr++;
- sptr+=3;
+ if ( info->directRenderingEnabled && info->DMAForXv )
+ {
+ CARD32 bufPitch;
+ unsigned int hpass;
+
+ while ( dptr = ( CARD32* )RADEONHostDataBlit( pScrn, 4, w, dstPitch,
+ &bufPitch, &dst, &h,
+ &hpass ) )
+ {
+ for( j = 0; j < hpass; j++ )
+ {
+ sptr = src;
+
+ for ( i = 0 ; i < w; i++ )
+ {
+ *dptr++ = ( ( *sptr++ ) << 24 ) | ( ( *sptr++ ) << 16 ) |
+ ( *sptr++ );
+ }
+
+ src += hpass * srcPitch;
+ dptr += hpass * bufPitch;
+ }
+ }
+
+ FLUSH_RING();
+
+ return;
+ }
+ else
+#endif /* XF86DRI */
+ {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ unsigned char *RADEONMMIO = info->MMIO;
+ OUTREG(RADEON_SURFACE_CNTL, (info->ModeReg.surface_cntl
+ | RADEON_NONSURF_AP0_SWP_32BPP)
+ & ~RADEON_NONSURF_AP0_SWP_16BPP);
+#endif
+
+ for(j=0;j<h;j++){
+ dptr=(CARD32 *)(dst+j*dstPitch);
+ sptr=src+j*srcPitch;
+
+ for(i=w;i>0;i--){
+ dptr[0]=((sptr[0])<<24)|((sptr[1])<<16)|(sptr[2]);
+ dptr++;
+ sptr+=3;
+ }
}
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ /* restore byte swapping */
+ OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);
+#endif
}
}
static void
RADEONCopyMungedData(
+ ScrnInfoPtr pScrn,
unsigned char *src1,
unsigned char *src2,
unsigned char *src3,
@@ -1994,37 +2113,86 @@ RADEONCopyMungedData(
int h,
int w
){
- CARD32 *dst;
- CARD8 *s1, *s2, *s3;
- int i, j;
-
- w >>= 1;
-
- for(j = 0; j < h; j++) {
- dst = (pointer)dst1;
- s1 = src1; s2 = src2; s3 = src3;
- i = w;
- while(i > 4) {
- dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
- dst[1] = s1[2] | (s1[3] << 16) | (s3[1] << 8) | (s2[1] << 24);
- dst[2] = s1[4] | (s1[5] << 16) | (s3[2] << 8) | (s2[2] << 24);
- dst[3] = s1[6] | (s1[7] << 16) | (s3[3] << 8) | (s2[3] << 24);
- dst += 4; s2 += 4; s3 += 4; s1 += 8;
- i -= 4;
- }
- while(i--) {
- dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
- dst++; s2++; s3++;
- s1 += 2;
+#ifdef XF86DRI
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ if ( info->directRenderingEnabled && info->DMAForXv )
+ {
+ CARD8 *buf;
+ CARD32 y = 0, bufPitch;
+ unsigned int hpass;
+
+ while ( buf = RADEONHostDataBlit( pScrn, 4, w/2, dstPitch,
+ &bufPitch, &dst1, &h, &hpass ) )
+ {
+ while ( hpass-- )
+ {
+ RADEON_420_422( (unsigned int *) buf, src1, src2, src3,
+ bufPitch / 4 );
+ src1 += srcPitch;
+ if ( y & 1 )
+ {
+ src2 += srcPitch2;
+ src3 += srcPitch2;
+ }
+ buf += bufPitch;
+ y++;
+ }
}
- dst1 += dstPitch;
- src1 += srcPitch;
- if(j & 1) {
- src2 += srcPitch2;
- src3 += srcPitch2;
+ FLUSH_RING();
+ }
+ else
+#endif /* XF86DRI */
+ {
+ CARD32 *dst;
+ CARD8 *s1, *s2, *s3;
+ int i, j;
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ unsigned char *RADEONMMIO = info->MMIO;
+ OUTREG(RADEON_SURFACE_CNTL, (info->ModeReg.surface_cntl
+ | RADEON_NONSURF_AP0_SWP_32BPP)
+ & ~RADEON_NONSURF_AP0_SWP_16BPP);
+#endif
+
+ w /= 2;
+
+ for( j = 0; j < h; j++ )
+ {
+ dst = (pointer)dst1;
+ s1 = src1; s2 = src2; s3 = src3;
+ i = w;
+ while( i > 4 )
+ {
+ dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
+ dst[1] = s1[2] | (s1[3] << 16) | (s3[1] << 8) | (s2[1] << 24);
+ dst[2] = s1[4] | (s1[5] << 16) | (s3[2] << 8) | (s2[2] << 24);
+ dst[3] = s1[6] | (s1[7] << 16) | (s3[3] << 8) | (s2[3] << 24);
+ dst += 4; s2 += 4; s3 += 4; s1 += 8;
+ i -= 4;
+ }
+ while( i-- )
+ {
+ dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24);
+ dst++; s2++; s3++;
+ s1 += 2;
+ }
+
+ dst1 += dstPitch;
+ src1 += srcPitch;
+ if( j & 1 )
+ {
+ src2 += srcPitch2;
+ src3 += srcPitch2;
+ }
}
- }
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ /* restore byte swapping */
+ OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);
+#endif
+ }
}
@@ -2472,7 +2640,7 @@ RADEONPutImage(
break;
case FOURCC_YV12:
case FOURCC_I420:
- dstPitch = ((width << 1) + 15) & ~15;
+ dstPitch = ((width << 1) + 63) & ~63;
new_size = ((dstPitch * height) + bpp - 1) / bpp;
srcPitch = (width + 3) & ~3;
s2offset = srcPitch * height;
@@ -2482,7 +2650,7 @@ RADEONPutImage(
case FOURCC_UYVY:
case FOURCC_YUY2:
default:
- dstPitch = ((width << 1) + 15) & ~15;
+ dstPitch = ((width << 1) + 63) & ~63;
new_size = ((dstPitch * height) + bpp - 1) / bpp;
srcPitch = (width << 1);
break;
@@ -2521,14 +2689,9 @@ RADEONPutImage(
s3offset = tmp;
}
nlines = ((((yb + 0xffff) >> 16) + 1) & ~1) - top;
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- OUTREG(RADEON_SURFACE_CNTL, (info->ModeReg.surface_cntl |
- RADEON_NONSURF_AP0_SWP_32BPP)
- & ~RADEON_NONSURF_AP0_SWP_16BPP);
-#endif
- RADEONCopyMungedData(buf + (top * srcPitch) + left, buf + s2offset,
- buf + s3offset, dst_start, srcPitch, srcPitch2,
- dstPitch, nlines, npixels);
+ RADEONCopyMungedData(pScrn, buf + (top * srcPitch) + left,
+ buf + s2offset, buf + s3offset, dst_start,
+ srcPitch, srcPitch2, dstPitch, nlines, npixels);
break;
case FOURCC_RGBT16:
case FOURCC_RGB16:
@@ -2539,32 +2702,22 @@ RADEONPutImage(
buf += (top * srcPitch) + left;
nlines = ((yb + 0xffff) >> 16) - top;
dst_start += left;
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl &
- ~(RADEON_NONSURF_AP0_SWP_32BPP
- | RADEON_NONSURF_AP0_SWP_16BPP));
-#endif
- RADEONCopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
+ RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 2);
break;
case FOURCC_RGBA32:
buf += (top * srcPitch) + left*4;
nlines = ((yb + 0xffff) >> 16) - top;
dst_start += left*4;
- RADEONCopyData(buf, dst_start, srcPitch, dstPitch, nlines, 2*npixels);
+ RADEONCopyData(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels, 4);
break;
case FOURCC_RGB24:
buf += (top * srcPitch) + left*3;
nlines = ((yb + 0xffff) >> 16) - top;
dst_start += left*4;
- RADEONCopyRGB24Data(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
+ RADEONCopyRGB24Data(pScrn, buf, dst_start, srcPitch, dstPitch, nlines, npixels);
break;
}
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- /* restore byte swapping */
- OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);
-#endif
-
/* update cliplist */
if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes))
{