Replace AA allocator usage with i830_memory.c for RandR rotation.

This requires EXA 2.2 (server 1.3) for rotated performance with EXA, because
the i830_memory.c allocation may not fall within what EXA considers the
offscreen area, so the PixmapIsOffscreen hook is needed.
This commit is contained in:
Eric Anholt 2007-08-17 17:49:21 -07:00
parent 9ad33dd65a
commit bd874b11bb
5 changed files with 48 additions and 111 deletions

View File

@ -234,12 +234,7 @@ typedef struct _I830CrtcPrivateRec {
/* Lookup table values to be set when the CRTC is enabled */
CARD8 lut_r[256], lut_g[256], lut_b[256];
#ifdef I830_USE_XAA
FBLinearPtr rotate_mem_xaa;
#endif
#ifdef I830_USE_EXA
ExaOffscreenArea *rotate_mem_exa;
#endif
i830_memory *rotate_mem;
/* Card virtual address of the cursor */
unsigned long cursor_offset;
unsigned long cursor_argb_offset;
@ -689,14 +684,6 @@ Bool i830_unbind_all_memory(ScrnInfoPtr pScrn);
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);

View File

@ -1291,59 +1291,24 @@ static void *
i830_crtc_shadow_allocate (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;
unsigned long rotate_offset;
int align = KB(4), size;
rotate_pitch = pScrn->displayWidth * pI830->cpp;
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;
assert(intel_crtc->rotate_mem == NULL);
intel_crtc->rotate_mem = i830_allocate_memory(pScrn, "rotated crtc",
size, align, 0);
if (intel_crtc->rotate_mem == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Couldn't allocate shadow memory for rotated CRTC\n");
return NULL;
}
#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->front_buffer->offset +
intel_crtc->rotate_mem_xaa->offset * pI830->cpp;
}
#endif /* I830_USE_XAA */
return pI830->FbBase + rotate_offset;
return pI830->FbBase + intel_crtc->rotate_mem->offset;
}
/**
@ -1380,26 +1345,16 @@ static void
i830_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
{
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
if (rotate_pixmap)
FreeScratchPixmapHeader(rotate_pixmap);
if (data)
{
#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 */
if (data) {
/* Be sure to sync acceleration before the memory gets unbound. */
I830Sync(pScrn);
i830_free_memory(pScrn, intel_crtc->rotate_mem);
intel_crtc->rotate_mem = NULL;
}
}

View File

@ -1562,7 +1562,11 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
memset(&req, 0, sizeof(req));
req.majorversion = 2;
#if EXA_VERSION_MINOR >= 2
req.minorversion = 2;
#else
req.minorversion = 1;
#endif
if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req,
&errmaj, &errmin)) {
LoaderErrorMsg(NULL, "exa", errmaj, errmin);

View File

@ -124,6 +124,22 @@ i830_pixmap_tiled(PixmapPtr pPixmap)
return FALSE;
}
Bool
i830_exa_pixmap_is_offscreen(PixmapPtr pPixmap)
{
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
if ((void *)pPixmap->devPrivate.ptr >= (void *)pI830->FbBase &&
(void *)pPixmap->devPrivate.ptr <
(void *)(pI830->FbBase + pI830->FbMapSize))
{
return TRUE;
} else {
return FALSE;
}
}
/**
* I830EXASync - wait for a command to finish
* @pScreen: current screen
@ -456,7 +472,17 @@ I830EXAInit(ScreenPtr pScreen)
pI830->bufferOffset = 0;
pI830->EXADriverPtr->exa_major = 2;
/* If compiled against EXA 2.2, require 2.2 so we can use the
* PixmapIsOffscreen hook.
*/
#if EXA_VERSION_MINOR >= 2
pI830->EXADriverPtr->exa_minor = 2;
#else
pI830->EXADriverPtr->exa_minor = 1;
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"EXA compatibility mode. Output rotation rendering "
"performance may suffer\n");
#endif
pI830->EXADriverPtr->memoryBase = pI830->FbBase;
pI830->EXADriverPtr->offScreenBase = pI830->exa_offscreen->offset;
pI830->EXADriverPtr->memorySize = pI830->exa_offscreen->offset +
@ -552,6 +578,9 @@ I830EXAInit(ScreenPtr pScreen)
pI830->EXADriverPtr->Composite = i965_composite;
pI830->EXADriverPtr->DoneComposite = i830_done_composite;
}
#if EXA_VERSION_MINOR >= 2
pI830->EXADriverPtr->PixmapIsOffscreen = i830_exa_pixmap_is_offscreen;
#endif
/* UploadToScreen/DownloadFromScreen */
if (0)

View File

@ -1684,41 +1684,3 @@ 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