summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellström <thomas@shipmail.org>2006-12-06 10:28:25 +0000
committerThomas Hellström <thomas@shipmail.org>2006-12-06 10:28:25 +0000
commit6646f2dd702ff942e7b620cfde3898373ca37637 (patch)
tree5bb1c3bf85d0555777f992d93b47359e2536bc6e
parent9dd1d7a636429d1cb508d3f94ddbf3e6ca9fbef3 (diff)
Fix up previous commit for > 16MB sizes.
-rw-r--r--ChangeLog6
-rw-r--r--unichrome/via_dri.c98
2 files changed, 68 insertions, 36 deletions
diff --git a/ChangeLog b/ChangeLog
index 6b93396..ea5912f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2006-12-06 Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ * unichrome/via_dri.c: (viaDRIFBMemcpy), (viaDRIOffscreenSave):
+
+ Fix up previous commit for > 16MB sizes.
+
+2006-12-06 Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+
* unichrome/via_dri.c: (viaDRIOffscreenSave),
(viaDRIOffscreenRestore):
* unichrome/via_driver.c: (VIAEnterVT), (VIALeaveVT):
diff --git a/unichrome/via_dri.c b/unichrome/via_dri.c
index 2c1b8f9..5e0b803 100644
--- a/unichrome/via_dri.c
+++ b/unichrome/via_dri.c
@@ -999,6 +999,53 @@ static Bool VIADRIMapInit(ScreenPtr pScreen, VIAPtr pVia)
return TRUE;
}
+#define DRM_VIA_BLIT_MAX_SIZE (2048*2048*4)
+
+static int
+viaDRIFBMemcpy(int fd, unsigned long fbOffset, unsigned char *addr,
+ unsigned long size, Bool toFB)
+{
+ int err;
+ drm_via_dmablit_t blit;
+ unsigned long curSize;
+
+ do {
+ curSize = (size > DRM_VIA_BLIT_MAX_SIZE) ? DRM_VIA_BLIT_MAX_SIZE :
+ size;
+
+ blit.num_lines = 1;
+ blit.line_length = curSize;
+ blit.fb_addr = fbOffset;
+ blit.fb_stride = ALIGN_TO(curSize, 16);
+ blit.mem_addr = addr;
+ blit.mem_stride = blit.fb_stride;
+ blit.to_fb = (toFB) ? 1 : 0;
+
+ do {
+ err = drmCommandWriteRead(fd, DRM_VIA_DMA_BLIT,
+ &blit, sizeof(blit));
+ } while (-EAGAIN == err);
+
+ if (err)
+ return err;
+
+ do {
+ err = drmCommandWriteRead(fd, DRM_VIA_BLIT_SYNC,
+ &blit.sync, sizeof(blit.sync));
+ } while (-EAGAIN == err);
+ if (err)
+ return err;
+
+ fbOffset += curSize;
+ addr += curSize;
+ size -= curSize;
+
+ } while (size > 0);
+ return 0;
+}
+
+
+
void
viaDRIOffscreenSave(ScrnInfoPtr pScrn)
{
@@ -1006,7 +1053,7 @@ viaDRIOffscreenSave(ScrnInfoPtr pScrn)
VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate;
unsigned char *saveAddr = pVia->FBBase + pVIADRI->fbOffset;
unsigned long saveSize = pVIADRI->fbSize;
- drm_via_dmablit_t blit;
+ unsigned long curSize;
int err;
@@ -1016,48 +1063,27 @@ viaDRIOffscreenSave(ScrnInfoPtr pScrn)
pVia->driOffScreenSave = malloc(saveSize + 16);
if (pVia->driOffScreenSave) {
if ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 8)) {
-
- blit.num_lines = 1;
- blit.line_length = saveSize;
- blit.fb_addr = pVIADRI->fbOffset;
- blit.fb_stride = ALIGN_TO(saveSize, 16);
- blit.mem_addr = (void *)ALIGN_TO((unsigned long)
- pVia->driOffScreenSave, 16);
- blit.mem_stride = blit.fb_stride;
- blit.to_fb = 0;
-
- do {
- err = drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT,
- &blit, sizeof(blit));
- } while (-EAGAIN == err);
- if (err)
- goto out_err;
-
- do {
- err = drmCommandWriteRead(pVia->drmFD, DRM_VIA_BLIT_SYNC,
- &blit.sync, sizeof(blit.sync));
- } while (-EAGAIN == err);
- if (err)
- goto out_err;
+ err = viaDRIFBMemcpy(pVia->drmFD, pVIADRI->fbOffset,
+ (unsigned char *)
+ ALIGN_TO((unsigned long)
+ pVia->driOffScreenSave, 16),
+ saveSize, FALSE);
+ if (!err)
+ return;
- } else {
- memcpy((void *)ALIGN_TO((unsigned long) pVia->driOffScreenSave, 16),
- saveAddr, saveSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Hardware backup of DRI offscreen memory failed: %s.\n"
+ "\tUsing slow software backup instead.\n",
+ strerror(-err));
}
+ memcpy((void *)ALIGN_TO((unsigned long) pVia->driOffScreenSave, 16),
+ saveAddr, saveSize);
+
} else {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Out of memory trying to backup DRI offscreen memory.\n");
}
return;
-
- out_err:
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Hardware backup of DRI offscreen memory failed.\n"
- "\tUsing slow software backup instead.\n");
-
- memcpy((void *)ALIGN_TO((unsigned long) pVia->driOffScreenSave, 16),
- saveAddr, saveSize);
- return;
}