diff options
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | src/radeon.h | 9 | ||||
-rw-r--r-- | src/radeon_accel.c | 66 | ||||
-rw-r--r-- | src/radeon_exa_funcs.c | 14 | ||||
-rw-r--r-- | src/radeon_render.c | 29 | ||||
-rw-r--r-- | src/radeon_video.c | 29 |
6 files changed, 107 insertions, 59 deletions
@@ -1,3 +1,22 @@ +2006-05-01 Michel Dänzer <michel@tungstengraphics.com> + + Bugzilla #6755 <https://bugs.freedesktop.org/show_bug.cgi?id=6755> + Patch #5536 <https://bugs.freedesktop.org/attachment.cgi?id=5536>: + * src/radeon.h: + * src/radeon_accel.c: (RADEONHostDataParams), (RADEONHostDataBlit), + (RADEONHostDataBlitCopyPass): + Change HostDataBlit interface to take dst_offset_pitch and coordinates + instead of just a destination pointer, as the latter is not sufficient + with tiling. + Also, use HW clipping to avoid overwriting destination data outside of + the specified width. + * src/radeon_exa_funcs.c: (RADEONUploadToScreen): + * src/radeon_render.c: (R100SetupTexture), (R200SetupTexture): + * src/radeon_video.c: (RADEONCopyData), (RADEONCopyRGB24Data), + (RADEONCopyMungedData): + Adapt to new HostDataBlit interface. This fixes corruption with + UploadToScreen to the front buffer (from exaPutImage). + 2006-04-29 Michel Dänzer <michel@daenzer.net> * src/radeon_driver.c: (RADEONInitDispBandwidth): diff --git a/src/radeon.h b/src/radeon.h index 29ee2a5..1af9f53 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -799,9 +799,12 @@ extern void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard); extern void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn); extern int RADEONCPStop(ScrnInfoPtr pScrn, RADEONInfoPtr info); -extern CARD8* RADEONHostDataBlit(ScrnInfoPtr pScrn, unsigned int bpp, - unsigned int w, CARD32 dstPitch, - CARD32 *bufPitch, CARD8 **dst, +extern void RADEONHostDataParams(ScrnInfoPtr pScrn, CARD8 *dst, + CARD32 pitch, int cpp, + CARD32 *dstPitchOffset, int *x, int *y); +extern CARD8* RADEONHostDataBlit(ScrnInfoPtr pScrn, unsigned int cpp, + unsigned int w, CARD32 dstPitchOff, + CARD32 *bufPitch, int x, int *y, unsigned int *h, unsigned int *hpass); extern void RADEONHostDataBlitCopyPass(ScrnInfoPtr pScrn, unsigned int bpp, diff --git a/src/radeon_accel.c b/src/radeon_accel.c index 0de3551..9068b7d 100644 --- a/src/radeon_accel.c +++ b/src/radeon_accel.c @@ -604,6 +604,22 @@ void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn) &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. + */ +void +RADEONHostDataParams(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 @@ -612,16 +628,17 @@ void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn) CARD8* RADEONHostDataBlit( ScrnInfoPtr pScrn, - unsigned int bpp, + unsigned int cpp, unsigned int w, - CARD32 dstPitch, + CARD32 dstPitchOff, CARD32 *bufPitch, - CARD8* *dst, + int x, + int *y, unsigned int *h, unsigned int *hpass ){ RADEONInfoPtr info = RADEONPTR( pScrn ); - CARD32 format, dst_offs, dwords, x, y; + CARD32 format, dwords; CARD8 *ret; RING_LOCALS; @@ -630,7 +647,7 @@ RADEONHostDataBlit( return NULL; } - switch ( bpp ) + switch ( cpp ) { case 4: format = RADEON_GMC_DST_32BPP; @@ -638,17 +655,15 @@ RADEONHostDataBlit( break; case 2: format = RADEON_GMC_DST_16BPP; - w = (w + 1) & ~1; - *bufPitch = 2 * w; + *bufPitch = 2 * ((w + 1) & ~1); break; case 1: format = RADEON_GMC_DST_8BPP_CI; - w = (w + 3) & ~3; - *bufPitch = w; + *bufPitch = (w + 3) & ~3; break; default: xf86DrvMsg( pScrn->scrnIndex, X_ERROR, - "%s: Unsupported bpp %d!\n", __func__, bpp ); + "%s: Unsupported cpp %d!\n", __func__, cpp ); return NULL; } @@ -658,10 +673,10 @@ RADEONHostDataBlit( */ if (info->ChipFamily < CHIP_FAMILY_R300) { BEGIN_RING(2); - if (bpp == 2) + if (cpp == 2) OUT_RING_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_HDW); - else if (bpp == 1) + else if (cpp == 1) OUT_RING_REG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_32BIT); else @@ -674,16 +689,13 @@ RADEONHostDataBlit( /*RADEON_PURGE_CACHE(); RADEON_WAIT_UNTIL_IDLE();*/ - dst_offs = *dst - info->FB + info->fbLocation; - *hpass = min( *h, ( ( RADEON_BUFFER_SIZE - 8 * 4 ) / *bufPitch ) ); + *hpass = min( *h, ( ( RADEON_BUFFER_SIZE - 10 * 4 ) / *bufPitch ) ); dwords = *hpass * *bufPitch / 4; - y = ( dst_offs & 1023 ) / dstPitch; - x = ( ( dst_offs & 1023 ) - ( y * dstPitch ) ) / bpp; - - BEGIN_RING( dwords + 8 ); - OUT_RING( CP_PACKET3( RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT, dwords + 8 - 2 ) ); + 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 @@ -691,11 +703,13 @@ RADEONHostDataBlit( | RADEON_DP_SRC_SOURCE_HOST_DATA | RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS ); - OUT_RING( dstPitch << 16 | dst_offs >> 10 ); + 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 | w ); + OUT_RING( *y << 16 | x ); + OUT_RING( *hpass << 16 | (*bufPitch / cpp) ); OUT_RING( dwords ); ret = ( CARD8* )&__head[__count]; @@ -703,7 +717,7 @@ RADEONHostDataBlit( __count += dwords; ADVANCE_RING(); - *dst += *hpass * dstPitch; + *y += *hpass; *h -= *hpass; return ret; @@ -763,7 +777,7 @@ void RADEONCopySwap(CARD8 *dst, CARD8 *src, unsigned int size, int swap) void RADEONHostDataBlitCopyPass( ScrnInfoPtr pScrn, - unsigned int bpp, + unsigned int cpp, CARD8 *dst, CARD8 *src, unsigned int hpass, @@ -780,7 +794,7 @@ RADEONHostDataBlitCopyPass( { #if X_BYTE_ORDER == X_BIG_ENDIAN if (info->ChipFamily >= CHIP_FAMILY_R300) { - switch(bpp) { + switch(cpp) { case 1: RADEONCopySwap(dst, src, hpass * dstPitch, RADEON_HOST_DATA_SWAP_32BIT); @@ -801,7 +815,7 @@ RADEONHostDataBlitCopyPass( { #if X_BYTE_ORDER == X_BIG_ENDIAN if (info->ChipFamily >= CHIP_FAMILY_R300) { - switch(bpp) { + switch(cpp) { case 1: RADEONCopySwap(dst, src, minPitch, RADEON_HOST_DATA_SWAP_32BIT); diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c index c443ec3..16d3f5d 100644 --- a/src/radeon_exa_funcs.c +++ b/src/radeon_exa_funcs.c @@ -219,7 +219,7 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h, unsigned int bpp = pDst->drawable.bitsPerPixel; #ifdef ACCEL_CP unsigned int hpass; - CARD32 buf_pitch; + CARD32 buf_pitch, dst_pitch_off; #endif #if X_BYTE_ORDER == X_BIG_ENDIAN unsigned char *RADEONMMIO = info->MMIO; @@ -234,21 +234,21 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h, return FALSE; #ifdef ACCEL_CP - if (info->directRenderingEnabled) { + if (info->directRenderingEnabled && + RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_off)) { CARD8 *buf; int cpp = bpp / 8; ACCEL_PREAMBLE(); - dst += (x * cpp) + (y * dst_pitch); RADEON_SWITCH_TO_2D(); while ((buf = RADEONHostDataBlit(pScrn, - cpp, w, dst_pitch, &buf_pitch, - &dst, &h, &hpass)) != 0) { - RADEONHostDataBlitCopyPass(pScrn, cpp, buf, (unsigned char *)src, + cpp, w, dst_pitch_off, &buf_pitch, + x, &y, (unsigned int*)&h, &hpass)) != 0) { + RADEONHostDataBlitCopyPass(pScrn, cpp, buf, (CARD8 *)src, hpass, buf_pitch, src_pitch); src += hpass * src_pitch; } - + exaMarkSync(pDst->drawable.pScreen); return TRUE; } diff --git a/src/radeon_render.c b/src/radeon_render.c index e444bd2..9e3529e 100644 --- a/src/radeon_render.c +++ b/src/radeon_render.c @@ -383,9 +383,10 @@ static Bool FUNC_NAME(R100SetupTexture)( RADEONInfoPtr info = RADEONPTR(pScrn); CARD8 *dst; CARD32 tex_size = 0, txformat; - int dst_pitch, offset, size, i, tex_bytepp; + int dst_pitch, offset, size, tex_bytepp; #ifdef ACCEL_CP - CARD32 buf_pitch; + CARD32 buf_pitch, dst_pitch_off; + int x, y; unsigned int hpass; CARD8 *tmp_dst; #endif @@ -430,11 +431,13 @@ static Bool FUNC_NAME(R100SetupTexture)( #ifdef ACCEL_CP + RADEONHostDataParams( pScrn, dst, dst_pitch, tex_bytepp, &dst_pitch_off, &x, &y ); + while ( height ) { tmp_dst = RADEONHostDataBlit( pScrn, tex_bytepp, width, - dst_pitch, &buf_pitch, - &dst, &height, &hpass); + dst_pitch_off, &buf_pitch, + x, &y, &height, &hpass ); RADEONHostDataBlitCopyPass( pScrn, tex_bytepp, tmp_dst, src, hpass, buf_pitch, src_pitch ); src += hpass * src_pitch; @@ -445,12 +448,10 @@ static Bool FUNC_NAME(R100SetupTexture)( #else - i = height; - if (info->accel->NeedToSync) info->accel->Sync(pScrn); - while(i--) { + while (height--) { memcpy(dst, src, width * tex_bytepp); src += src_pitch; dst += dst_pitch; @@ -715,9 +716,10 @@ static Bool FUNC_NAME(R200SetupTexture)( RADEONInfoPtr info = RADEONPTR(pScrn); CARD8 *dst; CARD32 tex_size = 0, txformat; - int dst_pitch, offset, size, i, tex_bytepp; + int dst_pitch, offset, size, tex_bytepp; #ifdef ACCEL_CP - CARD32 buf_pitch; + CARD32 buf_pitch, dst_pitch_off; + int x, y; unsigned int hpass; CARD8 *tmp_dst; #endif @@ -762,11 +764,13 @@ static Bool FUNC_NAME(R200SetupTexture)( #ifdef ACCEL_CP + RADEONHostDataParams( pScrn, dst, dst_pitch, tex_bytepp, &dst_pitch_off, &x, &y ); + while ( height ) { tmp_dst = RADEONHostDataBlit( pScrn, tex_bytepp, width, - dst_pitch, &buf_pitch, - &dst, &height, &hpass ); + dst_pitch_off, &buf_pitch, + x, &y, &height, &hpass ); RADEONHostDataBlitCopyPass( pScrn, tex_bytepp, tmp_dst, src, hpass, buf_pitch, src_pitch ); src += hpass * src_pitch; @@ -777,11 +781,10 @@ static Bool FUNC_NAME(R200SetupTexture)( #else - i = height; if (info->accel->NeedToSync) info->accel->Sync(pScrn); - while(i--) { + while (height--) { memcpy(dst, src, width * tex_bytepp); src += src_pitch; dst += dst_pitch; diff --git a/src/radeon_video.c b/src/radeon_video.c index 8c92621..d1e5f3f 100644 --- a/src/radeon_video.c +++ b/src/radeon_video.c @@ -2048,7 +2048,8 @@ RADEONCopyData( if ( info->directRenderingEnabled && info->DMAForXv ) { CARD8 *buf; - CARD32 bufPitch; + CARD32 bufPitch, dstPitchOff; + int x, y; unsigned int hpass; /* Get the byte-swapping right for big endian systems */ @@ -2058,8 +2059,10 @@ RADEONCopyData( bpp = 1; } - while ( buf = RADEONHostDataBlit( pScrn, bpp, w, dstPitch, - &bufPitch, &dst, &h, &hpass ) ) + RADEONHostDataParams( pScrn, dst, dstPitch, bpp, &dstPitchOff, &x, &y ); + + while ( (buf = RADEONHostDataBlit( pScrn, bpp, w, dstPitchOff, &bufPitch, + x, &y, &h, &hpass )) ) { RADEONHostDataBlitCopyPass( pScrn, bpp, buf, src, hpass, bufPitch, srcPitch ); @@ -2140,14 +2143,17 @@ RADEONCopyRGB24Data( if ( info->directRenderingEnabled && info->DMAForXv ) { - CARD32 bufPitch; + CARD32 bufPitch, dstPitchOff; + int x, y; unsigned int hpass; /* XXX Fix endian flip on R300 */ - while ( dptr = ( CARD32* )RADEONHostDataBlit( pScrn, 4, w, dstPitch, - &bufPitch, &dst, &h, - &hpass ) ) + RADEONHostDataParams( pScrn, dst, dstPitch, 4, &dstPitchOff, &x, &y ); + + while ( (dptr = ( CARD32* )RADEONHostDataBlit( pScrn, 4, w, dstPitch, + &bufPitch, x, &y, &h, + &hpass )) ) { for( j = 0; j < hpass; j++ ) { @@ -2215,13 +2221,16 @@ RADEONCopyMungedData( if ( info->directRenderingEnabled && info->DMAForXv ) { CARD8 *buf; - CARD32 y = 0, bufPitch; + CARD32 y = 0, bufPitch, dstPitchOff; + int blitX, blitY; unsigned int hpass; /* XXX Fix endian flip on R300 */ - while ( buf = RADEONHostDataBlit( pScrn, 4, w/2, dstPitch, - &bufPitch, &dst1, &h, &hpass ) ) + RADEONHostDataParams( pScrn, dst1, dstPitch, 4, &dstPitchOff, &blitX, &blitY ); + + while ( (buf = RADEONHostDataBlit( pScrn, 4, w/2, dstPitchOff, &bufPitch, + blitX, &blitY, &h, &hpass )) ) { while ( hpass-- ) { |