xf86-video-ati: Branch 'r6xx-r7xx-support' - 3 commits

Alex Deucher agd5f at kemper.freedesktop.org
Sat Feb 7 10:55:35 PST 2009


 src/r600_exa.c                 |   86 +++++++++++++++++++++++++++--------------
 src/r600_reg.h                 |   14 ++++++
 src/r600_state.h               |    2 
 src/r600_textured_videofuncs.c |   12 +++++
 src/r6xx_accel.c               |   59 +++++++++++++++++++++++++++-
 src/radeon_commonfuncs.c       |    2 
 src/radeon_reg.h               |    2 
 7 files changed, 146 insertions(+), 31 deletions(-)

New commits:
commit 132e4c575dc4675f4995e45f08c53c26bffd999a
Author: Yang Zhao <yang at yangman.ca>
Date:   Sat Feb 7 13:54:51 2009 -0500

    R6xx/R7xx EXA: Optimize overlapping copy
    
    Overlapping copy is now done in chunks proportional to the
    non-overlapping area.
    
    Diagonal overlaps are also handled properly.

diff --git a/src/r600_exa.c b/src/r600_exa.c
index a4e2a4d..fa99a6e 100644
--- a/src/r600_exa.c
+++ b/src/r600_exa.c
@@ -675,8 +675,6 @@ R600PrepareCopy(PixmapPtr pSrc,   PixmapPtr pDst,
 	accel_state->rop = rop;
 	accel_state->planemask = planemask;
 
-	return FALSE;
-
 #ifdef SHOW_VERTEXES
 	ErrorF("same surface!\n");
 #endif
@@ -719,58 +717,90 @@ R600OverlapCopy(PixmapPtr pDst,
     struct radeon_accel_state *accel_state = info->accel_state;
     uint32_t dst_pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel / 8);
     uint32_t dst_offset = exaGetPixmapOffset(pDst) + info->fbLocation + pScrn->fbOffset;
-    int i;
+    int i, chunk;
 
     if (is_overlap(srcX, srcX + w, srcY, srcY + h,
 		   dstX, dstX + w, dstY, dstY + h)) {
-	if (srcY == dstY) { // left/right
+        /* Diagonally offset overlap is reduced to a horizontal-only offset by first
+         * copying the vertically non-overlapping portion, then adjusting coordinates
+         */
+	if (srcX != dstX) { // left/right or diagonal
+            if (srcY > dstY ) { // diagonal up
+                chunk = srcY - dstY;
+                R600DoPrepareCopy(pScrn,
+                                  dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
+                                  dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
+                                  accel_state->rop, accel_state->planemask);
+                R600AppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, w, chunk);
+                R600DoCopy(pScrn);
+
+                h = h - chunk;
+                srcY = srcY + chunk;
+                dstY = dstY + chunk;
+            } else if (srcY < dstY) { // diagonal down
+                chunk = dstY - srcY;
+                R600DoPrepareCopy(pScrn,
+                                  dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
+                                  dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
+                                  accel_state->rop, accel_state->planemask);
+                R600AppendCopyVertex(pScrn, srcX, srcY + h - chunk, dstX, dstY + h - chunk, w, chunk);
+                R600DoCopy(pScrn);
+
+                h = h - chunk;
+            }
+
 	    if (srcX < dstX) { // right
 		// copy right to left
-		for (i = w; i > 0; i--) {
+                chunk = dstX - srcX;
+		for (i = w; i > 0; i -= chunk) {
 		    R600DoPrepareCopy(pScrn,
 				      dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
 				      dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
 				      accel_state->rop, accel_state->planemask);
-
-		    R600AppendCopyVertex(pScrn, srcX + i - 1, srcY, dstX + i - 1, dstY, 1, h);
+		    R600AppendCopyVertex(pScrn, srcX + i - chunk, srcY, dstX + i - chunk, dstY, chunk, h);
 		    R600DoCopy(pScrn);
 		}
 	    } else { //left
 		// copy left to right
-		for (i = 0; i < w; i++) {
+                chunk = srcX - dstX;
+		for (i = 0; i < w; i += chunk) {
 		    R600DoPrepareCopy(pScrn,
 				      dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
 				      dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
 				      accel_state->rop, accel_state->planemask);
 
-		    R600AppendCopyVertex(pScrn, srcX + i, srcY, dstX + i, dstY, 1, h);
+		    R600AppendCopyVertex(pScrn, srcX + i, srcY, dstX + i, dstY, chunk, h);
 		    R600DoCopy(pScrn);
 		}
 	    }
 	} else { //up/down
 	    if (srcY > dstY) { // up
 		// copy top to bottom
-		for (i = 0; i < h; i++) {
-		    R600DoPrepareCopy(pScrn,
-				      dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
-				      dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
-				      accel_state->rop, accel_state->planemask);
-
-		    R600AppendCopyVertex(pScrn, srcX, srcY + i, dstX, dstY + i, w, 1);
-		    R600DoCopy(pScrn);
-		}
+                for (i = 0; i < h; i += chunk) {
+                chunk = srcY - dstY;
+                    R600DoPrepareCopy(pScrn,
+                                      dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
+                                      dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
+                                      accel_state->rop, accel_state->planemask);
+
+                    if (chunk > h - i) chunk = h - i;
+                    R600AppendCopyVertex(pScrn, srcX, srcY + i, dstX, dstY + i, w, chunk);
+                    R600DoCopy(pScrn);
+                }
 	    } else { // down
 		// copy bottom to top
-		for (i = h; i > 0; i--) {
-		    R600DoPrepareCopy(pScrn,
-				      dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
-				      dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
-				      accel_state->rop, accel_state->planemask);
-
-		    R600AppendCopyVertex(pScrn, srcX, srcY + i - 1, dstX, dstY + i - 1, w, 1);
-		    R600DoCopy(pScrn);
-		}
-	    }
+		chunk = dstY - srcY;
+                for (i = h; i > 0; i -= chunk) {
+                    R600DoPrepareCopy(pScrn,
+                                      dst_pitch, pDst->drawable.width, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
+                                      dst_pitch, pDst->drawable.height, dst_offset, pDst->drawable.bitsPerPixel,
+                                      accel_state->rop, accel_state->planemask);
+
+                    if (chunk > i) chunk = i;
+                    R600AppendCopyVertex(pScrn, srcX, srcY + i - chunk, dstX, dstY + i - chunk, w, chunk);
+                    R600DoCopy(pScrn);
+                }
+            }
 	}
     } else {
 	R600DoPrepareCopy(pScrn,
commit 8e9ef8ff581892cbe1b7ea56d48b9a1abd70179d
Author: Pierre Ossman <pierre at ossman.eu>
Date:   Sat Feb 7 18:57:47 2009 +0100

    Xv vsync support on r6xx/r7xx cards.

diff --git a/src/r600_reg.h b/src/r600_reg.h
index dfe4703..9036e2a 100644
--- a/src/r600_reg.h
+++ b/src/r600_reg.h
@@ -115,4 +115,18 @@ enum {
     IT_SURFACE_BASE_UPDATE               = 0x73,
 } ;
 
+/* IT_WAIT_REG_MEM operation encoding */
+
+#define IT_WAIT_ALWAYS          (0<<0)
+#define IT_WAIT_LT              (1<<0)
+#define IT_WAIT_LE              (2<<0)
+#define IT_WAIT_EQ              (3<<0)
+#define IT_WAIT_NE              (4<<0)
+#define IT_WAIT_GE              (5<<0)
+#define IT_WAIT_GT              (6<<0)
+#define IT_WAIT_REG             (0<<4)
+#define IT_WAIT_MEM             (1<<4)
+
+#define IT_WAIT_ADDR(x)         ((x) >> 2)
+
 #endif
diff --git a/src/r600_state.h b/src/r600_state.h
index bf9cdb5..9efd557 100644
--- a/src/r600_state.h
+++ b/src/r600_state.h
@@ -194,6 +194,8 @@ set_render_target(ScrnInfoPtr pScrn, drmBufPtr ib, cb_config_t *cb_conf);
 void
 cp_set_surface_sync(ScrnInfoPtr pScrn, drmBufPtr ib, uint32_t sync_type, uint32_t size, uint64_t mc_addr);
 void
+cp_wait_vline_sync(ScrnInfoPtr pScrn, drmBufPtr ib, PixmapPtr pPix, int crtc, int start, int stop, Bool enable);
+void
 fs_setup(ScrnInfoPtr pScrn, drmBufPtr ib, shader_config_t *fs_conf);
 void
 vs_setup(ScrnInfoPtr pScrn, drmBufPtr ib, shader_config_t *vs_conf);
diff --git a/src/r600_textured_videofuncs.c b/src/r600_textured_videofuncs.c
index 5941899..222740e 100644
--- a/src/r600_textured_videofuncs.c
+++ b/src/r600_textured_videofuncs.c
@@ -268,6 +268,18 @@ R600DisplayTexturedVideo(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv)
     ereg  (accel_state->ib, SPI_INTERP_CONTROL_0,                0);
 
 
+    cp_wait_vline_sync(pScrn, accel_state->ib, pPixmap, 
+                       radeon_covering_crtc_num(pScrn,
+                                                pPriv->drw_x,
+                                                pPriv->drw_x + pPriv->dst_w,
+                                                pPriv->drw_y,
+                                                pPriv->drw_y + pPriv->dst_h,
+                                                pPriv->desired_crtc),
+                       pPriv->drw_y,
+                       pPriv->drw_y + pPriv->dst_h,
+                       pPriv->vsync);
+
+
     accel_state->vb_index = 0;
 
     while (nBox--) {
diff --git a/src/r6xx_accel.c b/src/r6xx_accel.c
index 659d13d..c0e3a2b 100644
--- a/src/r6xx_accel.c
+++ b/src/r6xx_accel.c
@@ -369,14 +369,69 @@ cp_set_surface_sync(ScrnInfoPtr pScrn, drmBufPtr ib, uint32_t sync_type, uint32_
     ereg  (ib, CP_COHER_SIZE,                       cp_coher_size);
     ereg  (ib, CP_COHER_BASE,                       (mc_addr >> 8));
     pack3 (ib, IT_WAIT_REG_MEM, 6);
-    e32   (ib, 0x00000003);						// ME, Register, EqualTo
-    e32   (ib, CP_COHER_STATUS >> 2);
+    e32   (ib, IT_WAIT_REG | IT_WAIT_EQ);
+    e32   (ib, IT_WAIT_ADDR(CP_COHER_STATUS));
     e32   (ib, 0);
     e32   (ib, 0);							// Ref value
     e32   (ib, STATUS_bit);						// Ref mask
     e32   (ib, 10);							// Wait interval
 }
 
+/* inserts a wait for vline in the command stream */
+void cp_wait_vline_sync(ScrnInfoPtr pScrn, drmBufPtr ib, PixmapPtr pPix,
+	int crtc, int start, int stop, Bool enable)
+{
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    xf86CrtcConfigPtr  xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    uint32_t offset;
+    RADEONCrtcPrivatePtr radeon_crtc;
+
+    if (!enable)
+        return;
+
+    if ((crtc < 0) || (crtc > 1))
+        return;
+
+    if (stop < start)
+        return;
+
+    if (!xf86_config->crtc[crtc]->enabled)
+        return;
+
+#ifdef USE_EXA
+    if (info->useEXA)
+        offset = exaGetPixmapOffset(pPix);
+    else
+#endif
+        offset = pPix->devPrivate.ptr - info->FB;
+
+    /* if drawing to front buffer */
+    if (offset != 0)
+        return;
+
+    start = max(start, 0);
+    stop = min(stop, xf86_config->crtc[crtc]->mode.VDisplay);
+
+    if (start > xf86_config->crtc[crtc]->mode.VDisplay)
+        return;
+
+    radeon_crtc = xf86_config->crtc[crtc]->driver_private;
+
+    /* set the VLINE range */
+    ereg(ib, AVIVO_D1MODE_VLINE_START_END + radeon_crtc->crtc_offset,
+         (start << AVIVO_D1MODE_VLINE_START_SHIFT) |
+         (stop << AVIVO_D1MODE_VLINE_END_SHIFT));
+
+    /* tell the CP to poll the VLINE state register */
+    pack3 (ib, IT_WAIT_REG_MEM, 6);
+    e32   (ib, IT_WAIT_REG | IT_WAIT_EQ);
+    e32   (ib, IT_WAIT_ADDR(AVIVO_D1MODE_VLINE_STATUS + radeon_crtc->crtc_offset));
+    e32   (ib, 0);
+    e32   (ib, 0);                          // Ref value
+    e32   (ib, AVIVO_D1MODE_VLINE_STAT);    // Mask
+    e32   (ib, 10);                         // Wait interval
+}
+
 void
 fs_setup(ScrnInfoPtr pScrn, drmBufPtr ib, shader_config_t *fs_conf)
 {
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 17f8575..7f0281a 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -3662,6 +3662,8 @@
 #       define AVIVO_D1MODE_VLINE_START_SHIFT   0
 #       define AVIVO_D1MODE_VLINE_END_SHIFT     16
 #       define AVIVO_D1MODE_VLINE_INV           (1 << 31)
+#define AVIVO_D1MODE_VLINE_STATUS               0x653c
+#       define AVIVO_D1MODE_VLINE_STAT          (1 << 12)
 #define AVIVO_D1MODE_VIEWPORT_START             0x6580
 #define AVIVO_D1MODE_VIEWPORT_SIZE              0x6584
 #define AVIVO_D1MODE_EXT_OVERSCAN_LEFT_RIGHT    0x6588
commit 2222f0fd700f100b2e91fac2babe7d1b53f56c3e
Author: Pierre Ossman <pierre at ossman.eu>
Date:   Sat Feb 7 18:56:42 2009 +0100

    Fix bad range adjustment in VLINE code.

diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c
index 7e00384..d69a9d8 100644
--- a/src/radeon_commonfuncs.c
+++ b/src/radeon_commonfuncs.c
@@ -659,7 +659,7 @@ void FUNC_NAME(RADEONWaitForVLine)(ScrnInfoPtr pScrn, PixmapPtr pPix,
 	return;
 
     start = max(start, 0);
-    stop = max(stop, xf86_config->crtc[crtc]->mode.VDisplay);
+    stop = min(stop, xf86_config->crtc[crtc]->mode.VDisplay);
 
     if (start > xf86_config->crtc[crtc]->mode.VDisplay)
 	return;


More information about the xorg-commit mailing list