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