Allocate per-crtc rotation buffers and hook up RandR 1.2 per-CRTC rotation.

It currently displays garbage.
This commit is contained in:
Eric Anholt 2007-01-17 16:01:18 -08:00
parent d17c386aee
commit f256243fff
4 changed files with 112 additions and 7 deletions

View File

@ -195,8 +195,11 @@ extern const char *i830_output_type_names[];
typedef struct _I830CrtcPrivateRec {
int pipe;
/* Lookup table values to be set when the CRTC is enabled */
CARD8 lut_r[256], lut_g[256], lut_b[256];
I830MemRange rotate_mem;
} I830CrtcPrivateRec, *I830CrtcPrivatePtr;
#define I830CrtcPrivate(c) ((I830CrtcPrivatePtr) (c)->driver_private)

View File

@ -342,9 +342,11 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y)
int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
if (I830IsPrimary(pScrn))
if (intel_crtc->rotate_mem.Start != 0) {
Start = intel_crtc->rotate_mem.Start;
} else if (I830IsPrimary(pScrn)) {
Start = pI830->FrontBuffer.Start;
else {
} else {
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
Start = pI8301->FrontBuffer2.Start;
}
@ -882,6 +884,45 @@ i830_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
i830_crtc_load_lut(crtc);
}
/**
* Creates a locked-in-framebuffer pixmap of the given width and height for
* this CRTC's rotated shadow framebuffer.
*
* The current implementation uses fixed buffers allocated at startup at the
* maximal size.
*/
static PixmapPtr
i830_crtc_shadow_create(xf86CrtcPtr crtc, int width, int height)
{
ScrnInfoPtr pScrn = crtc->scrn;
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;
rotate_pitch = pI830->displayWidth * pI830->cpp;
rotate_offset = pI830->FbBase + intel_crtc->rotate_mem.Start;
rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
width, height,
pScrn->depth,
pScrn->bitsPerPixel,
rotate_pitch,
rotate_offset);
return rotate_pixmap;
}
static void
i830_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap)
{
FreeScratchPixmapHeader(rotate_pixmap);
}
/**
* This function configures the screens in clone mode on
* all active outputs using a mode similar to the specified mode.
@ -1038,6 +1079,8 @@ static const xf86CrtcFuncsRec i830_crtc_funcs = {
.mode_fixup = i830_crtc_mode_fixup,
.mode_set = i830_crtc_mode_set,
.gamma_set = i830_crtc_gamma_set,
.shadow_create = i830_crtc_shadow_create,
.shadow_destroy = i830_crtc_shadow_destroy,
.destroy = NULL, /* XXX */
};

View File

@ -769,6 +769,63 @@ 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;
}
/*
* Allocate memory for 2D operation. This includes the (front) framebuffer,
* ring buffer, scratch memory, HW cursor.
@ -782,7 +839,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
int verbosity = dryrun ? 4 : 1;
const char *s = dryrun ? "[dryrun] " : "";
Bool tileable;
int align, alignflags;
int align, alignflags, i;
DPRINTF(PFX, "I830Allocate2DMemory: inital is %s\n",
BOOLTOSTRING(flags & ALLOC_INITIAL));
@ -814,6 +871,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
pI830->StolenPool.Free.Size);
if (flags & ALLOC_INITIAL) {
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
if (pI830->NeedRingBufferLow)
AllocateRingBuffer(pScrn, flags | FORCE_LOW);
@ -839,6 +897,10 @@ 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

View File

@ -190,13 +190,10 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
goto done;
}
#if 0
if (!xf86CrtcRotate (crtc, mode, rotation))
{
if (!xf86CrtcRotate (crtc, mode, rotation)) {
ret = FALSE;
goto done;
}
#endif
/* Disable the outputs and CRTCs before setting the mode. */
for (i = 0; i < xf86_config->num_output; i++) {