diff options
author | Thomas Hellström <thomas@shipmail.org> | 2006-12-06 09:19:19 +0000 |
---|---|---|
committer | Thomas Hellström <thomas@shipmail.org> | 2006-12-06 09:19:19 +0000 |
commit | 9dd1d7a636429d1cb508d3f94ddbf3e6ca9fbef3 (patch) | |
tree | 49e0527760b3ef7d8827d45ed0dea36f040c306a | |
parent | b46ecae0f365716ad98618effad793b2802d49f1 (diff) |
Back up DRI offscreen memory before leaving VT and restore it
when entering VT. It may be overwritten in between.
Use PCI DMA blit for this if available.
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | unichrome/via_dri.c | 80 | ||||
-rw-r--r-- | unichrome/via_driver.c | 5 | ||||
-rw-r--r-- | unichrome/via_driver.h | 4 |
4 files changed, 98 insertions, 2 deletions
@@ -1,3 +1,14 @@ +2006-12-06 Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> + + * unichrome/via_dri.c: (viaDRIOffscreenSave), + (viaDRIOffscreenRestore): + * unichrome/via_driver.c: (VIAEnterVT), (VIALeaveVT): + * unichrome/via_driver.h: + + Back up DRI offscreen memory before leaving VT and restore it + when entering VT. It may be overwritten in between. + Use PCI DMA blit for this if available. + 2006-12-05 Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> * unichrome/via_driver.c: (VIAWriteMode), (VIAInitialize3DEngine): diff --git a/unichrome/via_dri.c b/unichrome/via_dri.c index d0225f0..2c1b8f9 100644 --- a/unichrome/via_dri.c +++ b/unichrome/via_dri.c @@ -998,3 +998,83 @@ static Bool VIADRIMapInit(ScreenPtr pScreen, VIAPtr pVia) return TRUE; } + +void +viaDRIOffscreenSave(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; + unsigned char *saveAddr = pVia->FBBase + pVIADRI->fbOffset; + unsigned long saveSize = pVIADRI->fbSize; + drm_via_dmablit_t blit; + int err; + + + if (pVia->driOffScreenSave) + free(pVia->driOffScreenSave); + + 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; + + } else { + 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; +} + + +void +viaDRIOffscreenRestore(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; + + unsigned char *saveAddr = pVia->FBBase + pVIADRI->fbOffset; + unsigned long saveSize = pVIADRI->fbSize; + + if (pVia->driOffScreenSave) { + memcpy(saveAddr, + (void *)ALIGN_TO((unsigned long)pVia->driOffScreenSave, 16), + saveSize); + free(pVia->driOffScreenSave); + pVia->driOffScreenSave = NULL; + } +} diff --git a/unichrome/via_driver.c b/unichrome/via_driver.c index acbe3c8..7c441be 100644 --- a/unichrome/via_driver.c +++ b/unichrome/via_driver.c @@ -1644,6 +1644,7 @@ static Bool VIAEnterVT(int scrnIndex, int flags) #ifdef XF86DRI if (pVia->directRenderingEnabled) { kickVblank(pScrn); + viaDRIOffscreenRestore(pScrn); VIADRIRingBufferInit(pScrn); DRIUnlock(screenInfo.screens[scrnIndex]); } @@ -1677,8 +1678,8 @@ static void VIALeaveVT(int scrnIndex, int flags) #ifdef XF86DRI if (pVia->directRenderingEnabled) { - - VIADRIRingBufferCleanup(pScrn); + VIADRIRingBufferCleanup(pScrn); + viaDRIOffscreenSave(pScrn); } #endif diff --git a/unichrome/via_driver.h b/unichrome/via_driver.h index 533e490..cc26a11 100644 --- a/unichrome/via_driver.h +++ b/unichrome/via_driver.h @@ -330,6 +330,7 @@ typedef struct _VIA { int drmVerMinor; int drmVerPL; VIAMem driOffScreenMem; + void * driOffScreenSave; #endif Bool DRIIrqEnable; Bool agpEnable; @@ -457,6 +458,9 @@ void VIADRICloseScreen(ScreenPtr pScreen); Bool VIADRIFinishScreenInit(ScreenPtr pScreen); void VIADRIRingBufferCleanup(ScrnInfoPtr pScrn); Bool VIADRIRingBufferInit(ScrnInfoPtr pScrn); +void viaDRIOffscreenRestore(ScrnInfoPtr pScrn); +void viaDRIOffscreenSave(ScrnInfoPtr pScrn); + #endif /* XF86DRI */ #endif /* _VIA_DRIVER_H_ */ |