xf86-video-intel: Branch 'modesetting-rotation' - 3 commits - src/i830_cursor.c src/i830_display.c src/i830_driver.c src/i830_exa.c src/i830.h src/i830_memory.c src/i830_video.c

Eric Anholt anholt at kemper.freedesktop.org
Fri Jan 26 01:35:51 EET 2007


 src/i830.h         |   16 +++++++-
 src/i830_cursor.c  |    4 +-
 src/i830_display.c |   78 +++++++++++++++++++++++++++++++++++----
 src/i830_driver.c  |   18 ++++++++-
 src/i830_exa.c     |   13 ++++--
 src/i830_memory.c  |  104 +++++++++++++++++++----------------------------------
 src/i830_video.c   |   22 +----------
 7 files changed, 154 insertions(+), 101 deletions(-)

New commits:
diff-tree 5c1e27cdd243dc24dd2bfdeb46d757bbef6ba6af (from 83cc4601b27d871484a2408f31154e9387064b9e)
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jan 25 15:31:22 2007 -0800

    Make rotated shadow buffer allocation dynamic.
    
    For EXA, this requires version 2.1 of EXA to do rotation, as the VT switching
    issues were too complicated otherwise.

diff --git a/src/i830.h b/src/i830.h
index a7c889d..9ffae94 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -199,7 +199,13 @@ typedef struct _I830CrtcPrivateRec {
     /* Lookup table values to be set when the CRTC is enabled */
     CARD8 lut_r[256], lut_g[256], lut_b[256];
 
-    I830MemRange rotate_mem;
+#ifdef I830_USE_XAA
+    FBLinearPtr rotate_mem_xaa;
+#endif
+#ifdef I830_USE_EXA
+    ExaOffscreenArea *rotate_mem_exa;
+#endif
+
     I830MemRange cursor_mem;
     I830MemRange cursor_mem_argb;
 } I830CrtcPrivateRec, *I830CrtcPrivatePtr;
@@ -613,6 +619,14 @@ extern void i830WaitSync(ScrnInfoPtr pSc
 /* i830_memory.c */
 Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
 Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
+#ifdef I830_USE_XAA
+FBLinearPtr
+i830_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length,
+				 int granularity,
+				 MoveLinearCallbackProcPtr moveCB,
+				 RemoveLinearCallbackProcPtr removeCB,
+				 pointer privData);
+#endif /* I830_USE_EXA */
 
 /* i830_modes.c */
 DisplayModePtr i830_ddc_get_modes(xf86OutputPtr output);
diff --git a/src/i830_display.c b/src/i830_display.c
index 2313f76..8202985 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -342,8 +342,9 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x,
     int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
     int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
 
-    if (crtc->rotation != RR_Rotate_0) {
-	Start = intel_crtc->rotate_mem.Start;
+    if (crtc->rotatedPixmap != NULL) {
+	Start = (char *)crtc->rotatedPixmap->devPrivate.ptr -
+	    (char *)pI830->FbBase;
     } else if (I830IsPrimary(pScrn)) {
 	Start = pI830->FrontBuffer.Start;
     } else {
@@ -895,31 +896,92 @@ static PixmapPtr
 i830_crtc_shadow_create(xf86CrtcPtr crtc, int width, int height)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
+    ScreenPtr pScreen = pScrn->pScreen;
     I830Ptr pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
     unsigned long rotate_pitch;
     PixmapPtr rotate_pixmap;
-    pointer rotate_offset;
-
-    if (intel_crtc->rotate_mem.Start == 0)
-	return NULL;
+    unsigned long rotate_offset;
+    int align = KB(4), size;
 
     rotate_pitch = pI830->displayWidth * pI830->cpp;
-    rotate_offset = pI830->FbBase + intel_crtc->rotate_mem.Start;
+    size = rotate_pitch * height;
+
+#ifdef I830_USE_EXA
+    /* We could get close to what we want here by just creating a pixmap like
+     * normal, but we have to lock it down in framebuffer, and there is no
+     * setter for offscreen area locking in EXA currently.  So, we just
+     * allocate offscreen memory and fake up a pixmap header for it.
+     */
+    if (pI830->useEXA) {
+	assert(intel_crtc->rotate_mem_exa == NULL);
+
+	intel_crtc->rotate_mem_exa = exaOffscreenAlloc(pScreen, size, align,
+						       TRUE, NULL, NULL);
+	if (intel_crtc->rotate_mem_exa == NULL) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "Couldn't allocate shadow memory for rotated CRTC\n");
+	    return NULL;
+	}
+	rotate_offset = intel_crtc->rotate_mem_exa->offset;
+    }
+#endif /* I830_USE_EXA */
+#ifdef I830_USE_XAA
+    if (!pI830->useEXA) {
+	/* The XFree86 linear allocator operates in units of screen pixels,
+	 * sadly.
+	 */
+	size = (size + pI830->cpp - 1) / pI830->cpp;
+	align = (align + pI830->cpp - 1) / pI830->cpp;
+
+	assert(intel_crtc->rotate_mem_xaa == NULL);
+
+	intel_crtc->rotate_mem_xaa =
+	    i830_xf86AllocateOffscreenLinear(pScreen, size, align,
+					     NULL, NULL, NULL);
+	if (intel_crtc->rotate_mem_xaa == NULL) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "Couldn't allocate shadow memory for rotated CRTC\n");
+	    return NULL;
+	}
+	rotate_offset = pI830->FrontBuffer.Start +
+	    intel_crtc->rotate_mem_xaa->offset * pI830->cpp;
+    }
+#endif /* I830_USE_XAA */
 
     rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
 					   width, height,
 					   pScrn->depth,
 					   pScrn->bitsPerPixel,
 					   rotate_pitch,
