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