summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog19
-rw-r--r--src/radeon.h9
-rw-r--r--src/radeon_accel.c66
-rw-r--r--src/radeon_exa_funcs.c14
-rw-r--r--src/radeon_render.c29
-rw-r--r--src/radeon_video.c29
6 files changed, 107 insertions, 59 deletions
diff --git a/ChangeLog b/ChangeLog
index d4863be8..fa3471f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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-- )
{