summaryrefslogtreecommitdiff
path: root/src/r6xx_accel.c
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 /src/r6xx_accel.c
parent2222f0fd700f100b2e91fac2babe7d1b53f56c3e (diff)
Xv vsync support on r6xx/r7xx cards.
Diffstat (limited to 'src/r6xx_accel.c')
-rw-r--r--src/r6xx_accel.c59
1 files changed, 57 insertions, 2 deletions
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)
{