-					   rotate_offset);
+					   pI830->FbBase + rotate_offset);
+    if (rotate_pixmap == NULL) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "Couldn't allocate shadow pixmap for rotated CRTC\n");
+    }
     return rotate_pixmap;
 }
 
 static void
 i830_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap)
 {
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+
     FreeScratchPixmapHeader(rotate_pixmap);
+#ifdef I830_USE_EXA
+    if (pI830->useEXA && intel_crtc->rotate_mem_exa != NULL) {
+	exaOffscreenFree(pScrn->pScreen, intel_crtc->rotate_mem_exa);
+	intel_crtc->rotate_mem_exa = NULL;
+    }
+#endif /* I830_USE_EXA */
+#ifdef I830_USE_XAA
+    if (!pI830->useEXA) {
+	xf86FreeOffscreenLinear(intel_crtc->rotate_mem_xaa);
+	intel_crtc->rotate_mem_xaa = NULL;
+    }
+#endif /* I830_USE_XAA */
 }
 
 
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 644ea57..19e97b0 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2879,7 +2879,23 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       shadowSetup(pScreen);
       /* support all rotations */
       xf86RandR12Init (pScreen);
-      xf86RandR12SetRotations (pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
+      if (pI830->useEXA) {
+#ifdef I830_USE_EXA
+	 if (pI830->EXADriverPtr->exa_minor >= 1) {
+	    xf86RandR12SetRotations (pScreen, RR_Rotate_0 | RR_Rotate_90 |
+				     RR_Rotate_180 | RR_Rotate_270);
+	 } else {
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		       "EXA version %d.%d too old to support rotation\n",
+		       pI830->EXADriverPtr->exa_major,
+		       pI830->EXADriverPtr->exa_minor);
+	    xf86RandR12SetRotations (pScreen, RR_Rotate_0);
+	 }
+#endif /* I830_USE_EXA */
+      } else {
+	 xf86RandR12SetRotations (pScreen, RR_Rotate_0 | RR_Rotate_90 |
+				  RR_Rotate_180 | RR_Rotate_270);
+      }
       pI830->PointerMoved = pScrn->PointerMoved;
       pScrn->PointerMoved = I830PointerMoved;
       pI830->CreateScreenResources = pScreen->CreateScreenResources;
diff --git a/src/i830_exa.c b/src/i830_exa.c
index f1cd1e3..3fd5e4a 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -418,7 +418,7 @@ I830EXAInit(ScreenPtr pScreen)
     
     pI830->bufferOffset = 0;
     pI830->EXADriverPtr->exa_major = 2;
-    pI830->EXADriverPtr->exa_minor = 0;
+    pI830->EXADriverPtr->exa_minor = 1;
     pI830->EXADriverPtr->memoryBase = pI830->FbBase;
     pI830->EXADriverPtr->offScreenBase = pI830->Offscreen.Start;
     pI830->EXADriverPtr->memorySize = pI830->Offscreen.End;
@@ -520,9 +520,14 @@ I830EXAInit(ScreenPtr pScreen)
     }
 
     if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
