summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellström <thomas@shipmail.org>2006-12-06 09:19:19 +0000
committerThomas Hellström <thomas@shipmail.org>2006-12-06 09:19:19 +0000
commit9dd1d7a636429d1cb508d3f94ddbf3e6ca9fbef3 (patch)
tree49e0527760b3ef7d8827d45ed0dea36f040c306a
parentb46ecae0f365716ad98618effad793b2802d49f1 (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--ChangeLog11
-rw-r--r--unichrome/via_dri.c80
-rw-r--r--unichrome/via_driver.c5
-rw-r--r--unichrome/via_driver.h4
4 files changed, 98 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 21d1235..6b93396 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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_ */