diff options
author | Pierre Ossman <pierre@ossman.eu> | 2009-02-07 18:57:47 +0100 |
---|---|---|
committer | Pierre Ossman <pierre@ossman.eu> | 2009-02-07 19:04:12 +0100 |
commit | 8e9ef8ff581892cbe1b7ea56d48b9a1abd70179d (patch) | |
tree | 4075b85979badaba4bb815c51bf6be8d28ca779f /src | |
parent | 2222f0fd700f100b2e91fac2babe7d1b53f56c3e (diff) |
Xv vsync support on r6xx/r7xx cards.
Diffstat (limited to 'src')
-rw-r--r-- | src/r600_reg.h | 14 | ||||
-rw-r--r-- | src/r600_state.h | 2 | ||||
-rw-r--r-- | src/r600_textured_videofuncs.c | 12 | ||||
-rw-r--r-- | src/r6xx_accel.c | 59 | ||||
-rw-r--r-- | src/radeon_reg.h | 2 |
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 |