summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Ossman <pierre@ossman.eu>2009-02-07 18:57:47 +0100
committerPierre Ossman <pierre@ossman.eu>2009-02-07 19:04:12 +0100
commit8e9ef8ff581892cbe1b7ea56d48b9a1abd70179d (patch)
tree4075b85979badaba4bb815c51bf6be8d28ca779f
parent2222f0fd700f100b2e91fac2babe7d1b53f56c3e (diff)
Xv vsync support on r6xx/r7xx cards.
-rw-r--r--src/r600_reg.h14
-rw-r--r--src/r600_state.h2
-rw-r--r--src/r600_textured_videofuncs.c12
-rw-r--r--src/r6xx_accel.c59
-rw-r--r--src/radeon_reg.h2
5 files changed, 87 insertions, 2 deletions
diff --git a/src/r600_reg.h b/src/r600_reg.h
index dfe47039..9036e2a5 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 bf9cdb5b..9efd557c 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 5941899a..222740e5 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 659d13da..c0e3a2bb 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 17f8575c..7f0281a7 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