-	xfree(pI830->EXADriverPtr);
-	pI830->noAccel = TRUE;
-	return FALSE;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		   "EXA initialization failed; trying older version\n");
+	pI830->EXADriverPtr->exa_minor = 0;
+	if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
+	    xfree(pI830->EXADriverPtr);
+	    pI830->noAccel = TRUE;
+	    return FALSE;
+	}
     }
 
     I830SelectBuffer(pScrn, I830_SELECT_FRONT);
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 14dacc8..24f0b29 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -769,63 +769,6 @@ I830AllocateFramebuffer(ScrnInfoPtr pScr
    return TRUE;
 }
 
-/**
- * Allocates memory for the rotated shadow buffers.
- *
- * This memory would be better allocated normally through the linear allocator,
- * but it gets rotation working for now.
- */
-static Bool
-I830AllocateRotateBuffers(xf86CrtcPtr crtc, const int flags)
-{
-   ScrnInfoPtr pScrn = crtc->scrn;
-   I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
-   I830Ptr pI830 = I830PTR(pScrn);
-   Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
-   unsigned long avail, lineSize;
-   int verbosity = dryrun ? 4 : 1;
-   const char *s = dryrun ? "[dryrun] " : "";
-   int align, alignflags;
-   long size, alloced;
-   int rotate_width, rotate_height;
-
-   memset(&intel_crtc->rotate_mem, 0, sizeof(intel_crtc->rotate_mem));
-
-   rotate_width = pScrn->displayWidth;
-   if (pScrn->virtualX > pScrn->virtualY)
-      rotate_height = pScrn->virtualX;
-   else
-      rotate_height = pScrn->virtualY;
-
-   lineSize = pScrn->displayWidth * pI830->cpp;
-   avail = pScrn->videoRam * 1024;
-
-   align = KB(64);
-   alignflags = 0;
-
-   size = lineSize * rotate_height;
-   size = ROUND_TO_PAGE(size);
-   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
-		  "%sInitial %sshadow framebuffer allocation size: "
-		  "%ld kByte\n",
-		  s, (intel_crtc->pipe == 0) ? "" : "secondary ",
-		  size / 1024);
-   alloced = I830AllocVidMem(pScrn, &intel_crtc->rotate_mem,
-			     &pI830->StolenPool, size, align,
-			     flags | alignflags |
-			     FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
-   if (alloced < size) {
-      if (!dryrun) {
-	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
-		    "%sshadow framebuffer. Is your VideoRAM set too low?\n",
-		    (intel_crtc->pipe == 0) ? "" : "secondary ");
-      }
-      return FALSE;
-   }
-
-   return TRUE;
-}
-
 static Bool
 I830AllocateCursorBuffers(xf86CrtcPtr crtc, const int flags)
 {
@@ -981,10 +924,6 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, 
 	 return FALSE;
       }
 
