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.
This commit is contained in:
parent
83cc4601b2
commit
5c1e27cdd2
16
src/i830.h
16
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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
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 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue