From 221ef11b31756deb7134801730e76c040e841f5c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 12 Feb 2010 14:15:10 -0500 Subject: r6xx/r7xx: implement EXA vline support --- src/r600_exa.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++-------- src/radeon.h | 4 ++ 2 files changed, 102 insertions(+), 16 deletions(-) diff --git a/src/r600_exa.c b/src/r600_exa.c index 6a132bb5..ddbbb533 100644 --- a/src/r600_exa.c +++ b/src/r600_exa.c @@ -95,6 +95,30 @@ uint32_t RADEON_ROP[16] = { RADEON_ROP3_ONE, /* GXset */ }; +static void R600VlineHelperClear(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_accel_state *accel_state = info->accel_state; + + accel_state->vline_crtc = NULL; + accel_state->vline_y1 = -1; + accel_state->vline_y2 = 0; +} + +static void R600VlineHelperSet(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_accel_state *accel_state = info->accel_state; + + accel_state->vline_crtc = radeon_pick_best_crtc(pScrn, x1, y1, x2, y2); + if (accel_state->vline_y1 == -1) + accel_state->vline_y1 = y1; + if (y1 < accel_state->vline_y1) + accel_state->vline_y1 = y1; + if (y2 > accel_state->vline_y2) + accel_state->vline_y2 = y2; +} + static Bool R600ValidPM(uint32_t pm, int bpp) { uint8_t r, g, b, a; @@ -353,6 +377,9 @@ R600PrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg) ErrorF("PM: 0x%08x\n", pm); #endif + if (accel_state->vsync) + R600VlineHelperClear(pScrn); + return TRUE; } @@ -361,8 +388,13 @@ static void R600Solid(PixmapPtr pPix, int x1, int y1, int x2, int y2) { ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_accel_state *accel_state = info->accel_state; float *vb; + if (accel_state->vsync) + R600VlineHelperSet(pScrn, x1, y1, x2, y2); + vb = radeon_vbo_space(pScrn, 8); vb[0] = (float)x1; @@ -381,6 +413,14 @@ static void R600DoneSolid(PixmapPtr pPix) { ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_accel_state *accel_state = info->accel_state; + + if (accel_state->vsync) + cp_wait_vline_sync(pScrn, accel_state->ib, pPix, + accel_state->vline_crtc, + accel_state->vline_y1, + accel_state->vline_y2); r600_finish_op(pScrn, 8); } @@ -586,6 +626,22 @@ R600DoCopy(ScrnInfoPtr pScrn) r600_finish_op(pScrn, 16); } +static void +R600DoCopyVline(PixmapPtr pPix) +{ + ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + struct radeon_accel_state *accel_state = info->accel_state; + + if (accel_state->vsync) + cp_wait_vline_sync(pScrn, accel_state->ib, pPix, + accel_state->vline_crtc, + accel_state->vline_y1, + accel_state->vline_y2); + + r600_finish_op(pScrn, 16); +} + static void R600AppendCopyVertex(ScrnInfoPtr pScrn, int srcX, int srcY, @@ -739,6 +795,9 @@ R600PrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, accel_state->dst_mc_addr, accel_state->dst_bo, pDst->drawable.bitsPerPixel, rop, planemask); + if (accel_state->vsync) + R600VlineHelperClear(pScrn); + return TRUE; } @@ -798,7 +857,7 @@ R600OverlapCopy(PixmapPtr pDst, dst_offset, dst_bo, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, w, vchunk); - R600DoCopy(pScrn); + R600DoCopyVline(pDst); srcY = srcY + vchunk; dstY = dstY + vchunk; @@ -810,7 +869,7 @@ R600OverlapCopy(PixmapPtr pDst, dst_offset, dst_bo, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX, srcY + h - vchunk, dstX, dstY + h - vchunk, w, vchunk); - R600DoCopy(pScrn); + R600DoCopyVline(pDst); } h = h - vchunk; vchunk = 0; @@ -823,7 +882,7 @@ R600OverlapCopy(PixmapPtr pDst, dst_offset, dst_bo, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, hchunk, h); - R600DoCopy(pScrn); + R600DoCopyVline(pDst); srcX = srcX + hchunk; dstX = dstX + hchunk; @@ -835,7 +894,7 @@ R600OverlapCopy(PixmapPtr pDst, dst_offset, dst_bo, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX + w - hchunk, srcY, dstX + w - hchunk, dstY, hchunk, h); - R600DoCopy(pScrn); + R600DoCopyVline(pDst); } w = w - hchunk; hchunk = 0; @@ -853,7 +912,7 @@ R600OverlapCopy(PixmapPtr pDst, dst_offset, dst_bo, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX + i - hchunk, srcY, dstX + i - hchunk, dstY, hchunk, h); - R600DoCopy(pScrn); + R600DoCopyVline(pDst); } } else { /* left */ /* copy left to right */ @@ -866,7 +925,7 @@ R600OverlapCopy(PixmapPtr pDst, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX + i, srcY, dstX + i, dstY, hchunk, h); - R600DoCopy(pScrn); + R600DoCopyVline(pDst); } } } else { /* up/down */ @@ -882,7 +941,7 @@ R600OverlapCopy(PixmapPtr pDst, if (vchunk > h - i) vchunk = h - i; R600AppendCopyVertex(pScrn, srcX, srcY + i, dstX, dstY + i, w, vchunk); - R600DoCopy(pScrn); + R600DoCopyVline(pDst); } } else { /* down */ /* copy bottom to top */ @@ -896,7 +955,7 @@ R600OverlapCopy(PixmapPtr pDst, if (vchunk > i) vchunk = i; R600AppendCopyVertex(pScrn, srcX, srcY + i - vchunk, dstX, dstY + i - vchunk, w, vchunk); - R600DoCopy(pScrn); + R600DoCopyVline(pDst); } } } @@ -909,7 +968,7 @@ R600OverlapCopy(PixmapPtr pDst, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, w, h); - R600DoCopy(pScrn); + R600DoCopyVline(pDst); } } @@ -927,6 +986,9 @@ R600Copy(PixmapPtr pDst, if (accel_state->same_surface && (srcX == dstX) && (srcY == dstY)) return; + if (accel_state->vsync) + R600VlineHelperSet(pScrn, dstX, dstY, dstX + w, dstY + h); + #if defined(XF86DRM_MODE) if (info->cs) bo = radeon_get_pixmap_bo(pDst); @@ -964,7 +1026,7 @@ R600Copy(PixmapPtr pDst, orig_offset, bo, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, dstX, dstY, dstX, dstY, w, h); - R600DoCopy(pScrn); + R600DoCopyVline(pDst); } else R600OverlapCopy(pDst, srcX, srcY, dstX, dstY, w, h); } else if (accel_state->same_surface) { @@ -985,7 +1047,7 @@ R600Copy(PixmapPtr pDst, offset, bo, pDst->drawable.bitsPerPixel, accel_state->rop, accel_state->planemask); R600AppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, w, h); - R600DoCopy(pScrn); + R600DoCopyVline(pDst); } else { R600AppendCopyVertex(pScrn, srcX, srcY, dstX, dstY, w, h); } @@ -1000,7 +1062,7 @@ R600DoneCopy(PixmapPtr pDst) struct radeon_accel_state *accel_state = info->accel_state; if (!accel_state->same_surface) - R600DoCopy(pScrn); + R600DoCopyVline(pDst); if (accel_state->copy_area) { if (!info->cs) @@ -1752,6 +1814,9 @@ static Bool R600PrepareComposite(int op, PicturePtr pSrcPicture, EREG(accel_state->ib, SPI_INTERP_CONTROL_0, 0); END_BATCH(); + if (accel_state->vsync) + R600VlineHelperClear(pScrn); + return TRUE; } @@ -1769,6 +1834,9 @@ static void R600Composite(PixmapPtr pDst, /* ErrorF("R600Composite (%d,%d) (%d,%d) (%d,%d) (%d,%d)\n", srcX, srcY, maskX, maskY,dstX, dstY, w, h); */ + if (accel_state->vsync) + R600VlineHelperSet(pScrn, dstX, dstY, dstX + w, dstY + h); + if (accel_state->msk_pic) { vb = radeon_vbo_space(pScrn, 24); @@ -1795,7 +1863,7 @@ static void R600Composite(PixmapPtr pDst, vb[17] = (float)(maskY + h); radeon_vbo_commit(pScrn); - + } else { vb = radeon_vbo_space(pScrn, 16); @@ -1828,6 +1896,12 @@ static void R600DoneComposite(PixmapPtr pDst) struct radeon_accel_state *accel_state = info->accel_state; int vtx_size; + if (accel_state->vsync) + cp_wait_vline_sync(pScrn, accel_state->ib, pDst, + accel_state->vline_crtc, + accel_state->vline_y1, + accel_state->vline_y2); + vtx_size = accel_state->msk_pic ? 24 : 16; r600_finish_op(pScrn, vtx_size); @@ -2060,6 +2134,9 @@ R600UploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h, } radeon_bo_unmap(scratch); + if (info->accel_state->vsync) + R600VlineHelperSet(pScrn, x, y, x + w, y + h); + /* blit from gart to vram */ R600DoPrepareCopy(pScrn, src_pitch_hw, w, h, @@ -2068,7 +2145,7 @@ R600UploadToScreenCS(PixmapPtr pDst, int x, int y, int w, int h, 0, radeon_get_pixmap_bo(pDst), bpp, 3, 0xffffffff); R600AppendCopyVertex(pScrn, 0, 0, x, y, w, h); - R600DoCopy(pScrn); + R600DoCopyVline(pDst); out: radeon_bo_unref(scratch); @@ -2135,7 +2212,7 @@ R600DownloadFromScreenCS(PixmapPtr pSrc, int x, int y, int w, 3, 0xffffffff); R600AppendCopyVertex(pScrn, x, y, 0, 0, w, h); R600DoCopy(pScrn); - + if (info->cs) radeon_cs_flush_indirect(pScrn); @@ -2402,7 +2479,11 @@ R600DrawInit(ScreenPtr pScreen) info->accel_state->exa->maxY = 8192; /* not supported yet */ - info->accel_state->vsync = FALSE; + if (xf86ReturnOptValBool(info->Options, OPTION_EXA_VSYNC, FALSE)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EXA VSync enabled\n"); + info->accel_state->vsync = TRUE; + } else + info->accel_state->vsync = FALSE; if (!exaDriverInit(pScreen, info->accel_state->exa)) { xfree(info->accel_state->exa); @@ -2424,6 +2505,7 @@ R600DrawInit(ScreenPtr pScreen) info->accel_state->dst_bo = NULL; info->accel_state->copy_area_bo = NULL; info->accel_state->vb_start_op = -1; + R600VlineHelperClear(pScrn); #ifdef XF86DRM_MODE radeon_vbo_init_lists(pScrn); diff --git a/src/radeon.h b/src/radeon.h index 0c775564..59c2282c 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -784,6 +784,10 @@ struct radeon_accel_state { // composite Bool component_alpha; Bool src_alpha; + // vline + xf86CrtcPtr vline_crtc; + int vline_y1; + int vline_y2; #endif #ifdef USE_XAA -- cgit v1.2.3