diff options
author | Thomas Hellström <thomas@shipmail.org> | 2006-12-06 23:16:19 +0000 |
---|---|---|
committer | Thomas Hellström <thomas@shipmail.org> | 2006-12-06 23:16:19 +0000 |
commit | 15f5d854abb8c09ad478304f07ae76da394ee517 (patch) | |
tree | c5f2b6fb32b5841da9b0c7203ad50df9583e793c | |
parent | b2459ac4a5f0117311888d730fb5eac37ad8a2cf (diff) |
Reimplement download from screen to something more easily
debuggable.
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | unichrome/via_accel.c | 157 |
2 files changed, 94 insertions, 71 deletions
@@ -1,3 +1,11 @@ +2006-12-07 Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_accel.c: (viaAccelDMADownload), + (viaExaDownloadFromScreen): + + Reimplement download from screen to something more easily + debuggable. + 2006-12-06 Jon Nettleton <jon-dot-nettleton-at-gmail-dot-com> * unichrome/via_driver.c: diff --git a/unichrome/via_accel.c b/unichrome/via_accel.c index 6492b68..cb3eb58 100644 --- a/unichrome/via_accel.c +++ b/unichrome/via_accel.c @@ -1499,6 +1499,88 @@ viaOrder(CARD32 val, CARD32 * shift) #ifdef XF86DRI +static int +viaAccelDMADownload(ScrnInfoPtr pScrn, unsigned long fbOffset, + unsigned srcPitch, unsigned char *dst, + unsigned dstPitch, unsigned w, unsigned h) +{ + VIAPtr pVia = VIAPTR(pScrn); + drm_via_dmablit_t blit[2], *curBlit; + unsigned char *sysAligned = NULL; + Bool doSync[2], useBounceBuffer; + unsigned bouncePitch; + int curBuf, err, i , ret, blitHeight; + ret = 0; + + useBounceBuffer = (((unsigned long)dst & 15) || (dstPitch & 15)); + doSync[0] = FALSE; + doSync[1] = FALSE; + curBuf = 1; + blitHeight = h; + if (useBounceBuffer) { + bouncePitch = ALIGN_TO(dstPitch, 16); + blitHeight = VIA_DMA_DL_SIZE / bouncePitch; + } + + while (doSync[0] || doSync[1] || h != 0) { + curBuf = 1 - curBuf; + curBlit = &blit[curBuf]; + if (doSync[curBuf]) { + + do { + err = drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC, + &curBlit->sync, sizeof(curBlit->sync)); + } while (err == -EAGAIN); + + if (err) + return err; + + doSync[curBuf] = FALSE; + if (useBounceBuffer) { + for (i = 0; i < curBlit->num_lines; ++i) { + memcpy(dst, curBlit->mem_addr, curBlit->line_length); + dst += dstPitch; + curBlit->mem_addr += curBlit->mem_stride; + } + } + } + + if (h == 0) + continue; + + curBlit->num_lines = (h > blitHeight) ? blitHeight : h; + h -= curBlit->num_lines; + + sysAligned = (unsigned char *)pVia->dBounce + (curBuf * VIA_DMA_DL_SIZE); + sysAligned = (unsigned char *) + ALIGN_TO((unsigned long) sysAligned, 16); + + curBlit->mem_addr = (useBounceBuffer) ? sysAligned : dst; + curBlit->line_length = w; + curBlit->mem_stride = (useBounceBuffer) ? bouncePitch : dstPitch; + curBlit->fb_addr = fbOffset; + curBlit->fb_stride = srcPitch; + curBlit->to_fb = 0; + fbOffset += curBlit->num_lines * srcPitch; + + do { + err = drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, curBlit, + sizeof(*curBlit)); + } while (err == -EAGAIN); + + + if (err) { + ret = err; + h = 0; + continue; + } + + doSync[curBuf] = TRUE; + } + + return ret; +} + /* * Use PCI DMA if we can. If the system alignments don't match, we're using * an aligned bounce buffer for pipelined PCI DMA and memcpy. @@ -1511,14 +1593,10 @@ viaExaDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, { ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; VIAPtr pVia = VIAPTR(pScrn); - drm_via_dmablit_t blit[2], *curBlit; unsigned srcPitch = exaGetPixmapPitch(pSrc); unsigned wBytes = (pSrc->drawable.bitsPerPixel * w + 7) >> 3; unsigned srcOffset; - int err, buf, height, i; char *bounceAligned = NULL; - unsigned bouncePitch = 0; - Bool sync[2], useBounceBuffer; unsigned totSize; if (!w || !h) @@ -1550,74 +1628,11 @@ viaExaDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, return FALSE; } - useBounceBuffer = (((unsigned long)dst & 15) || (dst_pitch & 15)); - - height = h; - - if (useBounceBuffer) { - bounceAligned = (char *)(((unsigned long)pVia->dBounce + 15) & ~15); - bouncePitch = (dst_pitch + 15) & ~15; - height = VIA_DMA_DL_SIZE / bouncePitch; - } - - sync[0] = FALSE; - sync[1] = FALSE; - buf = 0; - err = 0; - - while (h && !err) { - curBlit = blit + buf; - - curBlit->num_lines = (h > height) ? height : h; - h -= curBlit->num_lines; - curBlit->line_length = wBytes; - curBlit->fb_addr = srcOffset; - curBlit->fb_stride = srcPitch; - curBlit->mem_addr = (unsigned char *) - ((useBounceBuffer) ? bounceAligned + VIA_DMA_DL_SIZE * buf : dst); - curBlit->mem_stride = (useBounceBuffer) ? bouncePitch : dst_pitch; - curBlit->to_fb = 0; - - while (-EAGAIN == (err = - drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, curBlit, - sizeof(*curBlit)))) ; - sync[buf] = TRUE; - buf = (buf) ? 0 : 1; - curBlit = blit + buf; - - if (sync[buf] && !err) { - while (-EAGAIN == (err = - drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC, - &curBlit->sync, sizeof(curBlit->sync)))) ; - sync[buf] = FALSE; - if (!err && useBounceBuffer) { - for (i = 0; i < curBlit->num_lines; ++i) { - memcpy(dst, curBlit->mem_addr, curBlit->line_length); - dst += dst_pitch; - curBlit->mem_addr += curBlit->mem_stride; - } - } - } - srcOffset += height * srcPitch; - } - - buf = (buf) ? 0 : 1; - curBlit = blit + buf; - - if (sync[buf] && !err) { - while (-EAGAIN == (err = - drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC, - &curBlit->sync, sizeof(curBlit->sync)))) ; - if (!err && useBounceBuffer) { - for (i = 0; i < curBlit->num_lines; ++i) { - memcpy(dst, curBlit->mem_addr, curBlit->line_length); - dst += dst_pitch; - curBlit->mem_addr += curBlit->mem_stride; - } - } - } + if (viaAccelDMADownload(pScrn, srcOffset, srcPitch, (unsigned char *)dst, + dst_pitch, wBytes, h)) + return FALSE; - return (err == 0); + return TRUE; } /* |