diff options
author | Michel Daenzer <michel@daenzer.net> | 2006-05-01 17:49:41 +0000 |
---|---|---|
committer | Michel Daenzer <michel@daenzer.net> | 2006-05-01 17:49:41 +0000 |
commit | 36c04b88416905b9ae305583e8e34fefdbfafc50 (patch) | |
tree | d2dde51e15d9aed0320c37ff608ef4edf869a3ac | |
parent | b90d3710e67caad0686efab491c2b76ae877920c (diff) |
Bugzilla #6755 <https://bugs.freedesktop.org/show_bug.cgi?id=6755> Patch
#5536 <https://bugs.freedesktop.org/attachment.cgi?id=5536>:
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.
Adapt to new HostDataBlit interface. This fixes corruption with
UploadToScreen to the front buffer (from exaPutImage).
-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 29ee2a59..1af9f53c 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 0de3551d..9068b7d6 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 c443ec30..16d3f5d5 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 e444bd2c..9e3529e3 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 8c926211..d1e5f3f3 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-- ) { |