summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/i830.h16
-rw-r--r--src/i830_display.c78
-rw-r--r--src/i830_driver.c18
-rw-r--r--src/i830_exa.c13
-rw-r--r--src/i830_memory.c104
-rw-r--r--src/i830_video.c22
6 files changed, 152 insertions, 99 deletions
diff --git a/src/i830.h b/src/i830.h
index a7c889d4..9ffae94c 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 pScrn);
/* 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 2313f768..82029850 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -342,8 +342,9 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y)
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 644ea57f..19e97b00 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2879,7 +2879,23 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
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 f1cd1e36..3fd5e4ae 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 14dacc86..24f0b296 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -769,63 +769,6 @@ I830AllocateFramebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
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, const int flags)
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 pScrn)
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 79f5a7c8..22f5bee4 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2073,8 +2073,6 @@ I830AllocateMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear, int size,
#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, struct linear_alloc *linear, int size,
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);
- return;
- }
-
- xf86QueryLargestOffscreenLinear(pScreen, &max_size, align,
- PRIORITY_EXTREME);
-
- if (max_size < size) {
- ErrorF("No memory available\n");
- linear->offset = 0;
+ linear->xaa = i830_xf86AllocateOffscreenLinear(pScreen, size, align,
+ NULL, NULL, NULL);
+ if (linear->xaa == NULL)
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 */