diff options
author | Thomas Hellström <thomas@shipmail.org> | 2006-12-06 10:28:25 +0000 |
---|---|---|
committer | Thomas Hellström <thomas@shipmail.org> | 2006-12-06 10:28:25 +0000 |
commit | 6646f2dd702ff942e7b620cfde3898373ca37637 (patch) | |
tree | 5bb1c3bf85d0555777f992d93b47359e2536bc6e | |
parent | 9dd1d7a636429d1cb508d3f94ddbf3e6ca9fbef3 (diff) |
Fix up previous commit for > 16MB sizes.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | unichrome/via_dri.c | 98 |
2 files changed, 68 insertions, 36 deletions
@@ -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; } |