summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellström <thomas@shipmail.org>2006-12-06 23:16:19 +0000
committerThomas Hellström <thomas@shipmail.org>2006-12-06 23:16:19 +0000
commit15f5d854abb8c09ad478304f07ae76da394ee517 (patch)
treec5f2b6fb32b5841da9b0c7203ad50df9583e793c
parentb2459ac4a5f0117311888d730fb5eac37ad8a2cf (diff)
Reimplement download from screen to something more easily
debuggable.
-rw-r--r--ChangeLog8
-rw-r--r--unichrome/via_accel.c157
2 files changed, 94 insertions, 71 deletions
diff --git a/ChangeLog b/ChangeLog
index f52eced..4f6ede6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;
}
/*