-      for (i = 0; i < xf86_config->num_crtc; i++) {
-	 I830AllocateRotateBuffers(xf86_config->crtc[i], flags);
-      }
-
 #ifdef I830_USE_EXA
       if (pI830->useEXA) {
 	 /* Default EXA to having 3 screens worth of offscreen memory space
@@ -1619,7 +1558,6 @@ I830FixupOffsets(ScrnInfoPtr pScrn)
    for (i = 0; i < xf86_config->num_crtc; i++) {
       I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private;
 
-      I830FixOffset(pScrn, &intel_crtc->rotate_mem);
       I830FixOffset(pScrn, &intel_crtc->cursor_mem);
       I830FixOffset(pScrn, &intel_crtc->cursor_mem_argb);
    }
@@ -2028,8 +1966,6 @@ I830BindAGPMemory(ScrnInfoPtr pScrn)
       for (i = 0; i < xf86_config->num_crtc; i++) {
 	 I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private;
 
-	 if (!BindMemRange(pScrn, &intel_crtc->rotate_mem))
-	    return FALSE;
 	 if (!BindMemRange(pScrn, &intel_crtc->cursor_mem))
 	    return FALSE;
 	 if (!BindMemRange(pScrn, &intel_crtc->cursor_mem_argb))
@@ -2130,8 +2066,6 @@ I830UnbindAGPMemory(ScrnInfoPtr pScrn)
       for (i = 0; i < xf86_config->num_crtc; i++) {
 	 I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private;
 
-	 if (!UnbindMemRange(pScrn, &intel_crtc->rotate_mem))
-	    return FALSE;
 	 if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem))
 	    return FALSE;
 	 if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem_argb))
@@ -2209,3 +2143,41 @@ I830CheckAvailableMemory(ScrnInfoPtr pSc
 
    return maxPages * 4;
 }
+
+#ifdef I830_USE_XAA
+/**
+ * Allocates memory from the XF86 linear allocator, but also purges
+ * memory if possible to cause the allocation to succeed.
+ */
+FBLinearPtr
+i830_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length,
+				 int granularity,
+				 MoveLinearCallbackProcPtr moveCB,
+				 RemoveLinearCallbackProcPtr removeCB,
+				 pointer privData)
+{
+   FBLinearPtr linear;
+   int max_size;
+
+   linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
+					removeCB, privData);
+   if (linear != NULL)
+      return linear;
+
+   /* The above allocation didn't succeed, so purge unlocked stuff and try
+    * again.
+    */
+   xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity,
+				   PRIORITY_EXTREME);
+
+   if (max_size < length)
+      return NULL;
+
+   xf86PurgeUnlockedOffscreenAreas(pScreen);
+
+   linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
+					removeCB, privData);
+
+   return linear;
+}
+#endif
diff --git a/src/i830_video.c b/src/i830_video.c
index 79f5a7c..22f5bee 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2073,8 +2073,6 @@ I830AllocateMemory(ScrnInfoPtr pScrn, st
 #endif /* I830_USE_EXA */
 #ifdef I830_USE_XAA
    if (!pI830->useEXA) {
-      int max_size;
-
       /* Converts an offset from XAA's linear allocator to an offset from the
        * start of fb.
        */
@@ -2100,25 +2098,11 @@ I830AllocateMemory(ScrnInfoPtr pScrn, st
 	 xf86FreeOffscreenLinear(linear->xaa);
       }
 
-      linear->xaa = xf86AllocateOffscreenLinear(pScreen, size, align,
-						NULL, NULL, NULL);
-      if (linear->xaa != NULL) {
-	 linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset);
+      linear->xaa = i830_xf86AllocateOffscreenLinear(pScreen, size, align,
+						     NULL, NULL, NULL);
+      if (linear->xaa == NULL)
 	 return;
-      }
-
-      xf86QueryLargestOffscreenLinear(pScreen, &max_size, align,
-				      PRIORITY_EXTREME);
-
-      if (max_size < size) {
-	 ErrorF("No memory available\n");
-	 linear->offset = 0;
-	 return;
-      }
 
-      xf86PurgeUnlockedOffscreenAreas(pScreen);
-      linear->xaa = xf86AllocateOffscreenLinear(pScreen, size, align,
-						NULL, NULL, NULL);
       linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset);
    }
 #endif /* I830_USE_XAA */
diff-tree 83cc4601b27d871484a2408f31154e9387064b9e (from e21332419581eff1d7651741bae0b640c84d0ecd)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jan 24 16:52:22 2007 +0800

    Fix a possible failure to misalign video allocation in XAA.

diff --git a/src/i830_video.c b/src/i830_video.c
index a330eb5..79f5a7c 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2117,7 +2117,7 @@ I830AllocateMemory(ScrnInfoPtr pScrn, st
       }
 
       xf86PurgeUnlockedOffscreenAreas(pScreen);
-      linear->xaa = xf86AllocateOffscreenLinear(pScreen, size, 4,
+      linear->xaa = xf86AllocateOffscreenLinear(pScreen, size, align,
 						NULL, NULL, NULL);
       linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset);
    }
diff-tree e21332419581eff1d7651741bae0b640c84d0ecd (from 74ebff6732b9bfcf8c865b52cbebfd9bf6b73eb2)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jan 24 12:32:38 2007 +0800

    Warning fix.

diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index bb5bc38..da220f5 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -486,8 +486,8 @@ I830SetCursorPosition(ScrnInfoPtr pScrn,
     {
 	xf86CrtcPtr	    crtc = xf86_config->crtc[pipe];
 	DisplayModePtr	    mode = &crtc->mode;
-	int		    thisx;
-	int		    thisy;
+	int		    thisx = 0;
+	int		    thisy = 0;
 	int hotspotx = 0, hotspoty = 0;
 
 	if (!crtc->enabled)



More information about the xorg-commit mailing list