rotation support for randr-1.2
This patch trys to resolve rotation regression with randr-1.2. Tested with Crestline VGA output. See bug 83.
This commit is contained in:
parent
a1796bfb51
commit
fbd3f588f0
|
|
@ -196,6 +196,8 @@ extern const char *i830_output_type_names[];
|
|||
typedef struct _I830CrtcPrivateRec {
|
||||
int pipe;
|
||||
Bool gammaEnabled;
|
||||
Rotation rotation; /* current rotation, mirror from pI830->rotation */
|
||||
Rotation rotations; /* all */
|
||||
} I830CrtcPrivateRec, *I830CrtcPrivatePtr;
|
||||
|
||||
#define I830CrtcPrivate(c) ((I830CrtcPrivatePtr) (c)->driver_private)
|
||||
|
|
|
|||
|
|
@ -821,7 +821,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
|
|||
((adjusted_mode->CrtcVBlankEnd - 1) << 16));
|
||||
OUTREG(vsync_reg, (adjusted_mode->CrtcVSyncStart - 1) |
|
||||
((adjusted_mode->CrtcVSyncEnd - 1) << 16));
|
||||
OUTREG(dspstride_reg, pScrn->displayWidth * pI830->cpp);
|
||||
/* XXX we might always set real line stride, rotation can change it */
|
||||
// OUTREG(dspstride_reg, pScrn->displayWidth * pI830->cpp);
|
||||
OUTREG(dspstride_reg, pI830->displayWidth * pI830->cpp);
|
||||
/* pipesrc and dspsize control the size that is scaled from, which should
|
||||
* always be the user's requested size.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2950,11 +2950,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
|
|||
shadowSetup(pScreen);
|
||||
/* support all rotations */
|
||||
xf86RandR12Init (pScreen);
|
||||
if (IS_I965G(pI830)) {
|
||||
xf86RandR12SetRotations (pScreen, RR_Rotate_0); /* only 0 degrees for I965G */
|
||||
} else {
|
||||
xf86RandR12SetRotations (pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
|
||||
}
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -333,6 +333,14 @@ xf86RandR12GetRotation(ScreenPtr pScreen)
|
|||
return randrp->rotation;
|
||||
}
|
||||
|
||||
Rotation
|
||||
xf86RandR12GetRotation12(RRCrtcPtr randr_crtc)
|
||||
{
|
||||
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
||||
I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc);
|
||||
return intel_crtc->rotation;
|
||||
}
|
||||
|
||||
Bool
|
||||
xf86RandR12CreateScreenResources (ScreenPtr pScreen)
|
||||
{
|
||||
|
|
@ -422,12 +430,29 @@ xf86RandR12Init (ScreenPtr pScreen)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* RandR12 should have been initialized, so we might set rotations
|
||||
to Crtc object.
|
||||
*/
|
||||
void
|
||||
xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
|
||||
{
|
||||
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
||||
#if RANDR_12_INTERFACE
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
int c;
|
||||
#endif
|
||||
|
||||
randrp->supported_rotations = rotations;
|
||||
#if RANDR_12_INTERFACE
|
||||
for (c = 0; c < config->num_crtc ; c++) {
|
||||
xf86CrtcPtr crtc = config->crtc[c];
|
||||
I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc);
|
||||
crtc->randr_crtc->rotations = rotations;
|
||||
intel_crtc->rotations = rotations;
|
||||
intel_crtc->rotation = RR_Rotate_0; /*XXX initial rotation fix */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -468,11 +493,13 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
|
|||
}
|
||||
if (pRoot)
|
||||
(*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
|
||||
pScrn->virtualX = width;
|
||||
pScrn->virtualY = height;
|
||||
|
||||
pScreen->width = pScrn->virtualX;
|
||||
pScreen->height = pScrn->virtualY;
|
||||
/* XXX don't change the actual draw window size */
|
||||
/*pScrn->virtualX = width;
|
||||
*pScrn->virtualY = height;
|
||||
*pScreen->width = pScrn->virtualX;
|
||||
*pScreen->height = pScrn->virtualY;*/
|
||||
pScreen->width = width;
|
||||
pScreen->height = height;
|
||||
pScreen->mmWidth = mmWidth;
|
||||
pScreen->mmHeight = mmHeight;
|
||||
|
||||
|
|
@ -509,7 +536,7 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
|
|||
return FALSE;
|
||||
x = crtc->x;
|
||||
y = crtc->y;
|
||||
rotation = RR_Rotate_0;
|
||||
rotation = xf86RandR12GetRotation12(randr_crtc);
|
||||
numOutputs = 0;
|
||||
randr_mode = NULL;
|
||||
for (i = 0; i < config->num_output; i++)
|
||||
|
|
@ -540,6 +567,9 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
|
|||
return ret;
|
||||
}
|
||||
|
||||
extern Bool i830RandR12Rotate(ScreenPtr pScreen, RRCrtcPtr randr_crtc,
|
||||
DisplayModePtr mode, Rotation rotation);
|
||||
|
||||
static Bool
|
||||
xf86RandR12CrtcSet (ScreenPtr pScreen,
|
||||
RRCrtcPtr randr_crtc,
|
||||
|
|
@ -556,6 +586,8 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
|
|||
DisplayModePtr mode = randr_mode ? randr_mode->devPrivate : NULL;
|
||||
Bool changed = FALSE;
|
||||
Bool pos_changed;
|
||||
Bool rotation_changed = FALSE;
|
||||
Rotation old_rotation;
|
||||
int o, ro;
|
||||
xf86CrtcPtr *save_crtcs;
|
||||
Bool save_enabled = crtc->enabled;
|
||||
|
|
@ -569,6 +601,14 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
|
|||
pos_changed = changed;
|
||||
if (x != crtc->x || y != crtc->y)
|
||||
pos_changed = TRUE;
|
||||
|
||||
old_rotation = xf86RandR12GetRotation12(randr_crtc);
|
||||
if (rotation != old_rotation) {
|
||||
changed = TRUE;
|
||||
rotation_changed = TRUE;
|
||||
pos_changed = TRUE;
|
||||
}
|
||||
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
{
|
||||
xf86OutputPtr output = config->output[o];
|
||||
|
|
@ -604,6 +644,14 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
|
|||
pI830->AccelInfoRec->NeedToSync = FALSE;
|
||||
}
|
||||
|
||||
/* rotation should take effect when crtc enabled*/
|
||||
if (rotation_changed && crtc->enabled) {
|
||||
randr_crtc->rotation = rotation;
|
||||
if (!i830RandR12Rotate(pScreen, randr_crtc, mode, rotation)) {
|
||||
randr_crtc->rotation = old_rotation;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode)
|
||||
{
|
||||
if (!i830PipeSetMode (crtc, mode, TRUE))
|
||||
|
|
|
|||
|
|
@ -60,9 +60,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#include "i830.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_3d.h"
|
||||
#include "i830_xf86Crtc.h"
|
||||
#include "i830_randr.h"
|
||||
|
||||
#include "brw_defines.h"
|
||||
#include "brw_structs.h"
|
||||
|
||||
#ifdef XF86DRI
|
||||
#include "dri.h"
|
||||
#endif
|
||||
|
|
@ -1341,6 +1343,268 @@ I830UpdateRotate (ScreenPtr pScreen,
|
|||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
Bool i830_setup_shadowfb(ScrnInfoPtr pScrn, xf86CrtcPtr crtc)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc);
|
||||
ShadowUpdateProc func = NULL;
|
||||
|
||||
if (pI830->noAccel)
|
||||
func = LoaderSymbol("shadowUpdateRotatePacked");
|
||||
else {
|
||||
if (IS_I9XX(pI830)) {
|
||||
if (IS_I965G(pI830))
|
||||
func = I965UpdateRotate;
|
||||
else
|
||||
func = I915UpdateRotate;
|
||||
} else
|
||||
func = I830UpdateRotate;
|
||||
}
|
||||
|
||||
if (!func)
|
||||
return FALSE;
|
||||
|
||||
shadowRemove (pScrn->pScreen, NULL);
|
||||
if (intel_crtc->rotation != RR_Rotate_0) {
|
||||
shadowAdd (pScrn->pScreen,
|
||||
(*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen),
|
||||
func, I830WindowLinear, intel_crtc->rotation, 0);
|
||||
}
|
||||
|
||||
if (intel_crtc->rotation != RR_Rotate_0)
|
||||
pScrn->fbOffset = pI830->RotatedMem.Start;
|
||||
else
|
||||
pScrn->fbOffset = pI830->FrontBuffer.Start;
|
||||
|
||||
I830SelectBuffer(pScrn, I830_SELECT_FRONT);
|
||||
|
||||
pScrn->pScreen->ModifyPixmapHeader((*pScrn->pScreen->GetScreenPixmap)(pScrn->pScreen),
|
||||
pScrn->pScreen->width,
|
||||
pScrn->pScreen->height,
|
||||
pScrn->pScreen->rootDepth, pScrn->bitsPerPixel,
|
||||
PixmapBytePad(pScrn->displayWidth, pScrn->pScreen->rootDepth),
|
||||
(pointer)(pI830->FbBase + pScrn->fbOffset));
|
||||
(*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, FALSE);
|
||||
(*pScrn->EnableDisableFBAccess) (pScrn->pScreen->myNum, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static
|
||||
Bool i830_rotate_mem_realloc(ScrnInfoPtr pScrn, xf86CrtcPtr crtc)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc);
|
||||
#ifdef XF86DRI
|
||||
Bool didLock = FALSE;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
#ifdef XF86DRI
|
||||
if (pI830->directRenderingEnabled) {
|
||||
didLock = I830DRILock(pScrn);
|
||||
|
||||
/* Do heap teardown here
|
||||
*/
|
||||
if (pI830->mmModeFlags & I830_KERNEL_TEX) {
|
||||
drmI830MemDestroyHeap destroy;
|
||||
destroy.region = I830_MEM_REGION_AGP;
|
||||
|
||||
if (drmCommandWrite(pI830->drmSubFD,
|
||||
DRM_I830_DESTROY_HEAP,
|
||||
&destroy, sizeof(destroy))) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"[dri] I830 destroy heap failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (pI830->mmModeFlags & I830_KERNEL_TEX) {
|
||||
if (pI830->TexMem.Key != -1)
|
||||
xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->TexMem.Key);
|
||||
I830FreeVidMem(pScrn, &(pI830->TexMem));
|
||||
}
|
||||
if (pI830->StolenPool.Allocated.Key != -1) {
|
||||
xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->StolenPool.Allocated.Key);
|
||||
xf86DeallocateGARTMemory(pScrn->scrnIndex, pI830->StolenPool.Allocated.Key);
|
||||
}
|
||||
if (pI830->DepthBuffer.Key != -1)
|
||||
xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->DepthBuffer.Key);
|
||||
I830FreeVidMem(pScrn, &(pI830->DepthBuffer));
|
||||
if (pI830->BackBuffer.Key != -1)
|
||||
xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->BackBuffer.Key);
|
||||
I830FreeVidMem(pScrn, &(pI830->BackBuffer));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pI830->RotatedMem.Key != -1)
|
||||
xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->RotatedMem.Key);
|
||||
|
||||
I830FreeVidMem(pScrn, &(pI830->RotatedMem));
|
||||
memset(&(pI830->RotatedMem), 0, sizeof(pI830->RotatedMem));
|
||||
pI830->RotatedMem.Key = -1;
|
||||
|
||||
if (IS_I965G(pI830)) {
|
||||
if (pI830->RotateStateMem.Key != -1)
|
||||
xf86UnbindGARTMemory(pScrn->scrnIndex, pI830->RotateStateMem.Key);
|
||||
|
||||
I830FreeVidMem(pScrn, &(pI830->RotateStateMem));
|
||||
memset(&(pI830->RotateStateMem), 0, sizeof(pI830->RotateStateMem));
|
||||
pI830->RotateStateMem.Key = -1;
|
||||
}
|
||||
|
||||
if (intel_crtc->rotation != RR_Rotate_0) {
|
||||
if (!I830AllocateRotatedBuffer(pScrn, pI830->disableTiling ? ALLOC_NO_TILING : 0))
|
||||
goto BAIL1;
|
||||
|
||||
I830FixOffset(pScrn, &(pI830->RotatedMem));
|
||||
if (pI830->RotatedMem.Key != -1)
|
||||
xf86BindGARTMemory(pScrn->scrnIndex, pI830->RotatedMem.Key, pI830->RotatedMem.Offset);
|
||||
if (IS_I965G(pI830)) {
|
||||
I830FixOffset(pScrn, &(pI830->RotateStateMem));
|
||||
if (pI830->RotateStateMem.Key != -1)
|
||||
xf86BindGARTMemory(pScrn->scrnIndex, pI830->RotateStateMem.Key,
|
||||
pI830->RotateStateMem.Offset);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef XF86DRI
|
||||
if (pI830->directRenderingEnabled) {
|
||||
if (!I830AllocateBackBuffer(pScrn,
|
||||
pI830->disableTiling ? ALLOC_NO_TILING : 0))
|
||||
goto BAIL2;
|
||||
|
||||
if (!I830AllocateDepthBuffer(pScrn,
|
||||
pI830->disableTiling ? ALLOC_NO_TILING : 0))
|
||||
goto BAIL3;
|
||||
|
||||
if (pI830->mmModeFlags & I830_KERNEL_TEX) {
|
||||
if (!I830AllocateTextureMemory(pScrn,
|
||||
pI830->disableTiling ? ALLOC_NO_TILING : 0))
|
||||
goto BAIL4;
|
||||
}
|
||||
|
||||
I830DoPoolAllocation(pScrn, &(pI830->StolenPool));
|
||||
|
||||
I830FixOffset(pScrn, &(pI830->BackBuffer));
|
||||
I830FixOffset(pScrn, &(pI830->DepthBuffer));
|
||||
|
||||
if (pI830->BackBuffer.Key != -1)
|
||||
xf86BindGARTMemory(pScrn->scrnIndex, pI830->BackBuffer.Key, pI830->BackBuffer.Offset);
|
||||
if (pI830->DepthBuffer.Key != -1)
|
||||
xf86BindGARTMemory(pScrn->scrnIndex, pI830->DepthBuffer.Key, pI830->DepthBuffer.Offset);
|
||||
if (pI830->StolenPool.Allocated.Key != -1)
|
||||
xf86BindGARTMemory(pScrn->scrnIndex, pI830->StolenPool.Allocated.Key, pI830->StolenPool.Allocated.Offset);
|
||||
if (pI830->mmModeFlags & I830_KERNEL_TEX) {
|
||||
if (pI830->TexMem.Key != -1)
|
||||
xf86BindGARTMemory(pScrn->scrnIndex, pI830->TexMem.Key, pI830->TexMem.Offset);
|
||||
}
|
||||
I830SetupMemoryTiling(pScrn);
|
||||
/* update fence registers */
|
||||
if (IS_I965G(pI830)) {
|
||||
for (i = 0; i < FENCE_NEW_NR; i++) {
|
||||
OUTREG(FENCE_NEW + i * 8, pI830->ModeReg.Fence[i]);
|
||||
OUTREG(FENCE_NEW + 4 + i * 8, pI830->ModeReg.Fence[i+FENCE_NEW_NR]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 8; i++)
|
||||
OUTREG(FENCE + i * 4, pI830->ModeReg.Fence[i]);
|
||||
}
|
||||
|
||||
{
|
||||
drmI830Sarea *sarea = DRIGetSAREAPrivate(pScrn->pScreen);
|
||||
I830UpdateDRIBuffers(pScrn, sarea );
|
||||
}
|
||||
|
||||
if (didLock)
|
||||
I830DRIUnlock(pScrn);
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
BAIL1:
|
||||
BAIL2:
|
||||
BAIL3:
|
||||
BAIL4:
|
||||
//XXX alloc failure
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool
|
||||
i830RandR12Rotate(ScreenPtr pScreen, RRCrtcPtr randr_crtc,
|
||||
DisplayModePtr mode, Rotation rotation)
|
||||
{
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
||||
I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc);
|
||||
Rotation old_rotation = intel_crtc->rotation;
|
||||
|
||||
if (old_rotation == rotation)
|
||||
return TRUE;
|
||||
intel_crtc->rotation = rotation;
|
||||
pI830->rotation = rotation;
|
||||
|
||||
*pI830->used3D |= 1<<31; /* use high bit to denote new rotation occured */
|
||||
|
||||
|
||||
/* user should have already changed screen size. */
|
||||
/* pI830->displayWidth should always trigger current width in use,
|
||||
pScrn->displayWidth is current config in use. */
|
||||
switch (intel_crtc->rotation) {
|
||||
case RR_Rotate_0:
|
||||
ErrorF("Rotating Screen to 0 degrees\n");
|
||||
pScrn->displayWidth = pI830->displayWidth;
|
||||
break;
|
||||
case RR_Rotate_90:
|
||||
ErrorF("Rotating Screen to 90 degrees\n");
|
||||
pScrn->displayWidth = pScrn->pScreen->width;
|
||||
break;
|
||||
case RR_Rotate_180:
|
||||
ErrorF("Rotating Screen to 180 degrees\n");
|
||||
pScrn->displayWidth = pI830->displayWidth;
|
||||
break;
|
||||
case RR_Rotate_270:
|
||||
ErrorF("Rotating Screen to 270 degrees\n");
|
||||
pScrn->displayWidth = pScrn->pScreen->width;
|
||||
break;
|
||||
}
|
||||
ErrorF("pScrn->displayWidth %d\n", pScrn->displayWidth);
|
||||
|
||||
if (!i830_rotate_mem_realloc(pScrn, crtc)) {
|
||||
intel_crtc->rotation = old_rotation;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!i830_setup_shadowfb(pScrn, crtc)) {
|
||||
intel_crtc->rotation = old_rotation;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef I830_USE_XAA
|
||||
if (pI830->AccelInfoRec != NULL) {
|
||||
/* Don't allow pixmap cache or offscreen pixmaps when rotated */
|
||||
/* XAA needs some serious fixing for this to happen */
|
||||
if (intel_crtc->rotation == RR_Rotate_0) {
|
||||
pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS |
|
||||
PIXMAP_CACHE;
|
||||
pI830->AccelInfoRec->UsingPixmapCache = TRUE;
|
||||
/* funny as it seems this will enable XAA's createpixmap */
|
||||
pI830->AccelInfoRec->maxOffPixWidth = 0;
|
||||
pI830->AccelInfoRec->maxOffPixHeight = 0;
|
||||
} else {
|
||||
pI830->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER;
|
||||
pI830->AccelInfoRec->UsingPixmapCache = FALSE;
|
||||
/* funny as it seems this will disable XAA's createpixmap */
|
||||
pI830->AccelInfoRec->maxOffPixWidth = 1;
|
||||
pI830->AccelInfoRec->maxOffPixHeight = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
I830Rotate(ScrnInfoPtr pScrn, DisplayModePtr mode)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -517,6 +517,7 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
|
|||
xf86CrtcPtr crtc;
|
||||
DisplayModePtr last, mode;
|
||||
int originalVirtualX, originalVirtualY;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
output = config->output[config->compat_output];
|
||||
if (!output->crtc)
|
||||
|
|
@ -549,9 +550,10 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
|
|||
/* Disable modes in the XFree86 DDX list that are larger than the current
|
||||
* virtual size.
|
||||
*/
|
||||
/* pass real line pitch, rotation might change this */
|
||||
i830xf86ValidateModesSize(pScrn, pScrn->modes,
|
||||
originalVirtualX, originalVirtualY,
|
||||
pScrn->displayWidth);
|
||||
pI830->displayWidth);
|
||||
|
||||
/* Strip out anything that we threw out for virtualX/Y. */
|
||||
i830xf86PruneInvalidModes(pScrn, &pScrn->modes, TRUE);
|
||||
|
|
|
|||
Loading…
Reference in New Issue