From e065324661ad08b3b359136f48090232f6138959 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Wed, 22 Nov 2006 16:49:36 +0000 Subject: [PATCH 01/82] update port attributes immediately when overlay is on. --- src/i830_video.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/i830_video.c b/src/i830_video.c index 054d26bb..1a1b9680 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -934,14 +934,16 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, pPriv->brightness = value; overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff); ErrorF("BRIGHTNESS\n"); - OVERLAY_UPDATE; + if (*pI830->overlayOn) + OVERLAY_UPDATE; } else if (attribute == xvContrast) { if ((value < 0) || (value > 255)) return BadValue; pPriv->contrast = value; overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff); ErrorF("CONTRAST\n"); - OVERLAY_UPDATE; + if (*pI830->overlayOn) + OVERLAY_UPDATE; } else if (pI830->Clone && attribute == xvPipe) { if ((value < 0) || (value > 1)) return BadValue; @@ -955,7 +957,8 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, else overlay->OCONFIG |= OVERLAY_PIPE_B; ErrorF("PIPE CHANGE\n"); - OVERLAY_UPDATE; + if (*pI830->overlayOn) + OVERLAY_UPDATE; } else if (attribute == xvGamma0 && (IS_I9XX(pI830))) { pPriv->gamma0 = value; } else if (attribute == xvGamma1 && (IS_I9XX(pI830))) { @@ -982,7 +985,8 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, break; } ErrorF("COLORKEY\n"); - OVERLAY_UPDATE; + if (*pI830->overlayOn) + OVERLAY_UPDATE; REGION_EMPTY(pScrn->pScreen, &pPriv->clip); } else if(attribute == xvDoubleBuffer) { if ((value < 0) || (value > 1)) @@ -1000,13 +1004,8 @@ I830SetPortAttribute(ScrnInfoPtr pScrn, attribute == xvGamma3 || attribute == xvGamma4 || attribute == xvGamma5) && (IS_I9XX(pI830))) { - CARD32 r = overlay->OCMD & OVERLAY_ENABLE; ErrorF("GAMMA\n"); - overlay->OCMD &= ~OVERLAY_ENABLE; - OVERLAY_UPDATE; I830UpdateGamma(pScrn); - overlay->OCMD |= r; - OVERLAY_UPDATE; } return Success; From 6781575f734f05547d7d5ceef4116fc157bba44d Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Wed, 22 Nov 2006 16:49:57 +0000 Subject: [PATCH 02/82] Be a little more verbose when rejecting modes. --- src/i830_modes.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/i830_modes.c b/src/i830_modes.c index 7d145198..002c0048 100644 --- a/src/i830_modes.c +++ b/src/i830_modes.c @@ -394,7 +394,6 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id, !I830CheckModeSupport(pScrn, mode->XResolution, mode->YResolution, id)) modeOK = FALSE; - /* * Check if there's a valid monitor mode that this one can be matched * up with from the 'specified' modes list. @@ -410,6 +409,9 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id, if (status == MODE_OK) { modeOK = TRUE; break; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not using mode \"%s\" (%s)\n", p->name, + xf86ModeStatusToString(status)); } } if (p) { @@ -442,6 +444,9 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id, newMode = p; } modeOK = TRUE; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not using mode \"%s\" (%s)\n", p->name, + xf86ModeStatusToString(status)); } } if (newMode) { @@ -487,8 +492,11 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id, modeOK = FALSE; } else modeOK = TRUE; - } else + } else { modeOK = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not using mode \"%s\" (%s)\n", pMode->name, + xf86ModeStatusToString(status)); + } pMode->status = status; } else { modeOK = FALSE; From 99f6f84076b25af69dc226e6d4704c74d207e657 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Thu, 7 Dec 2006 09:47:34 +0000 Subject: [PATCH 03/82] Bump to 1.7.3 --- configure.ac | 2 +- src/i810_dri.h | 2 +- src/i830_dri.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index fc0f9cd8..48b39a14 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ AC_PREREQ(2.57) AC_INIT([xf86-video-i810], - 1.7.2, + 1.7.3, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xf86-video-i810) diff --git a/src/i810_dri.h b/src/i810_dri.h index f090b923..70ea8999 100644 --- a/src/i810_dri.h +++ b/src/i810_dri.h @@ -10,7 +10,7 @@ #define I810_MAJOR_VERSION 1 #define I810_MINOR_VERSION 7 -#define I810_PATCHLEVEL 2 +#define I810_PATCHLEVEL 3 typedef struct { drm_handle_t regs; diff --git a/src/i830_dri.h b/src/i830_dri.h index a1404978..969eb60e 100644 --- a/src/i830_dri.h +++ b/src/i830_dri.h @@ -10,7 +10,7 @@ #define I830_MAJOR_VERSION 1 #define I830_MINOR_VERSION 7 -#define I830_PATCHLEVEL 2 +#define I830_PATCHLEVEL 3 #define I830_REG_SIZE 0x80000 From e3604fc63243ab0f31673a923d20e23131b607f6 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Wed, 13 Dec 2006 15:42:53 +0000 Subject: [PATCH 04/82] Delete ChangeLog --- ChangeLog | 138 ------------------------------------------------------ 1 file changed, 138 deletions(-) delete mode 100644 ChangeLog diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index d77176bb..00000000 --- a/ChangeLog +++ /dev/null @@ -1,138 +0,0 @@ -2006-05-01 Matthieu Herrb - - * src/common.h: - Fix build on non-dri systems. - -2006-04-07 Adam Jackson - - * configure.ac: - * src/i810.h: - Bump to 1.6.0. - -2006-04-07 Aaron Plattner - - * src/i810_video.c: (I810PutImage): - * src/i830_video.c: (I830PutImage): - Add a DrawablePtr argument to the XV functions to pave the way for - redirected video. - -2006-04-05 Dave Airlie - - * src/i810_hwmc.c: (I810XvMCCreateContext), - (I810XvMCCreateSurface), (I810XvMCCreateSubpicture): - * src/i810_memory.c: (I810SetTiledMemory): - * src/i830_memory.c: (SetFence): - Fix some argument inversions in xf86DrvMsg function calls - -2006-04-04 Kristian Høgsberg - - * src/i810_dri.c: - * src/i810_driver.c: - * src/i830_dri.c: - * src/i830_driver.c: Add more missing #include's, in particular - assert.h. - -2006-03-22 Kristian Høgsberg - - * src/*.c: Drop libc wrapper; don't include xf86_ansic.h and add - includes now missing. - -2006-03-10 Alan Hourihane - - * src/i830_cursor.c: (I830InitHWCursor), (I830ShowCursor), - (I830HideCursor): - Enable gamma for hw cursor when ARGB cursor in use (Lukas Hejtmanek) - -2006-03-03 Alan Hourihane - - * configure.ac: - * src/i810.h: - * src/i830.h: - * src/i830_dri.h: - * src/i830_driver.c: (I830BIOSPreInit), (I830BIOSScreenInit), - (I830BIOSCloseScreen): - * src/i830_video.c: - Check the version of shadow being used and turn off rotation if - it isn't the right one. - Bump the Xvideo resolution support from 1920x1080 to 1920x1088. - -2006-02-20 Alan Hourihane - - * src/i830_rotate.c: (I915UpdateRotate), (I830UpdateRotate): - Fix a rotation problem when DRI is disabled - -2005-01-25 Alan Hourihane - - * src/i830_driver.c: When going dual head only take a portion of - memory for the second head instead of doubling the requirements. - -2005-01-25 Alan Hourihane - - * src/i830_driver.c: Fix a glitch in a dual head fix from #3105 - -2005-01-24 Alan Hourihane - - * configure.ac, man/i810.man, src/Makefile.am, src/common.h, - src/i810.h, src/i810_dri.c, src/i810_driver.c, src/i830.h, - src/i830_common.h, src/i830_cursor.c, src/i830_dga.c, - src/i830_dri.c, src/i830_dri.h, src/i830_driver.c, - src/i830_memory.c, src/i830_modes.c, src/i830_randr.c, - src/i830_rotate.c, src/i830_shadow.c, src/i830_video.c: - Bump version to 1.5.0.0 - Add Intel 945GM support - Add RandR rotation support (full 3D acceleration, HWcursor & - Xvideo rotated too) - Remove older shadow framebuffer rotation code - Add a new LinearAlloc option to allow more offscreen memory - to be allocated for XVideo applications. This allows HDTV movies - to be played via Xvideo. - -2005-12-20 Kevin E. Martin - - * configure.ac: - Update package version for X11R7 release. - -2005-12-14 Kevin E. Martin - - * configure.ac: - Update package version number for final X11R7 release candidate. - -2005-12-06 Kevin E. Martin - - * man/Makefile.am: - Change *man_SOURCES ==> *man_PRE to fix autotools warnings. - -2005-12-03 Kevin E. Martin - - * configure.ac: - Update package version number for X11R7 RC3 release. - -2005-12-01 Kevin E. Martin - - * configure.ac: - Remove extraneous AC_MSG_RESULT. - -2005-11-30 Adam Jackson - - * configure.ac: - Bump libdrm dep to 2.0. - -2005-11-29 Adam Jackson - - * configure.ac: - Only build dlloader modules by default. - -2005-11-19 Kevin E. Martin - - * configure.ac: - Update dependencies to work with separate build roots. - -2005-11-09 Kevin E. Martin - - * configure.ac: - Update package version number for X11R7 RC2 release. - -2005-11-01 Kevin E. Martin - - * configure.ac: - Update pkgcheck dependencies to work with separate build roots. From 08575331ac75783c9910cfb6e78db701a29983ac Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Fri, 15 Dec 2006 17:44:44 -0500 Subject: [PATCH 05/82] Convert callers of LookupWindow() to dixLookupWindow(). --- src/i830_driver.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index e950d7c3..e133c856 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1760,8 +1760,9 @@ I830ProcXineramaGetState(ClientPtr client) register int n; REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); - pWin = LookupWindow(stuff->window, client); - if(!pWin) return BadWindow; + n = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess); + if (n != Success) + return n; rep.type = X_Reply; rep.length = 0; @@ -1785,8 +1786,9 @@ I830ProcXineramaGetScreenCount(ClientPtr client) register int n; REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); - pWin = LookupWindow(stuff->window, client); - if(!pWin) return BadWindow; + n = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess); + if (n != Success) + return n; rep.type = X_Reply; rep.length = 0; @@ -1810,8 +1812,9 @@ I830ProcXineramaGetScreenSize(ClientPtr client) register int n; REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); - pWin = LookupWindow (stuff->window, client); - if(!pWin) return BadWindow; + n = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess); + if (n != Success) + return n; rep.type = X_Reply; rep.length = 0; From 1975fa5b010100196af201e40f43b30a149b7750 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Mon, 18 Dec 2006 14:08:55 -0500 Subject: [PATCH 06/82] Revert "Convert callers of LookupWindow() to dixLookupWindow()." This reverts commit 08575331ac75783c9910cfb6e78db701a29983ac. --- src/i830_driver.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index e133c856..e950d7c3 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1760,9 +1760,8 @@ I830ProcXineramaGetState(ClientPtr client) register int n; REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); - n = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess); - if (n != Success) - return n; + pWin = LookupWindow(stuff->window, client); + if(!pWin) return BadWindow; rep.type = X_Reply; rep.length = 0; @@ -1786,9 +1785,8 @@ I830ProcXineramaGetScreenCount(ClientPtr client) register int n; REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); - n = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess); - if (n != Success) - return n; + pWin = LookupWindow(stuff->window, client); + if(!pWin) return BadWindow; rep.type = X_Reply; rep.length = 0; @@ -1812,9 +1810,8 @@ I830ProcXineramaGetScreenSize(ClientPtr client) register int n; REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); - n = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess); - if (n != Success) - return n; + pWin = LookupWindow (stuff->window, client); + if(!pWin) return BadWindow; rep.type = X_Reply; rep.length = 0; From 33c0fac6d63d9a509a24c7a5e5a46a0d6ee4dc5d Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 9 Jan 2007 14:02:47 +0000 Subject: [PATCH 07/82] Fix bug #8536, i915 BIOS fails when restarting Xserver. --- src/i830_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index e950d7c3..11c23ca6 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -7087,7 +7087,7 @@ IntelEmitInvarientState(ScrnInfoPtr pScrn) I830Ptr pI830 = I830PTR(pScrn); CARD32 ctx_addr; - if (pI830->noAccel) + if (pI830->noAccel || !I830IsPrimary(pScrn)) return; ctx_addr = pI830->ContextMem.Start; From efb75f56053ee06f1dbd4edfaea9986b27162afb Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 9 Jan 2007 14:05:43 +0000 Subject: [PATCH 08/82] Bump to 1.7.4 --- configure.ac | 2 +- src/i810_dri.h | 2 +- src/i830_dri.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 48b39a14..a232f184 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ AC_PREREQ(2.57) AC_INIT([xf86-video-i810], - 1.7.3, + 1.7.4, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xf86-video-i810) diff --git a/src/i810_dri.h b/src/i810_dri.h index 70ea8999..5aa43383 100644 --- a/src/i810_dri.h +++ b/src/i810_dri.h @@ -10,7 +10,7 @@ #define I810_MAJOR_VERSION 1 #define I810_MINOR_VERSION 7 -#define I810_PATCHLEVEL 3 +#define I810_PATCHLEVEL 4 typedef struct { drm_handle_t regs; diff --git a/src/i830_dri.h b/src/i830_dri.h index 969eb60e..91891a58 100644 --- a/src/i830_dri.h +++ b/src/i830_dri.h @@ -10,7 +10,7 @@ #define I830_MAJOR_VERSION 1 #define I830_MINOR_VERSION 7 -#define I830_PATCHLEVEL 3 +#define I830_PATCHLEVEL 4 #define I830_REG_SIZE 0x80000 From 85de57947570de6b3dc9197647be3e9237480880 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Sat, 13 Jan 2007 19:18:24 +0000 Subject: [PATCH 09/82] Fix bug #9639, i810 XvMC needs linking against libdrm. --- src/xvmc/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xvmc/Makefile.am b/src/xvmc/Makefile.am index 5cd5b25c..69d164a2 100644 --- a/src/xvmc/Makefile.am +++ b/src/xvmc/Makefile.am @@ -4,5 +4,5 @@ libI810XvMC_la_SOURCES = I810XvMC.c \ I810XvMC.h libI810XvMC_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(top_srcdir)/src -DTRUE=1 -DFALSE=0 -libI810XvMC_la_LDFLAGS = -version-number 1:0:0 -endif \ No newline at end of file +libI810XvMC_la_LDFLAGS = @DRI_LIBS@ -version-number 1:0:0 +endif From 319be199ba657d2b82ba034edf3581aea6dcc3f0 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 13 Jan 2007 21:34:00 +0000 Subject: [PATCH 10/82] Tweak to bug #9639 --- src/xvmc/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/xvmc/Makefile.am b/src/xvmc/Makefile.am index 69d164a2..a9ea9d1f 100644 --- a/src/xvmc/Makefile.am +++ b/src/xvmc/Makefile.am @@ -4,5 +4,6 @@ libI810XvMC_la_SOURCES = I810XvMC.c \ I810XvMC.h libI810XvMC_la_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(top_srcdir)/src -DTRUE=1 -DFALSE=0 -libI810XvMC_la_LDFLAGS = @DRI_LIBS@ -version-number 1:0:0 +libI810XvMC_la_LDFLAGS = -version-number 1:0:0 +libI810XvMC_la_LIBADD = @DRI_LIBS@ endif From 9a5106401a65c90df32cb71987fca7126dc22e81 Mon Sep 17 00:00:00 2001 From: Emilio Scalise Date: Mon, 15 Jan 2007 17:22:27 +0000 Subject: [PATCH 11/82] patch to control mergedfb options, bug #9664 --- src/i830_driver.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/i830_driver.c b/src/i830_driver.c index 11c23ca6..f7c700a7 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -270,6 +270,9 @@ typedef enum { OPTION_SECONDHSYNC, OPTION_SECONDVREFRESH, OPTION_SECONDPOSITION, + OPTION_SECONDISSCRN0, + OPTION_MERGEDFBNONRECT, + OPTION_MERGEDFBMOUSER, OPTION_INTELXINERAMA, OPTION_INTELTEXPOOL, OPTION_INTELMMSIZE @@ -299,6 +302,9 @@ static OptionInfoRec I830BIOSOptions[] = { {OPTION_SECONDHSYNC, "SecondMonitorHorizSync",OPTV_STRING, {0}, FALSE }, {OPTION_SECONDVREFRESH,"SecondMonitorVertRefresh",OPTV_STRING,{0}, FALSE }, {OPTION_SECONDPOSITION,"SecondPosition",OPTV_STRING, {0}, FALSE }, + {OPTION_SECONDISSCRN0,"MergedXineramaSecondIsScreen0", OPTV_BOOLEAN, {0}, FALSE }, + {OPTION_MERGEDFBNONRECT,"MergedNonRectangular",OPTV_BOOLEAN, {0}, FALSE}, + {OPTION_MERGEDFBMOUSER,"MergedMouseRestriction",OPTV_BOOLEAN, {0}, FALSE}, {OPTION_INTELXINERAMA,"MergedXinerama",OPTV_BOOLEAN, {0}, TRUE}, {OPTION_INTELTEXPOOL,"Legacy3D", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_INTELMMSIZE, "AperTexSize", OPTV_INTEGER, {0}, FALSE}, @@ -4755,6 +4761,27 @@ I830BIOSPreInit(ScrnInfoPtr pScrn, int flags) } xfree(tempstr); } + + /* If OPTION_SECONDISSCRN0 is true then swap screens */ + if(xf86GetOptValBool(pI830->Options, OPTION_SECONDISSCRN0, TRUE)) { + if (pI830->SecondIsScrn0) + pI830->SecondIsScrn0 = FALSE; + else + pI830->SecondIsScrn0 = TRUE; + } + + /* Set pI830->NonRect according to OPTION_MERGEDFBNONRECT */ + if(xf86GetOptValBool(pI830->Options, OPTION_MERGEDFBNONRECT, TRUE)) + pI830->NonRect = TRUE; + else + pI830->NonRect = FALSE; + + /* Set pI830->MouseRestrictions according to OPTION_MERGEDFBMOUSER */ + if(xf86GetOptValBool(pI830->Options, OPTION_MERGEDFBMOUSER, TRUE)) + pI830->MouseRestrictions = TRUE; + else + pI830->MouseRestrictions = FALSE; + if((s = (char *)xf86GetOptValString(pI830->Options, OPTION_METAMODES))) { pI830->MetaModes = xalloc(strlen(s) + 1); if(pI830->MetaModes) From 0df490938af10d3a748221e2fb5467b0f244f9eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 21 Dec 2006 11:27:28 +0100 Subject: [PATCH 12/82] If the DRM can handle it, enable vertical blank interrupts for both pipes. --- src/i830_dri.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index 70e7e491..3531bf52 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -1497,7 +1497,10 @@ I830DRISetVBlankInterrupt (ScrnInfoPtr pScrn, Bool on) if (pI830->directRenderingEnabled && pI830->drmMinor >= 5) { if (on) { if (xf86_config->num_crtc > 1 && xf86_config->crtc[1]->enabled) - pipe.pipe = DRM_I830_VBLANK_PIPE_B; + if (pI830->drmMinor >= 6) + pipe.pipe = DRM_I830_VBLANK_PIPE_A | DRM_I830_VBLANK_PIPE_B; + else + pipe.pipe = DRM_I830_VBLANK_PIPE_B; else pipe.pipe = DRM_I830_VBLANK_PIPE_A; } else { From 1d22bad33b634aaf61976907cb2ceeec8a9ebe4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 14 Feb 2007 12:57:12 +0100 Subject: [PATCH 13/82] Update SAREA pipe fields in i830PipeSetBase. --- src/i830_display.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/i830_display.c b/src/i830_display.c index 345eea9f..258897ee 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -361,6 +361,31 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y) OUTREG(dspbase, Start + ((y * pScrn->displayWidth + x) * pI830->cpp)); (void) INREG(dspbase); } + +#ifdef XF86DRI + if (pI830->directRenderingEnabled) { + drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn->pScreen); + + switch (pipe) { + case 0: + sPriv->pipeA_x = x; + sPriv->pipeA_y = y; + sPriv->pipeA_w = crtc->mode.HDisplay; + sPriv->pipeA_h = crtc->mode.VDisplay; + break; + case 1: + sPriv->pipeB_x = x; + sPriv->pipeB_y = y; + sPriv->pipeB_w = crtc->mode.HDisplay; + sPriv->pipeB_h = crtc->mode.VDisplay; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Can't update pipe %d in SAREA\n", pipe); + break; + } + } +#endif } /** From 3bd8edb95fcbbb49e97a1a2bdd5c8eae4f83d3a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 2 Feb 2007 17:41:18 +0100 Subject: [PATCH 14/82] Revive i830 page flipping support. Use the damage layer directly instead of via shadowfb. --- configure.ac | 5 ++ src/i830.h | 7 ++ src/i830_dri.c | 175 ++++++++++++++++++++++------------------------ src/i830_driver.c | 9 +++ src/i830_memory.c | 66 ++++++++++------- 5 files changed, 144 insertions(+), 118 deletions(-) diff --git a/configure.ac b/configure.ac index d45185ae..219fbe6a 100644 --- a/configure.ac +++ b/configure.ac @@ -94,6 +94,8 @@ if test "$DRI" != no; then [have_sarea_h="yes"], [have_sarea_h="no"]) AC_CHECK_FILE([${sdkdir}/dristruct.h], [have_dristruct_h="yes"], [have_dristruct_h="no"]) + AC_CHECK_FILE([${sdkdir}/damage.h], + [have_damage_h="yes"], [have_damage_h="no"]) fi AC_MSG_CHECKING([whether to include DRI support]) @@ -127,6 +129,9 @@ if test "$DRI" = yes; then if test "x$DRI_MM" = xyes; then AC_DEFINE(XF86DRI_MM,1,[Extended DRI memory management]) fi + if test "$have_damage_h" = yes; then + AC_DEFINE(DAMAGE,1,[Use Damage extension]) + fi fi AM_CONDITIONAL(VIDEO_DEBUG, test x$VIDEO_DEBUG = xyes) diff --git a/src/i830.h b/src/i830.h index 96972eb5..78381fbf 100644 --- a/src/i830.h +++ b/src/i830.h @@ -68,6 +68,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dri.h" #include "GL/glxint.h" #include "i830_dri.h" +#ifdef DAMAGE +#include "damage.h" +#endif #endif #ifdef I830_USE_EXA @@ -302,6 +305,10 @@ typedef struct _I830Rec { unsigned int front_tiled; unsigned int back_tiled; unsigned int depth_tiled; + +#ifdef DAMAGE + DamagePtr pDamage; +#endif #endif Bool NeedRingBufferLow; diff --git a/src/i830_dri.c b/src/i830_dri.c index 3531bf52..05171d37 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -984,17 +984,6 @@ I830DRIFinishScreenInit(ScreenPtr pScreen) DPRINTF(PFX, "I830DRIFinishScreenInit\n"); - /* Have shadow run only while there is 3d active. - */ -#if 0 - if (pI830->allowPageFlip && pI830->drmMinor >= 1) { - shadowAdd(pScreen, 0, I830DRIShadowUpdate, 0, 0, 0); - } - else -#endif - pI830->allowPageFlip = 0; - - if (!DRIFinishScreenInit(pScreen)) return FALSE; @@ -1025,6 +1014,49 @@ I830DRIFinishScreenInit(ScreenPtr pScreen) } } +#ifdef DAMAGE +/* This should be done *before* XAA syncs, + * Otherwise will have to sync again??? + */ +static void +I830DRIRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + I830Ptr pI830 = I830PTR(pScrn); + int i, cmd, br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16); + drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); + + /* Don't want to do this when no 3d is active and pages are + * right-way-round : + */ + if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0) + return; + + if (pScrn->bitsPerPixel == 32) { + cmd = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + br13 |= 3 << 24; + } else { + cmd = (XY_SRC_COPY_BLT_CMD); + br13 |= 1 << 24; + } + + for (i = 0 ; i < num ; i++, pbox++) { + BEGIN_LP_RING(8); + OUT_RING(cmd); + OUT_RING(br13); + OUT_RING((pbox->y1 << 16) | pbox->x1); + OUT_RING((pbox->y2 << 16) | pbox->x2); + OUT_RING(pI830->BackBuffer.Start); + OUT_RING((pbox->y1 << 16) | pbox->x1); + OUT_RING(br13 & 0xffff); + OUT_RING(pI830->FrontBuffer.Start); + ADVANCE_LP_RING(); + } + + DamageEmpty(pI830->pDamage); +} +#endif + static void I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, DRIContextType oldContextType, void *oldContext, @@ -1045,12 +1077,47 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, return; pI830->LockHeld = 1; I830RefreshRing(pScrn); + +#ifdef DAMAGE + if (!pI830->pDamage && pI830->allowPageFlip) { + PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen); + pI830->pDamage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, + pScreen, pPix); + + if (pI830->pDamage == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No screen damage record, page flipping disabled\n"); + pI830->allowPageFlip = 0; + } else { + DamageRegister(&pPix->drawable, pI830->pDamage); + + DamageDamageRegion(&pPix->drawable, + &WindowTable[pScreen->myNum]->winSize); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Damage tracking initialized for page flipping\n"); + } + } +#endif } else if (syncType == DRI_2D_SYNC && oldContextType == DRI_NO_CONTEXT && newContextType == DRI_2D_CONTEXT) { pI830->LockHeld = 0; if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("i830DRISwapContext (out)\n"); + +#ifdef DAMAGE + if (pI830->pDamage) { + RegionPtr pDamageReg = DamageRegion(pI830->pDamage); + + if (pDamageReg) { + int nrects = REGION_NUM_RECTS(pDamageReg); + + if (nrects) + I830DRIRefreshArea(pScrn, nrects, REGION_RECTS(pDamageReg)); + } + } +#endif } else if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("i830DRISwapContext (other)\n"); } @@ -1286,54 +1353,6 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, * might be faster, but seems like a lot more work... */ - -#if 0 -/* This should be done *before* XAA syncs, - * Otherwise will have to sync again??? - */ -static void -I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); - RegionPtr damage = &pBuf->damage; - int i, num = REGION_NUM_RECTS(damage); - BoxPtr pbox = REGION_RECTS(damage); - drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen); - int cmd, br13; - - /* Don't want to do this when no 3d is active and pages are - * right-way-round : - */ - if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0) - return; - - br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16); - - if (pScrn->bitsPerPixel == 32) { - cmd = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - br13 |= 3 << 24; - } else { - cmd = (XY_SRC_COPY_BLT_CMD); - br13 |= 1 << 24; - } - - for (i = 0 ; i < num ; i++, pbox++) { - BEGIN_LP_RING(8); - OUT_RING(cmd); - OUT_RING(br13); - OUT_RING((pbox->y1 << 16) | pbox->x1); - OUT_RING((pbox->y2 << 16) | pbox->x2); - OUT_RING(pI830->BackBuffer.Start); - OUT_RING((pbox->y1 << 16) | pbox->x1); - OUT_RING(br13 & 0xffff); - OUT_RING(pI830->FrontBuffer.Start); - ADVANCE_LP_RING(); - } -} -#endif - static void I830EnablePageFlip(ScreenPtr pScreen) { @@ -1342,32 +1361,7 @@ I830EnablePageFlip(ScreenPtr pScreen) drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen); pSAREAPriv->pf_enabled = pI830->allowPageFlip; - pSAREAPriv->pf_active = 0; - - if (pI830->allowPageFlip) { - int br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16); - - BEGIN_LP_RING(8); - if (pScrn->bitsPerPixel == 32) { - OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - br13 |= 3 << 24; - } else { - OUT_RING(XY_SRC_COPY_BLT_CMD); - br13 |= 1 << 24; - } - - OUT_RING(br13); - OUT_RING(0); - OUT_RING((pScrn->virtualY << 16) | pScrn->virtualX); - OUT_RING(pI830->BackBuffer.Start); - OUT_RING(0); - OUT_RING(br13 & 0xffff); - OUT_RING(pI830->FrontBuffer.Start); - ADVANCE_LP_RING(); - - pSAREAPriv->pf_active = 1; - } + pSAREAPriv->pf_active = pI830->allowPageFlip; } static void @@ -1419,14 +1413,13 @@ I830DRITransitionTo2d(ScreenPtr pScreen) if (sPriv->pf_current_page == 1) drmCommandNone(pI830->drmSubFD, DRM_I830_FLIP); - /* Shut down shadowing if we've made it back to the front page: - */ - if (sPriv->pf_current_page == 0) { - I830DisablePageFlip(pScreen); - } + if (sPriv->pf_current_page == 1) + xf86DrvMsg(pScreen->myNum, X_WARNING, + "[dri] %s: kernel failed to unflip buffers.\n", __func__); + + I830DisablePageFlip(pScreen); pI830->have3DWindows = 0; - } diff --git a/src/i830_driver.c b/src/i830_driver.c index cb3dd878..d1f83e5a 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -3168,6 +3168,15 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen) pI830->closing = TRUE; #ifdef XF86DRI if (pI830->directRenderingOpen) { +#ifdef DAMAGE + if (pI830->pDamage) { + PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen); + + DamageUnregister(&pPix->drawable, pI830->pDamage); + DamageDestroy(pI830->pDamage); + pI830->pDamage = NULL; + } +#endif #ifdef XF86DRI_MM if (pI830->mmModeFlags & I830_KERNEL_MM) { #ifndef XSERVER_LIBDRM_MM diff --git a/src/i830_memory.c b/src/i830_memory.c index 6ceb05b5..29d9d31d 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -515,7 +515,7 @@ I830AllocateFramebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, int verbosity = dryrun ? 4 : 1; const char *s = dryrun ? "[dryrun] " : ""; Bool tileable; - int align, alignflags; + int align; long size, alloced, fb_height; /* Clear everything first. */ @@ -586,16 +586,6 @@ I830AllocateFramebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip && IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); - if (tileable) { - if (IS_I9XX(pI830)) - align = MB(1); - else - align = KB(512); - alignflags = ALIGN_BOTH_ENDS; - } else { - align = KB(64); - alignflags = 0; - } size = lineSize * (fb_height + cacheLines); size = ROUND_TO_PAGE(size); @@ -603,10 +593,26 @@ I830AllocateFramebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, "%sInitial %sframebuffer allocation size: %ld kByte\n", s, secondary ? "secondary " : "", size / 1024); - alloced = I830AllocVidMem(pScrn, FrontBuffer, - StolenPool, size, align, - flags | alignflags | - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); + + if (tileable) { + align = GetBestTileAlignment(size); + + for (align = GetBestTileAlignment(size); + align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) { + alloced = I830AllocVidMem(pScrn, FrontBuffer, StolenPool, size, align, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP | + ALIGN_BOTH_ENDS); + if (alloced >= size) + break; + } + } else { + align = KB(64); + + alloced = I830AllocVidMem(pScrn, FrontBuffer, + StolenPool, size, align, + flags | FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); + } + if (alloced < size) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " @@ -718,7 +724,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) int verbosity = dryrun ? 4 : 1; const char *s = dryrun ? "[dryrun] " : ""; Bool tileable; - int align, alignflags, i; + int align, i; DPRINTF(PFX, "I830Allocate2DMemory: inital is %s\n", BOOLTOSTRING(flags & ALLOC_INITIAL)); @@ -877,20 +883,26 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) pI830->FbMemBox.y2 = maxFb / lineSize; tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip && IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); + if (tileable) { - if (IS_I9XX(pI830)) - align = MB(1); - else - align = KB(512); - alignflags = ALIGN_BOTH_ENDS; + align = GetBestTileAlignment(size); + + for (align = GetBestTileAlignment(size); + align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) { + alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer), + &(pI830->StolenPool), size, align, + flags | FROM_ANYWHERE | + ALLOCATE_AT_TOP | ALIGN_BOTH_ENDS); + if (alloced >= size) + break; + } } else { - align = KB(64); - alignflags = 0; + alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer), + &(pI830->StolenPool), maxFb, align, + flags | + FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); } - alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer), - &(pI830->StolenPool), maxFb, align, - flags | alignflags | - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); + if (alloced < maxFb) { if (!dryrun) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, From 55c7b017ed718107b9b11467030addf225728b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 14 Feb 2007 16:45:22 +0100 Subject: [PATCH 15/82] Use new DRI ClipNotify hook to track page flipping per CRTC when available. --- src/i830_dri.c | 89 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 19 deletions(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index 05171d37..b368c992 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -107,6 +107,7 @@ static void I830DRITransitionTo2d(ScreenPtr pScreen); static void I830DRITransitionTo3d(ScreenPtr pScreen); static void I830DRITransitionMultiToSingle3d(ScreenPtr pScreen); static void I830DRITransitionSingleToMulti3d(ScreenPtr pScreen); +static void I830DRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num); #if 0 static void I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf); @@ -551,10 +552,31 @@ I830DRIScreenInit(ScreenPtr pScreen) pDRIInfo->InitBuffers = I830DRIInitBuffers; pDRIInfo->MoveBuffers = I830DRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; - pDRIInfo->TransitionTo2d = I830DRITransitionTo2d; - pDRIInfo->TransitionTo3d = I830DRITransitionTo3d; - pDRIInfo->TransitionSingleToMulti3D = I830DRITransitionSingleToMulti3d; - pDRIInfo->TransitionMultiToSingle3D = I830DRITransitionMultiToSingle3d; + +#if DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1 + { + int major, minor, patch; + + DRIQueryVersion(&major, &minor, &patch); + + if (minor >= 1) +#endif +#if DRIINFO_MAJOR_VERSION > 5 || \ + (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1) + pDRIInfo->ClipNotify = I830DRIClipNotify; +#endif + } + +#if DRIINFO_MAJOR_VERSION > 5 || \ + (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1) + if (!pDRIInfo->ClipNotify) +#endif + { + pDRIInfo->TransitionTo2d = I830DRITransitionTo2d; + pDRIInfo->TransitionTo3d = I830DRITransitionTo3d; + pDRIInfo->TransitionSingleToMulti3D = I830DRITransitionSingleToMulti3d; + pDRIInfo->TransitionMultiToSingle3D = I830DRITransitionMultiToSingle3d; + } /* do driver-independent DRI screen initialization here */ if (!DRIScreenInit(pScreen, pDRIInfo, &pI830->drmSubFD)) { @@ -1354,25 +1376,16 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, */ static void -I830EnablePageFlip(ScreenPtr pScreen) +I830DRISetPfMask(ScreenPtr pScreen, int pfMask) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen); pSAREAPriv->pf_enabled = pI830->allowPageFlip; - pSAREAPriv->pf_active = pI830->allowPageFlip; + pSAREAPriv->pf_active = pfMask; } -static void -I830DisablePageFlip(ScreenPtr pScreen) -{ - drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen); - - pSAREAPriv->pf_active = 0; -} - - static void I830DRITransitionSingleToMulti3d(ScreenPtr pScreen) { @@ -1380,15 +1393,18 @@ I830DRITransitionSingleToMulti3d(ScreenPtr pScreen) * -- Field in sarea, plus bumping the window counters. * -- DRM needs to cope with Front-to-Back swapbuffers. */ - I830DisablePageFlip(pScreen); + I830DRISetPfMask(pScreen, 0); } static void I830DRITransitionMultiToSingle3d(ScreenPtr pScreen) { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + /* Let the remaining 3d app start page flipping again. */ - I830EnablePageFlip(pScreen); + I830DRISetPfMask(pScreen, pI830->allowPageFlip ? 0x3 : 0); } static void @@ -1397,7 +1413,7 @@ I830DRITransitionTo3d(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); - I830EnablePageFlip(pScreen); + I830DRISetPfMask(pScreen, pI830->allowPageFlip ? 0x3 : 0); pI830->have3DWindows = 1; } @@ -1417,11 +1433,46 @@ I830DRITransitionTo2d(ScreenPtr pScreen) xf86DrvMsg(pScreen->myNum, X_WARNING, "[dri] %s: kernel failed to unflip buffers.\n", __func__); - I830DisablePageFlip(pScreen); + I830DRISetPfMask(pScreen, 0); pI830->have3DWindows = 0; } +static void +I830DRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num) +{ + unsigned pfMask = 0; + + if (num > 0) { + drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); + BoxRec crtcBox[2]; + unsigned numvisible[2] = { 0, 0 }; + int i, j; + + crtcBox[0].x1 = sPriv->pipeA_x; + crtcBox[0].y1 = sPriv->pipeA_y; + crtcBox[0].x2 = crtcBox[0].x1 + sPriv->pipeA_w; + crtcBox[0].y2 = crtcBox[0].y1 + sPriv->pipeA_h; + crtcBox[1].x1 = sPriv->pipeB_x; + crtcBox[1].y1 = sPriv->pipeB_y; + crtcBox[1].x2 = crtcBox[0].x1 + sPriv->pipeB_w; + crtcBox[1].y2 = crtcBox[0].y1 + sPriv->pipeB_h; + + for (i = 0; i < 2; i++) { + for (j = 0; j < num; j++) { + if (ppWin[j] && RECT_IN_REGION(pScreen, &ppWin[j]->clipList, + &crtcBox[i]) != rgnOUT) + numvisible[i]++; + } + + if (numvisible[i] == 1) + pfMask |= 1 << i; + } + } + + I830DRISetPfMask(pScreen, pfMask); +} + /** * Update the SAREA fields with the most recent values. From fac8f2eb49de22abd853ca75f3c985d4d94e3633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 20 Feb 2007 18:38:40 +0100 Subject: [PATCH 16/82] Document Option "PageFlip". --- man/intel.man | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/man/intel.man b/man/intel.man index b932632c..3f4cff89 100644 --- a/man/intel.man +++ b/man/intel.man @@ -159,6 +159,13 @@ atctivate the legacy texture pool (see gain some performance by increasing this value. Default: 32768. .TP +.BI "Option \*qPageFlip\*q \*q" boolean \*q +Enable support for page flipping. This should improve 3D performance at the +potential cost of worse performance or artifacts with mixed 2D/3D. Also note +that this gives no benefit without corresponding support in the Mesa 3D driver. +Default for i810: The option is not used. +Default for i9xx: Disabled. +.TP .BI "Option \*qAccelMethod\*q \*q" string \*q Choose acceleration architecture, either "XAA" or "EXA". XAA is the old (but stable) XFree86 based acceleration architecture. EXA is a newer and From 2212baa8454abb4c7948c3f2e20e337f831d1b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 20 Feb 2007 18:39:13 +0100 Subject: [PATCH 17/82] Don't mark page flipping as active when it really isn't. --- src/i830_dri.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index b368c992..d6551830 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -1382,8 +1382,11 @@ I830DRISetPfMask(ScreenPtr pScreen, int pfMask) I830Ptr pI830 = I830PTR(pScrn); drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen); - pSAREAPriv->pf_enabled = pI830->allowPageFlip; - pSAREAPriv->pf_active = pfMask; + if (pI830->allowPageFlip && pfMask) { + pSAREAPriv->pf_enabled = pI830->allowPageFlip; + pSAREAPriv->pf_active = pfMask; + } else + pSAREAPriv->pf_enabled = pSAREAPriv->pf_active = 0; } static void From 0bee64f4bc7581de7ab28ca438581d215e85c610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 20 Feb 2007 19:09:37 +0100 Subject: [PATCH 18/82] Add support for triple buffering using a third static buffer. Need to bump the DRI DDX version minor for the added SAREA fields. --- man/intel.man | 17 ++++++++-- src/i830.h | 5 +++ src/i830_accel.c | 3 ++ src/i830_common.h | 6 ++++ src/i830_dri.c | 63 ++++++++++++++++++++++++++++++----- src/i830_dri.h | 4 +-- src/i830_driver.c | 14 +++++++- src/i830_memory.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++ src/i830_xaa.c | 2 ++ 9 files changed, 184 insertions(+), 14 deletions(-) diff --git a/man/intel.man b/man/intel.man index 3f4cff89..503b52a7 100644 --- a/man/intel.man +++ b/man/intel.man @@ -162,9 +162,22 @@ Default: 32768. .BI "Option \*qPageFlip\*q \*q" boolean \*q Enable support for page flipping. This should improve 3D performance at the potential cost of worse performance or artifacts with mixed 2D/3D. Also note -that this gives no benefit without corresponding support in the Mesa 3D driver. +that this gives no benefit without corresponding support in the Mesa 3D driver +and may not give the full benefit without triple buffering (see +.B "Option \*qTripleBuffer\*q" +). Default for i810: The option is not used. -Default for i9xx: Disabled. +Default for i830 and above: Disabled. +.TP +.BI "Option \*qTripleBuffer\*q \*q" boolean \*q +Enable support for triple flipping. This should improve 3D performance at the +potential cost of worse performance with mixed 2D/3D. Also note that this gives +no benefit without corresponding support in the Mesa 3D driver and may not give +any benefit without page flipping either (see +.B "Option \*qPageFlip\*q" +). +Default for i810: The option is not used. +Default for i830 and above: Disabled. .TP .BI "Option \*qAccelMethod\*q \*q" string \*q Choose acceleration architecture, either "XAA" or "EXA". XAA is the old diff --git a/src/i830.h b/src/i830.h index 78381fbf..bbbb4a8e 100644 --- a/src/i830.h +++ b/src/i830.h @@ -294,6 +294,7 @@ typedef struct _I830Rec { I830MemRange ContextMem; #ifdef XF86DRI I830MemRange BackBuffer; + I830MemRange ThirdBuffer; I830MemRange DepthBuffer; I830MemRange TexMem; int TexGranularity; @@ -304,6 +305,7 @@ typedef struct _I830Rec { unsigned int front_tiled; unsigned int back_tiled; + unsigned int third_tiled; unsigned int depth_tiled; #ifdef DAMAGE @@ -313,6 +315,7 @@ typedef struct _I830Rec { Bool NeedRingBufferLow; Bool allowPageFlip; + Bool TripleBuffer; Bool disableTiling; int backPitch; @@ -511,6 +514,7 @@ typedef struct _I830Rec { #define I830_SELECT_FRONT 0 #define I830_SELECT_BACK 1 #define I830_SELECT_DEPTH 2 +#define I830_SELECT_THIRD 3 /* I830 specific functions */ extern int I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis); @@ -539,6 +543,7 @@ extern void i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on); #ifdef XF86DRI extern Bool I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags); extern Bool I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags); +extern Bool I830AllocateThirdBuffer(ScrnInfoPtr pScrn, const int flags); extern Bool I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags); extern Bool I830AllocateTextureMemory(ScrnInfoPtr pScrn, const int flags); extern void I830SetupMemoryTiling(ScrnInfoPtr pScrn); diff --git a/src/i830_accel.c b/src/i830_accel.c index db3168a8..c76c7483 100644 --- a/src/i830_accel.c +++ b/src/i830_accel.c @@ -228,6 +228,9 @@ I830SelectBuffer(ScrnInfoPtr pScrn, int buffer) case I830_SELECT_BACK: pI830->bufferOffset = pI830->BackBuffer.Start; break; + case I830_SELECT_THIRD: + pI830->bufferOffset = pI830->ThirdBuffer.Start; + break; case I830_SELECT_DEPTH: pI830->bufferOffset = pI830->DepthBuffer.Start; break; diff --git a/src/i830_common.h b/src/i830_common.h index 79455b61..f853ccd8 100644 --- a/src/i830_common.h +++ b/src/i830_common.h @@ -130,6 +130,12 @@ typedef struct { int pipeB_y; int pipeB_w; int pipeB_h; + + /* Triple buffering */ + drm_handle_t third_handle; + int third_offset; + int third_size; + unsigned int third_tiled; } drmI830Sarea; /* Flags for perf_boxes diff --git a/src/i830_dri.c b/src/i830_dri.c index d6551830..65736cdc 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -751,6 +751,20 @@ I830DRIMapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Back Buffer = 0x%08x\n", (int)sarea->back_handle); + if (pI830->TripleBuffer) { + if (drmAddMap(pI830->drmSubFD, + (drm_handle_t)(sarea->third_offset + pI830->LinearAddr), + sarea->third_size, DRM_AGP, 0, + (drmAddress) &sarea->third_handle) < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] drmAddMap(third_handle) failed. Disabling DRI\n"); + DRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Third Buffer = 0x%08x\n", + (int)sarea->third_handle); + } + if (drmAddMap(pI830->drmSubFD, (drm_handle_t)sarea->depth_offset + pI830->LinearAddr, sarea->depth_size, DRM_AGP, 0, @@ -794,6 +808,10 @@ I830DRIUnmapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea) drmRmMap(pI830->drmSubFD, sarea->back_handle); sarea->back_handle = 0; } + if (sarea->third_handle) { + drmRmMap(pI830->drmSubFD, sarea->third_handle); + sarea->third_handle = 0; + } if (sarea->depth_handle) { drmRmMap(pI830->drmSubFD, sarea->depth_handle); sarea->depth_handle = 0; @@ -870,6 +888,7 @@ I830DRIDoMappings(ScreenPtr pScreen) /* init to zero to be safe */ sarea->front_handle = 0; sarea->back_handle = 0; + sarea->third_handle = 0; sarea->depth_handle = 0; sarea->tex_handle = 0; @@ -1041,17 +1060,10 @@ I830DRIFinishScreenInit(ScreenPtr pScreen) * Otherwise will have to sync again??? */ static void -I830DRIRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox) +I830DRIDoRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox, CARD32 dst) { I830Ptr pI830 = I830PTR(pScrn); int i, cmd, br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16); - drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); - - /* Don't want to do this when no 3d is active and pages are - * right-way-round : - */ - if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0) - return; if (pScrn->bitsPerPixel == 32) { cmd = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | @@ -1068,12 +1080,31 @@ I830DRIRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox) OUT_RING(br13); OUT_RING((pbox->y1 << 16) | pbox->x1); OUT_RING((pbox->y2 << 16) | pbox->x2); - OUT_RING(pI830->BackBuffer.Start); + OUT_RING(dst); OUT_RING((pbox->y1 << 16) | pbox->x1); OUT_RING(br13 & 0xffff); OUT_RING(pI830->FrontBuffer.Start); ADVANCE_LP_RING(); } +} + +static void +I830DRIRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + I830Ptr pI830 = I830PTR(pScrn); + drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); + + /* Don't want to do this when no 3d is active and pages are + * right-way-round : + */ + if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0) + return; + + I830DRIDoRefreshArea(pScrn, num, pbox, pI830->BackBuffer.Start); + + if (pI830->TripleBuffer) { + I830DRIDoRefreshArea(pScrn, num, pbox, pI830->ThirdBuffer.Start); + } DamageEmpty(pI830->pDamage); } @@ -1160,6 +1191,13 @@ I830DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) I830SelectBuffer(pScrn, I830_SELECT_BACK); I830SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); + + if (I830PTR(pScrn)->TripleBuffer) { + I830SelectBuffer(pScrn, I830_SELECT_THIRD); + I830SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, + pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); + } + pbox++; } @@ -1333,6 +1371,10 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, I830SelectBuffer(pScrn, I830_SELECT_BACK); I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); + if (pI830->TripleBuffer) { + I830SelectBuffer(pScrn, I830_SELECT_THIRD); + I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); + } if (!IS_I965G(pI830)) { I830SelectBuffer(pScrn, I830_SELECT_DEPTH); I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); @@ -1492,6 +1534,7 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) sarea->front_tiled = pI830->front_tiled; sarea->back_tiled = pI830->back_tiled; + sarea->third_tiled = pI830->third_tiled; sarea->depth_tiled = pI830->depth_tiled; sarea->rotated_tiled = FALSE; @@ -1509,6 +1552,8 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) sarea->height = pScreen->height; sarea->back_offset = pI830->BackBuffer.Start; sarea->back_size = pI830->BackBuffer.Size; + sarea->third_offset = pI830->ThirdBuffer.Start; + sarea->third_size = pI830->ThirdBuffer.Size; sarea->depth_offset = pI830->DepthBuffer.Start; sarea->depth_size = pI830->DepthBuffer.Size; sarea->tex_offset = pI830->TexMem.Start; diff --git a/src/i830_dri.h b/src/i830_dri.h index a1404978..a2cf78ec 100644 --- a/src/i830_dri.h +++ b/src/i830_dri.h @@ -9,8 +9,8 @@ #define I830_MAX_DRAWABLES 256 #define I830_MAJOR_VERSION 1 -#define I830_MINOR_VERSION 7 -#define I830_PATCHLEVEL 2 +#define I830_MINOR_VERSION 8 +#define I830_PATCHLEVEL 0 #define I830_REG_SIZE 0x80000 diff --git a/src/i830_driver.c b/src/i830_driver.c index d1f83e5a..3c8ec1a1 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -273,7 +273,8 @@ typedef enum { OPTION_CHECKDEVICES, OPTION_LINEARALLOC, OPTION_INTELTEXPOOL, - OPTION_INTELMMSIZE + OPTION_INTELMMSIZE, + OPTION_TRIPLEBUFFER, } I830Opts; static OptionInfoRec I830Options[] = { @@ -292,6 +293,7 @@ static OptionInfoRec I830Options[] = { {OPTION_LINEARALLOC, "LinearAlloc", OPTV_INTEGER, {0}, FALSE}, {OPTION_INTELTEXPOOL,"Legacy3D", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_INTELMMSIZE, "AperTexSize", OPTV_INTEGER, {0}, FALSE}, + {OPTION_TRIPLEBUFFER, "TripleBuffer", OPTV_BOOLEAN, {0}, FALSE}, {-1, NULL, OPTV_NONE, {0}, FALSE} }; /* *INDENT-ON* */ @@ -1487,6 +1489,16 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } #endif +#ifdef XF86DRI + pI830->TripleBuffer = FALSE; + from = (!pI830->directRenderingDisabled && + xf86GetOptValBool(pI830->Options, OPTION_TRIPLEBUFFER, + &pI830->TripleBuffer)) ? X_CONFIG : X_DEFAULT; + + xf86DrvMsg(pScrn->scrnIndex, from, "Triple buffering %sabled\n", + pI830->TripleBuffer ? "en" : "dis"); +#endif + /* * If the driver can do gamma correction, it should call xf86SetGamma() here. */ diff --git a/src/i830_memory.c b/src/i830_memory.c index 29d9d31d..2d1cca9c 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -1117,6 +1117,69 @@ I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags) return TRUE; } +Bool +I830AllocateThirdBuffer(ScrnInfoPtr pScrn, const int flags) +{ + I830Ptr pI830 = I830PTR(pScrn); + unsigned long size, alloced, align = 0; + Bool tileable; + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + int lines; + int height = (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) ? pScrn->virtualY : pScrn->virtualX; + + /* Third Buffer */ + memset(&(pI830->ThirdBuffer), 0, sizeof(pI830->ThirdBuffer)); + pI830->ThirdBuffer.Key = -1; + tileable = !(flags & ALLOC_NO_TILING) && + IsTileable(pScrn, pScrn->displayWidth * pI830->cpp); + if (tileable) { + /* Make the height a multiple of the tile height (16) */ + lines = (height + 15) / 16 * 16; + } else { + lines = height; + } + + size = ROUND_TO_PAGE(pScrn->displayWidth * lines * pI830->cpp); + /* + * Try to allocate on the best tile-friendly boundaries. + */ + alloced = 0; + if (tileable) { + align = GetBestTileAlignment(size); + for (align = GetBestTileAlignment(size); align >= (IS_I9XX(pI830) ? MB(1) : KB(512)); align >>= 1) { + alloced = I830AllocVidMem(pScrn, &(pI830->ThirdBuffer), + &(pI830->StolenPool), size, align, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP | + ALIGN_BOTH_ENDS); + if (alloced >= size) + break; + } + } + if (alloced < size) { + /* Give up on trying to tile */ + tileable = FALSE; + size = ROUND_TO_PAGE(pScrn->displayWidth * height * pI830->cpp); + align = GTT_PAGE_SIZE; + alloced = I830AllocVidMem(pScrn, &(pI830->ThirdBuffer), + &(pI830->StolenPool), size, align, + flags | FROM_ANYWHERE | ALLOCATE_AT_TOP); + } + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate third buffer space.\n"); + } + return FALSE; + } + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocated %ld kB for the third buffer at 0x%lx.\n", s, + alloced / 1024, pI830->ThirdBuffer.Start); + + return TRUE; +} + Bool I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags) { @@ -1271,6 +1334,9 @@ I830Allocate3DMemory(ScrnInfoPtr pScrn, const int flags) if (!I830AllocateBackBuffer(pScrn, flags)) return FALSE; + if (pI830->TripleBuffer && !I830AllocateThirdBuffer(pScrn, flags)) + return FALSE; + if (!I830AllocateDepthBuffer(pScrn, flags)) return FALSE; @@ -1439,6 +1505,7 @@ I830FixupOffsets(ScrnInfoPtr pScrn) if (pI830->directRenderingEnabled) { I830FixOffset(pScrn, &(pI830->ContextMem)); I830FixOffset(pScrn, &(pI830->BackBuffer)); + I830FixOffset(pScrn, &(pI830->ThirdBuffer)); I830FixOffset(pScrn, &(pI830->DepthBuffer)); if (pI830->mmModeFlags & I830_KERNEL_TEX) { I830FixOffset(pScrn, &(pI830->TexMem)); @@ -1701,6 +1768,7 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn) pI830->front_tiled = FENCE_LINEAR; pI830->back_tiled = FENCE_LINEAR; + pI830->third_tiled = FENCE_LINEAR; pI830->depth_tiled = FENCE_LINEAR; if (pI830->allowPageFlip) { @@ -1739,6 +1807,18 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn) } } + if (pI830->ThirdBuffer.Alignment >= KB(512)) { + if (MakeTiles(pScrn, &(pI830->ThirdBuffer), FENCE_XMAJOR)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Activating tiled memory for the third buffer.\n"); + pI830->third_tiled = FENCE_XMAJOR; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MakeTiles failed for the third buffer.\n"); + pI830->allowPageFlip = FALSE; + } + } + if (pI830->DepthBuffer.Alignment >= KB(512)) { if (MakeTiles(pScrn, &(pI830->DepthBuffer), FENCE_YMAJOR)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -1825,6 +1905,8 @@ I830BindAGPMemory(ScrnInfoPtr pScrn) return FALSE; if (!BindMemRange(pScrn, &(pI830->BackBuffer))) return FALSE; + if (pI830->TripleBuffer && !BindMemRange(pScrn, &(pI830->ThirdBuffer))) + return FALSE; if (!BindMemRange(pScrn, &(pI830->DepthBuffer))) return FALSE; if ((pI830->mmModeFlags & I830_KERNEL_TEX) && @@ -1919,6 +2001,8 @@ I830UnbindAGPMemory(ScrnInfoPtr pScrn) return FALSE; if (!UnbindMemRange(pScrn, &(pI830->BackBuffer))) return FALSE; + if (pI830->TripleBuffer && !UnbindMemRange(pScrn, &(pI830->ThirdBuffer))) + return FALSE; if (!UnbindMemRange(pScrn, &(pI830->DepthBuffer))) return FALSE; if ((pI830->mmModeFlags & I830_KERNEL_TEX) && diff --git a/src/i830_xaa.c b/src/i830_xaa.c index 5ef5d3c4..9b11973f 100644 --- a/src/i830_xaa.c +++ b/src/i830_xaa.c @@ -281,6 +281,8 @@ CheckTiling(ScrnInfoPtr pScrn) tiled = 1; if (pI830->bufferOffset == pI830->BackBuffer.Start && pI830->back_tiled == FENCE_XMAJOR) tiled = 1; + if (pI830->bufferOffset == pI830->ThirdBuffer.Start && pI830->third_tiled == FENCE_XMAJOR) + tiled = 1; /* not really supported as it's always YMajor tiled */ if (pI830->bufferOffset == pI830->DepthBuffer.Start && pI830->depth_tiled == FENCE_XMAJOR) tiled = 1; From f346549183a407a4bff6521ec2450dacb97442e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 21 Feb 2007 09:19:54 +0100 Subject: [PATCH 19/82] intel.man: Fix typo. --- man/intel.man | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/intel.man b/man/intel.man index 503b52a7..05a91f7e 100644 --- a/man/intel.man +++ b/man/intel.man @@ -170,7 +170,7 @@ Default for i810: The option is not used. Default for i830 and above: Disabled. .TP .BI "Option \*qTripleBuffer\*q \*q" boolean \*q -Enable support for triple flipping. This should improve 3D performance at the +Enable support for triple buffering. This should improve 3D performance at the potential cost of worse performance with mixed 2D/3D. Also note that this gives no benefit without corresponding support in the Mesa 3D driver and may not give any benefit without page flipping either (see From 8cce74f195e5ef6ce5599ecd52f35bcfcb0d7913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 22 Feb 2007 18:27:59 +0100 Subject: [PATCH 20/82] Do not sync DRI windows between pages when possible. --- src/i830.h | 1 + src/i830_dri.c | 38 +++++++++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/i830.h b/src/i830.h index bbbb4a8e..e26556f5 100644 --- a/src/i830.h +++ b/src/i830.h @@ -310,6 +310,7 @@ typedef struct _I830Rec { #ifdef DAMAGE DamagePtr pDamage; + RegionRec driRegion; #endif #endif diff --git a/src/i830_dri.c b/src/i830_dri.c index 65736cdc..6c91cdcc 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -980,6 +980,10 @@ I830DRICloseScreen(ScreenPtr pScreen) DPRINTF(PFX, "I830DRICloseScreen\n"); +#ifdef DAMAGE + REGION_UNINIT(pScreen, &pI830->driRegion); +#endif + if (pI830DRI->irq) { drmCtlUninstHandler(pI830->drmSubFD); pI830DRI->irq = 0; @@ -1164,10 +1168,16 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, RegionPtr pDamageReg = DamageRegion(pI830->pDamage); if (pDamageReg) { - int nrects = REGION_NUM_RECTS(pDamageReg); + RegionRec region; + int nrects; - if (nrects) - I830DRIRefreshArea(pScrn, nrects, REGION_RECTS(pDamageReg)); + REGION_NULL(pScreen, ®ion); + REGION_SUBTRACT(pScreen, ®ion, pDamageReg, &pI830->driRegion); + + if ((nrects = REGION_NUM_RECTS(®ion))) + I830DRIRefreshArea(pScrn, nrects, REGION_RECTS(®ion)); + + REGION_UNINIT(pScreen, ®ion); } } #endif @@ -1486,8 +1496,13 @@ I830DRITransitionTo2d(ScreenPtr pScreen) static void I830DRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num) { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); unsigned pfMask = 0; + REGION_UNINIT(pScreen, &pI830->driRegion); + REGION_NULL(pScreen, &pI830->driRegion); + if (num > 0) { drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); BoxRec crtcBox[2]; @@ -1505,15 +1520,24 @@ I830DRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num) for (i = 0; i < 2; i++) { for (j = 0; j < num; j++) { - if (ppWin[j] && RECT_IN_REGION(pScreen, &ppWin[j]->clipList, - &crtcBox[i]) != rgnOUT) - numvisible[i]++; + WindowPtr pWin = ppWin[j]; + + if (pWin) { + if (RECT_IN_REGION(pScreen, &pWin->clipList, &crtcBox[i]) != + rgnOUT) + numvisible[i]++; + + if (i == 0) + REGION_UNION(pScreen, &pI830->driRegion, &pWin->clipList, + &pI830->driRegion); + } } if (numvisible[i] == 1) pfMask |= 1 << i; } - } + } else + REGION_NULL(pScreen, &pI830->driRegion); I830DRISetPfMask(pScreen, pfMask); } From f5ab9e0ad3a65c972861dd53be6e33e1aac13191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 22 Feb 2007 18:57:23 +0100 Subject: [PATCH 21/82] I830DRISwapContext: Some cleanups. Also call I830EmitFlush() when entering/leaving the server context. Doesn't seem to help for artifacts with page flipping and mixed 2D/3D unfortunately. --- src/i830_dri.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index 6c91cdcc..afc7de06 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -1135,6 +1135,8 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, pI830->LockHeld = 1; I830RefreshRing(pScrn); + I830EmitFlush(pScrn); + #ifdef DAMAGE if (!pI830->pDamage && pI830->allowPageFlip) { PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen); @@ -1159,10 +1161,12 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, } else if (syncType == DRI_2D_SYNC && oldContextType == DRI_NO_CONTEXT && newContextType == DRI_2D_CONTEXT) { - pI830->LockHeld = 0; if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("i830DRISwapContext (out)\n"); + if (!pScrn->vtSema) + return; + #ifdef DAMAGE if (pI830->pDamage) { RegionPtr pDamageReg = DamageRegion(pI830->pDamage); @@ -1181,6 +1185,10 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, } } #endif + + I830EmitFlush(pScrn); + + pI830->LockHeld = 0; } else if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("i830DRISwapContext (other)\n"); } From b5316fb2623e9630cbd58020e0a7c95bf354c587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 28 Feb 2007 17:50:56 +0100 Subject: [PATCH 22/82] I830DRIClipNotify: Fix initialization of crtcBox[1].[xy]2. --- src/i830_dri.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index afc7de06..e5460668 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -1523,8 +1523,8 @@ I830DRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num) crtcBox[0].y2 = crtcBox[0].y1 + sPriv->pipeA_h; crtcBox[1].x1 = sPriv->pipeB_x; crtcBox[1].y1 = sPriv->pipeB_y; - crtcBox[1].x2 = crtcBox[0].x1 + sPriv->pipeB_w; - crtcBox[1].y2 = crtcBox[0].y1 + sPriv->pipeB_h; + crtcBox[1].x2 = crtcBox[1].x1 + sPriv->pipeB_w; + crtcBox[1].y2 = crtcBox[1].y1 + sPriv->pipeB_h; for (i = 0; i < 2; i++) { for (j = 0; j < num; j++) { From 36cad3fcb65e3dcd88e58e301cd60adb121cb96b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 28 Feb 2007 17:52:42 +0100 Subject: [PATCH 23/82] Update vblank pipe setup when setting a mode. --- src/i830_display.c | 6 +++--- src/i830_driver.c | 4 ---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/i830_display.c b/src/i830_display.c index 258897ee..04159e73 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -864,6 +864,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, OUTREG(dspcntr_reg, dspcntr); /* Flush the plane changes */ i830PipeSetBase(crtc, x, y); +#ifdef XF86DRI + I830DRISetVBlankInterrupt (pScrn, TRUE); +#endif i830WaitForVblank(pScrn); } @@ -1041,9 +1044,6 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, Rotation rotation) i830DescribeOutputConfiguration(pScrn); -#ifdef XF86DRI - I830DRISetVBlankInterrupt (pScrn, TRUE); -#endif done: i830DumpRegs (pScrn); i830_sdvo_dump(pScrn); diff --git a/src/i830_driver.c b/src/i830_driver.c index 3c8ec1a1..9bd70299 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -3085,10 +3085,6 @@ I830EnterVT(int scrnIndex, int flags) i830DumpRegs (pScrn); i830DescribeOutputConfiguration(pScrn); -#ifdef XF86DRI - I830DRISetVBlankInterrupt (pScrn, TRUE); -#endif - ResetState(pScrn, TRUE); SetHWOperatingState(pScrn); From af565872a49a1a464ee4154c27136660b184c4c1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 4 Mar 2007 21:20:33 -0800 Subject: [PATCH 24/82] Set version number to 2.0 RC1 (1.9.91). --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 772b40bd..c8b99c74 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ AC_PREREQ(2.57) AC_INIT([xf86-video-intel], - 1.9.90, + 1.9.91, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xf86-video-intel) From 50ba1fff886a7f51b178ac6d3a1ba79a3014b214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 5 Mar 2007 10:22:07 +0100 Subject: [PATCH 25/82] Be more verbose when page flipping can't be enabled for various reasons. --- src/i830_dri.c | 2 +- src/i830_driver.c | 21 +++++++++++++-------- src/i830_memory.c | 19 +++++++++++++++++-- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index e5460668..dba1a07a 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -1146,7 +1146,7 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, if (pI830->pDamage == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No screen damage record, page flipping disabled\n"); - pI830->allowPageFlip = 0; + pI830->allowPageFlip = FALSE; } else { DamageRegister(&pPix->drawable, pI830->pDamage); diff --git a/src/i830_driver.c b/src/i830_driver.c index 9bd70299..c9501497 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -853,7 +853,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) int i; char *s; pointer pVBEModule = NULL; - Bool enable; const char *chipname; int num_pipe; int max_width, max_height; @@ -1479,14 +1478,14 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->colorKey); #endif - pI830->allowPageFlip = FALSE; - enable = xf86ReturnOptValBool(pI830->Options, OPTION_PAGEFLIP, FALSE); #ifdef XF86DRI - if (!pI830->directRenderingDisabled) { - pI830->allowPageFlip = enable; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "page flipping %s\n", - enable ? "enabled" : "disabled"); - } + pI830->allowPageFlip = FALSE; + from = (!pI830->directRenderingDisabled && + xf86GetOptValBool(pI830->Options, OPTION_PAGEFLIP, + &pI830->allowPageFlip)) ? X_CONFIG : X_DEFAULT; + + xf86DrvMsg(pScrn->scrnIndex, from, "Will%s try to enable page flipping\n", + pI830->allowPageFlip ? "" : " not"); #endif #ifdef XF86DRI @@ -1676,6 +1675,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) -pI830->MemoryAperture.Size / 1024); } pScrn->displayWidth = savedDisplayWidth; + if (pI830->allowPageFlip) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Can't enable page flipping due to the above\n"); pI830->allowPageFlip = FALSE; } else if (pScrn->displayWidth != savedDisplayWidth) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -2682,6 +2684,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) I830SetupMemoryTiling(pScrn); pI830->directRenderingEnabled = I830DRIDoMappings(pScreen); } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page Flipping %sabled\n", + pI830->allowPageFlip ? "en" : "dis"); #endif DPRINTF(PFX, "assert( if(!I830MapMem(pScrn)) )\n"); diff --git a/src/i830_memory.c b/src/i830_memory.c index 2d1cca9c..a952b708 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -1762,6 +1762,9 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I830SetupMemoryTiling: Not tileable 0x%x\n", pScrn->displayWidth * pI830->cpp); + if (pI830->allowPageFlip) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Can't enable page flipping due to the above\n"); pI830->allowPageFlip = FALSE; return; } @@ -1778,14 +1781,20 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn) "Activating tiled memory for the front buffer\n"); pI830->front_tiled = FENCE_XMAJOR; } else { - pI830->allowPageFlip = FALSE; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MakeTiles failed for the front buffer\n"); + if (pI830->allowPageFlip) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Can't enable page flipping due to the above\n"); + pI830->allowPageFlip = FALSE; } } else { - pI830->allowPageFlip = FALSE; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Alignment bad for the front buffer\n"); + if (pI830->allowPageFlip) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Can't enable page flipping due to the above\n"); + pI830->allowPageFlip = FALSE; } } @@ -1803,6 +1812,9 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn) } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MakeTiles failed for the back buffer.\n"); + if (pI830->allowPageFlip) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Can't enable page flipping due to the above\n"); pI830->allowPageFlip = FALSE; } } @@ -1815,6 +1827,9 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn) } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "MakeTiles failed for the third buffer.\n"); + if (pI830->allowPageFlip) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Can't enable page flipping due to the above\n"); pI830->allowPageFlip = FALSE; } } From 7358642e64ab6d13bc1dc1a44703ee66d715ff61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 5 Mar 2007 11:53:09 +0100 Subject: [PATCH 26/82] Fix handling of new vs. old texture pools. Only one of them can be active. --- src/i830_driver.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index ac4e38c1..373c6360 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -272,8 +272,10 @@ typedef enum { OPTION_COLOR_KEY, OPTION_CHECKDEVICES, OPTION_LINEARALLOC, +#ifdef XF86DRI_MM OPTION_INTELTEXPOOL, OPTION_INTELMMSIZE +#endif } I830Opts; static OptionInfoRec I830Options[] = { @@ -290,8 +292,10 @@ static OptionInfoRec I830Options[] = { {OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE}, {OPTION_CHECKDEVICES, "CheckDevices",OPTV_BOOLEAN, {0}, FALSE}, {OPTION_LINEARALLOC, "LinearAlloc", OPTV_INTEGER, {0}, FALSE}, +#ifdef XF86DRI_MM {OPTION_INTELTEXPOOL,"Legacy3D", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_INTELMMSIZE, "AperTexSize", OPTV_INTEGER, {0}, FALSE}, +#endif {-1, NULL, OPTV_NONE, {0}, FALSE} }; /* *INDENT-ON* */ @@ -1230,30 +1234,38 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->mmModeFlags = 0; if (!pI830->directRenderingDisabled) { +#ifdef XF86DRI_MM Bool tmp = FALSE; - pI830->mmModeFlags |= I830_KERNEL_TEX; -#ifdef XF86DRI_MM if (!IS_I965G(pI830)) pI830->mmModeFlags |= I830_KERNEL_MM; + else #endif + pI830->mmModeFlags |= I830_KERNEL_TEX; from = X_PROBED; + +#ifdef XF86DRI_MM if (xf86GetOptValBool(pI830->Options, OPTION_INTELTEXPOOL, &tmp)) { from = X_CONFIG; if (tmp) { pI830->mmModeFlags |= I830_KERNEL_TEX; + pI830->mmModeFlags &= ~I830_KERNEL_MM; } else { pI830->mmModeFlags &= ~I830_KERNEL_TEX; + pI830->mmModeFlags |= I830_KERNEL_MM; } } +#endif + xf86DrvMsg(pScrn->scrnIndex, from, "Will %stry to allocate texture pool " "for old Mesa 3D driver.\n", (pI830->mmModeFlags & I830_KERNEL_TEX) ? "" : "not "); +#ifdef XF86DRI_MM pI830->mmSize = I830_MM_MAXSIZE; from = X_INFO; if (xf86GetOptValInteger(pI830->Options, OPTION_INTELMMSIZE, @@ -1266,6 +1278,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->mmSize); } } +#endif #endif @@ -2129,7 +2142,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) MessageType from; #ifdef XF86DRI Bool driDisabled; +#ifdef XF86DRI_MM unsigned long savedMMSize; +#endif #endif pScrn = xf86Screens[pScreen->myNum]; @@ -2257,7 +2272,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!I830CheckDRIAvailable(pScrn)) { pI830->directRenderingDisabled = TRUE; +#ifdef XF86DRI_MM pI830->mmSize = 0; +#endif } if (!pI830->directRenderingDisabled) { @@ -2307,18 +2324,24 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) */ pI830->disableTiling = FALSE; +#ifdef XF86DRI_MM savedMMSize = pI830->mmSize; - for (i = 0; i < 4; i++) { +#define MM_TURNS 4 +#else +#define MM_TURNS 2 +#endif + for (i = 0; i < MM_TURNS; i++) { if (!tiled && i < 2) continue; - if (i >= 2) { + if (i >= MM_TURNS/2) { /* For further allocations, disable tiling */ pI830->disableTiling = TRUE; pScrn->displayWidth = savedDisplayWidth; pI830->allowPageFlip = FALSE; } +#ifdef XF86DRI_MM if (i & 1) { /* For this allocation, switch to a smaller DRI memory manager * size. @@ -2333,6 +2356,11 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) "\t %s DRI memory manager reservation:\n", (i & 2) ? "untiled" : "tiled", (i & 1) ? "small" : "large"); +#else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Attempting memory allocation with %s buffers:\n", + (i & 1) ? "untiled" : "tiled"); +#endif if (i830_allocate_2d_memory(pScrn) && i830_allocate_3d_memory(pScrn)) @@ -2351,10 +2379,12 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) i830_reset_allocations(pScrn); } - if (i == 4) { + if (i == MM_TURNS) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Not enough video memory. Disabling DRI.\n"); +#ifdef XF86DRI_MM pI830->mmSize = 0; +#endif pI830->directRenderingDisabled = TRUE; } } else From d717d9d566fe3c0866b06840114e1c1990bd7be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 5 Mar 2007 12:57:21 +0100 Subject: [PATCH 27/82] Fix DRM memory manager initialization. It takes the offset and size in pages, not bytes. --- src/i830_driver.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 373c6360..7ab2cdc8 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2764,13 +2764,17 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) I830DRICloseScreen(pScreen); pI830->directRenderingEnabled = FALSE; } else { + unsigned long aperEnd = ROUND_DOWN_TO(pI830->memory_manager->offset + + pI830->memory_manager->size, + GTT_PAGE_SIZE) / GTT_PAGE_SIZE; + unsigned long aperStart = ROUND_TO(pI830->memory_manager->offset, + GTT_PAGE_SIZE) / GTT_PAGE_SIZE; + #ifndef XSERVER_LIBDRM_MM - if (I830DrmMMInit(pI830->drmSubFD, pI830->memory_manager->offset, - pI830->memory_manager->size, + if (I830DrmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart, DRM_BO_MEM_TT)) { #else - if (drmMMInit(pI830->drmSubFD, pI830->memory_manager->offset, - pI830->memory_manager->size, + if (drmMMInit(pI830->drmSubFD, aperStart, aperEnd - aperStart, DRM_BO_MEM_TT)) { #endif xf86DrvMsg(pScrn->scrnIndex, X_ERROR, From c2c62559e702e7de1fa2ef309fa647ab13564dc3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 3 Mar 2007 23:12:54 -0800 Subject: [PATCH 28/82] Move single mode setting code to X server. Code to drive the global configuration from a single mode setting operation (from RandR 1.1, XFree86-VidModeExtension or XFree86-DGA) has been included in the X server now, so remove it from this driver. --- src/i830_display.c | 141 --------------------------------------------- 1 file changed, 141 deletions(-) diff --git a/src/i830_display.c b/src/i830_display.c index d0b21a92..e9c997ab 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -392,107 +392,6 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y) } } -/** - * In the current world order, there are lists of modes per output, which may - * or may not include the mode that was asked to be set by XFree86's mode - * selection. Find the closest one, in the following preference order: - * - * - Equality - * - Closer in size to the requested mode, but no larger - * - Closer in refresh rate to the requested mode. - */ -DisplayModePtr -i830PipeFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode) -{ - ScrnInfoPtr pScrn = crtc->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - DisplayModePtr pBest = NULL, pScan = NULL; - int i; - - /* Assume that there's only one output connected to the given CRTC. */ - for (i = 0; i < xf86_config->num_output; i++) - { - xf86OutputPtr output = xf86_config->output[i]; - if (output->crtc == crtc && output->probed_modes != NULL) - { - pScan = output->probed_modes; - break; - } - } - - /* If the pipe doesn't have any detected modes, just let the system try to - * spam the desired mode in. - */ - if (pScan == NULL) { - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "No pipe mode list for pipe %d," - "continuing with desired mode\n", intel_crtc->pipe); - return pMode; - } - - for (; pScan != NULL; pScan = pScan->next) { - assert(pScan->VRefresh != 0.0); - - /* If there's an exact match, we're done. */ - if (xf86ModesEqual(pScan, pMode)) { - pBest = pMode; - break; - } - - /* Reject if it's larger than the desired mode. */ - if (pScan->HDisplay > pMode->HDisplay || - pScan->VDisplay > pMode->VDisplay) - { - continue; - } - - if (pBest == NULL) { - pBest = pScan; - continue; - } - - /* Find if it's closer to the right size than the current best - * option. - */ - if ((pScan->HDisplay > pBest->HDisplay && - pScan->VDisplay >= pBest->VDisplay) || - (pScan->HDisplay >= pBest->HDisplay && - pScan->VDisplay > pBest->VDisplay)) - { - pBest = pScan; - continue; - } - - /* Find if it's still closer to the right refresh than the current - * best resolution. - */ - if (pScan->HDisplay == pBest->HDisplay && - pScan->VDisplay == pBest->VDisplay && - (fabs(pScan->VRefresh - pMode->VRefresh) < - fabs(pBest->VRefresh - pMode->VRefresh))) { - pBest = pScan; - } - } - - if (pBest == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "No suitable mode found to program for the pipe.\n" - " continuing with desired mode %dx%d@%.1f\n", - pMode->HDisplay, pMode->VDisplay, pMode->VRefresh); - } else if (!xf86ModesEqual(pBest, pMode)) { - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - int pipe = intel_crtc->pipe; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Choosing pipe %d's mode %dx%d@%.1f instead of xf86 " - "mode %dx%d@%.1f\n", pipe, - pBest->HDisplay, pBest->VDisplay, pBest->VRefresh, - pMode->HDisplay, pMode->VDisplay, pMode->VRefresh); - pMode = pBest; - } - return pMode; -} - /** * Sets the power management mode of the pipe and plane. * @@ -1140,46 +1039,6 @@ i830_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) } -/** - * This function configures the screens in clone mode on - * all active outputs using a mode similar to the specified mode. - */ -Bool -i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, Rotation rotation) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - Bool ok = TRUE; - xf86CrtcPtr crtc = config->output[config->compat_output]->crtc; - - DPRINTF(PFX, "i830SetMode\n"); - - if (crtc && crtc->enabled) - { - ok = xf86CrtcSetMode(crtc, - i830PipeFindClosestMode(crtc, pMode), - rotation, 0, 0); - if (!ok) - goto done; - crtc->desiredMode = *pMode; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Mode bandwidth is %d Mpixel/s\n", - (int)(pMode->HDisplay * pMode->VDisplay * - pMode->VRefresh / 1000000)); - - xf86DisableUnusedFunctions(pScrn); - - i830DescribeOutputConfiguration(pScrn); - -#ifdef XF86DRI - I830DRISetVBlankInterrupt (pScrn, TRUE); -#endif -done: - i830DumpRegs (pScrn); - i830_sdvo_dump(pScrn); - return ok; -} - void i830DescribeOutputConfiguration(ScrnInfoPtr pScrn) { From 5c720147e2b86ca4046b7c3812c1ca6b0fb78c9d Mon Sep 17 00:00:00 2001 From: Wang Zhenyu Date: Tue, 6 Mar 2007 12:44:04 +0800 Subject: [PATCH 29/82] EXA: try to always alloc exa i965 state buffer in stolen mem I think this is a safe way to work around any possible chip error. --- src/i830_memory.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/i830_memory.c b/src/i830_memory.c index 5cddf173..7bcf48e0 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -936,6 +936,20 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) "Failed to allocate logical context space.\n"); return FALSE; } +#ifdef I830_USE_EXA + if (pI830->useEXA) { + if (IS_I965G(pI830) && pI830->exa_965_state == NULL) { + pI830->exa_965_state = + i830_allocate_memory(pScrn, "exa G965 state buffer", + EXA_LINEAR_EXTRA, GTT_PAGE_SIZE, 0); + if (pI830->exa_965_state == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to allocate exa state buffer for 965.\n"); + return FALSE; + } + } + } +#endif #ifdef I830_XV /* Allocate overlay register space and optional XAA linear allocator @@ -982,17 +996,6 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) return FALSE; } } - - if (IS_I965G(pI830) && pI830->exa_965_state == NULL) { - pI830->exa_965_state = - i830_allocate_memory(pScrn, "exa G965 state buffer", - EXA_LINEAR_EXTRA, GTT_PAGE_SIZE, 0); - if (pI830->exa_965_state == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to allocate exa state buffer for 965.\n"); - return FALSE; - } - } } #endif /* I830_USE_EXA */ From 4042b27f01fdb94e7fc0d4e991e054fff88479ea Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 5 Mar 2007 22:32:52 -0800 Subject: [PATCH 30/82] Move EnterVT mode setting code to xf86SetDesiredModes. Make the application of crtc desiredModes generic code instead of per-driver by creating xf86SetDesiredModes from the code that was in EnterVT and calling it. Also, move the frame buffer clear until just before mode setting to make sure things are mapped correctly. --- src/i830.h | 2 -- src/i830_display.h | 3 --- src/i830_driver.c | 45 +++++++-------------------------------------- src/i830_memory.c | 2 ++ 4 files changed, 9 insertions(+), 43 deletions(-) diff --git a/src/i830.h b/src/i830.h index 08d9e3ed..dfa94d8e 100644 --- a/src/i830.h +++ b/src/i830.h @@ -255,8 +255,6 @@ typedef struct _I830Rec { unsigned char *FbBase; int cpp; - DisplayModePtr currentMode; - I830EntPtr entityPrivate; int init; diff --git a/src/i830_display.h b/src/i830_display.h index 31ab6155..07dfe93a 100644 --- a/src/i830_display.h +++ b/src/i830_display.h @@ -28,9 +28,6 @@ #include "xorgVersion.h" /* i830_display.c */ -DisplayModePtr -i830PipeFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode); -Bool i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, Rotation rotation); void i830PipeSetBase(xf86CrtcPtr crtc, int x, int y); void i830WaitForVblank(ScrnInfoPtr pScrn); void i830DescribeOutputConfiguration(ScrnInfoPtr pScrn); diff --git a/src/i830_driver.c b/src/i830_driver.c index 7ab2cdc8..0977511f 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2885,9 +2885,7 @@ static Bool I830EnterVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); I830Ptr pI830 = I830PTR(pScrn); - int i; DPRINTF(PFX, "Enter VT\n"); @@ -2902,12 +2900,6 @@ I830EnterVT(int scrnIndex, int flags) pI830->leaving = FALSE; -#if 1 - /* Clear the framebuffer */ - memset(pI830->FbBase + pScrn->fbOffset, 0, - pScrn->virtualY * pScrn->displayWidth * pI830->cpp); -#endif - if (I830IsPrimary(pScrn)) if (!i830_bind_all_memory(pScrn)) return FALSE; @@ -2920,27 +2912,13 @@ I830EnterVT(int scrnIndex, int flags) ResetState(pScrn, FALSE); SetHWOperatingState(pScrn); - for (i = 0; i < xf86_config->num_crtc; i++) - { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - - /* Mark that we'll need to re-set the mode for sure */ - memset(&crtc->mode, 0, sizeof(crtc->mode)); - if (!crtc->desiredMode.CrtcHDisplay) - { - crtc->desiredMode = *i830PipeFindClosestMode (crtc, pScrn->currentMode); - crtc->desiredRotation = RR_Rotate_0; - crtc->desiredX = 0; - crtc->desiredY = 0; - } - - if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation, - crtc->desiredX, crtc->desiredY)) - return FALSE; - } - - xf86DisableUnusedFunctions(pScrn); + /* Clear the framebuffer */ + memset(pI830->FbBase + pScrn->fbOffset, 0, + pScrn->virtualY * pScrn->displayWidth * pI830->cpp); + if (!xf86SetDesiredModes (pScrn)) + return FALSE; + i830DumpRegs (pScrn); i830DescribeOutputConfiguration(pScrn); @@ -3003,8 +2981,6 @@ I830EnterVT(int scrnIndex, int flags) if (pI830->checkDevices) pI830->devicesTimer = TimerSet(NULL, 0, 1000, I830CheckDevicesTimer, pScrn); - pI830->currentMode = pScrn->currentMode; - /* Force invarient 3D state to be emitted */ *pI830->used3D = 1<<31; @@ -3014,17 +2990,10 @@ I830EnterVT(int scrnIndex, int flags) static Bool I830SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) { - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; I830Ptr pI830 = I830PTR(pScrn); - Bool ret = TRUE; - DPRINTF(PFX, "I830SwitchMode: mode == %p\n", mode); - - if (!i830SetMode(pScrn, mode, pI830->rotation)) - pI830->currentMode = mode; - - return ret; + return xf86SetSingleMode (pScrn, mode, pI830->rotation); } static Bool diff --git a/src/i830_memory.c b/src/i830_memory.c index 7bcf48e0..ea6b90d7 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -835,6 +835,8 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, return NULL; } + if (pI830->FbBase) + memset (pI830->FbBase + front_buffer->offset, 0, size); return front_buffer; } From e787d7b698d320a7c45df35d58c5113413561fe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 6 Mar 2007 09:35:42 +0100 Subject: [PATCH 31/82] Remove warnings about potential artifacts with page flipping and mixed 2D/3D. The artifacts only seemed to occur when EXA was falling back to software for the front buffer. --- man/intel.man | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/man/intel.man b/man/intel.man index 05a91f7e..32aa7c12 100644 --- a/man/intel.man +++ b/man/intel.man @@ -161,9 +161,9 @@ Default: 32768. .TP .BI "Option \*qPageFlip\*q \*q" boolean \*q Enable support for page flipping. This should improve 3D performance at the -potential cost of worse performance or artifacts with mixed 2D/3D. Also note -that this gives no benefit without corresponding support in the Mesa 3D driver -and may not give the full benefit without triple buffering (see +potential cost of worse performance with mixed 2D/3D. Also note that this gives +no benefit without corresponding support in the Mesa 3D driver and may not give +the full benefit without triple buffering (see .B "Option \*qTripleBuffer\*q" ). Default for i810: The option is not used. From c25cfafbe1eb380b58b5fc16e94f5cc6f422f0cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 6 Mar 2007 10:00:12 +0100 Subject: [PATCH 32/82] Unify allocation of back buffers. --- src/i830_memory.c | 77 +++++++++++------------------------------------ 1 file changed, 18 insertions(+), 59 deletions(-) diff --git a/src/i830_memory.c b/src/i830_memory.c index 17cad73b..54cd6beb 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -1064,7 +1064,8 @@ myLog2(unsigned int n) } static Bool -i830_allocate_backbuffer(ScrnInfoPtr pScrn) +i830_allocate_backbuffer(ScrnInfoPtr pScrn, i830_memory **buffer, + unsigned int *tiled, const char *name) { I830Ptr pI830 = I830PTR(pScrn); unsigned int pitch = pScrn->displayWidth * pI830->cpp; @@ -1080,69 +1081,23 @@ i830_allocate_backbuffer(ScrnInfoPtr pScrn) if (!pI830->disableTiling && IsTileable(pScrn, pitch)) { size = ROUND_TO_PAGE(pitch * ALIGN(height, 16)); - pI830->back_buffer = - i830_allocate_memory_tiled(pScrn, "back buffer", - size, pitch, GTT_PAGE_SIZE, - ALIGN_BOTH_ENDS, - TILING_XMAJOR); - pI830->back_tiled = FENCE_XMAJOR; + *buffer = i830_allocate_memory_tiled(pScrn, name, size, pitch, + GTT_PAGE_SIZE, ALIGN_BOTH_ENDS, + TILING_XMAJOR); + *tiled = FENCE_XMAJOR; } /* Otherwise, just allocate it linear */ - if (pI830->back_buffer == NULL) { + if (*buffer == NULL) { size = ROUND_TO_PAGE(pitch * height); - pI830->back_buffer = i830_allocate_memory(pScrn, "back buffer", - size, GTT_PAGE_SIZE, - ALIGN_BOTH_ENDS); - pI830->back_tiled = FENCE_LINEAR; + *buffer = i830_allocate_memory(pScrn, name, size, GTT_PAGE_SIZE, + ALIGN_BOTH_ENDS); + *tiled = FENCE_LINEAR; } - if (pI830->back_buffer == NULL) { + if (*buffer == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to allocate back buffer space.\n"); - return FALSE; - } - - return TRUE; -} - -static Bool -i830_allocate_thirdbuffer(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - unsigned int pitch = pScrn->displayWidth * pI830->cpp; - unsigned long size; - int height; - - if (pI830->rotation & (RR_Rotate_0 | RR_Rotate_180)) - height = pScrn->virtualY; - else - height = pScrn->virtualX; - - /* Try to allocate on the best tile-friendly boundaries. */ - if (!pI830->disableTiling && IsTileable(pScrn, pitch)) - { - size = ROUND_TO_PAGE(pitch * ALIGN(height, 16)); - pI830->third_buffer = - i830_allocate_memory_tiled(pScrn, "third buffer", - size, pitch, GTT_PAGE_SIZE, - ALIGN_BOTH_ENDS, - TILING_XMAJOR); - pI830->third_tiled = FENCE_XMAJOR; - } - - /* Otherwise, just allocate it linear */ - if (pI830->third_buffer == NULL) { - size = ROUND_TO_PAGE(pitch * height); - pI830->third_buffer = i830_allocate_memory(pScrn, "third buffer", - size, GTT_PAGE_SIZE, - ALIGN_BOTH_ENDS); - pI830->third_tiled = FENCE_LINEAR; - } - - if (pI830->third_buffer == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to allocate third buffer space.\n"); + "Failed to allocate %s space.\n", name); return FALSE; } @@ -1246,10 +1201,14 @@ i830_allocate_3d_memory(ScrnInfoPtr pScrn) DPRINTF(PFX, "i830_allocate_3d_memory\n"); - if (!i830_allocate_backbuffer(pScrn)) + if (!i830_allocate_backbuffer(pScrn, &pI830->back_buffer, + &pI830->back_tiled, "back buffer")) return FALSE; - if (pI830->TripleBuffer && !i830_allocate_thirdbuffer(pScrn)) { + if (pI830->TripleBuffer && !i830_allocate_backbuffer(pScrn, + &pI830->third_buffer, + &pI830->third_tiled, + "third buffer")) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to allocate third buffer, triple buffering " "inactive\n"); From 3c08bc7d6974a1a6cf5f9cb81898617032966c52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 6 Mar 2007 10:14:47 +0100 Subject: [PATCH 33/82] Fix some conditionals related to triple buffering. Guard code that dereferences pI830->third_buffer with tests for that instead of pI830->TripleBuffer. It could happen that we want to enable triple buffering but (temporarily) can't because the third buffer couldn't be allocated. --- src/i830_dri.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index d69ab3fb..bb9de1e8 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -748,18 +748,19 @@ I830DRIMapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Back Buffer = 0x%08x\n", (int)sarea->back_handle); - if (pI830->TripleBuffer) { + if (pI830->third_buffer) { if (drmAddMap(pI830->drmSubFD, (drm_handle_t)(sarea->third_offset + pI830->LinearAddr), sarea->third_size, DRM_AGP, 0, (drmAddress) &sarea->third_handle) < 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "[drm] drmAddMap(third_handle) failed. Disabling DRI\n"); - DRICloseScreen(pScreen); - return FALSE; - } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Third Buffer = 0x%08x\n", - (int)sarea->third_handle); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "[drm] drmAddMap(third_handle) failed. Triple buffering " + "inactive\n"); + i830_free_memory(pI830->third_buffer); + sarea->third_handle = pI830->third_buffer = NULL; + } else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Third Buffer = 0x%08x\n", + (int)sarea->third_handle); } if (drmAddMap(pI830->drmSubFD, @@ -1103,7 +1104,7 @@ I830DRIRefreshArea (ScrnInfoPtr pScrn, int num, BoxPtr pbox) I830DRIDoRefreshArea(pScrn, num, pbox, pI830->back_buffer->offset); - if (pI830->TripleBuffer) { + if (pI830->third_buffer) { I830DRIDoRefreshArea(pScrn, num, pbox, pI830->third_buffer->offset); } @@ -1207,7 +1208,7 @@ I830DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) I830SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); - if (I830PTR(pScrn)->TripleBuffer) { + if (I830PTR(pScrn)->third_buffer) { I830SelectBuffer(pScrn, I830_SELECT_THIRD); I830SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); @@ -1386,7 +1387,7 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, I830SelectBuffer(pScrn, I830_SELECT_BACK); I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); - if (pI830->TripleBuffer) { + if (pI830->third_buffer) { I830SelectBuffer(pScrn, I830_SELECT_THIRD); I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); } @@ -1582,8 +1583,13 @@ I830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea) sarea->height = pScreen->height; sarea->back_offset = pI830->back_buffer->offset; sarea->back_size = pI830->back_buffer->size; - sarea->third_offset = pI830->third_buffer->offset; - sarea->third_size = pI830->third_buffer->size; + if (pI830->third_buffer != NULL) { + sarea->third_offset = pI830->third_buffer->offset; + sarea->third_size = pI830->third_buffer->size; + } else { + sarea->third_offset = 0; + sarea->third_size = 0; + } sarea->depth_offset = pI830->depth_buffer->offset; sarea->depth_size = pI830->depth_buffer->size; if (pI830->textures != NULL) { From 1e1b45fa6ed1683cba4ae73ac98933e74c3ab9d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 6 Mar 2007 10:28:41 +0100 Subject: [PATCH 34/82] Fix reduced DRI memory manager size. pI830->mmSize is in kB. --- src/i830_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 0977511f..a27d8058 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2346,7 +2346,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* For this allocation, switch to a smaller DRI memory manager * size. */ - pI830->mmSize = I830_MM_MINPAGES * GTT_PAGE_SIZE; + pI830->mmSize = I830_MM_MINPAGES * GTT_PAGE_SIZE / KB(1); } else { pI830->mmSize = savedMMSize; } From e972265261c421268e4fb806e587378d0adec577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 6 Mar 2007 16:54:16 +0100 Subject: [PATCH 35/82] Fix build failure. Not sure how I missed this before... Thanks to Todd Merrill for reporting. --- src/i830_dri.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index bb9de1e8..9931acc4 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -756,8 +756,9 @@ I830DRIMapScreenRegions(ScrnInfoPtr pScrn, drmI830Sarea *sarea) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] drmAddMap(third_handle) failed. Triple buffering " "inactive\n"); - i830_free_memory(pI830->third_buffer); - sarea->third_handle = pI830->third_buffer = NULL; + i830_free_memory(pScrn, pI830->third_buffer); + pI830->third_buffer = NULL; + sarea->third_handle = 0; } else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] Third Buffer = 0x%08x\n", (int)sarea->third_handle); From 30bb719ca0abc2599ffb89e59f297fa9a0a00c3c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 6 Mar 2007 12:23:43 -0800 Subject: [PATCH 36/82] Continue to allocate the legacy texture pool by default. This is a partial revert of 7358642e64ab6d13bc1dc1a44703ee66d715ff61 If we don't allocate it now, when the DRM version is too low there won't be any memory allocated and DRI will fail. Instead, waste the memory in the i915tex case for now, and leave fixing it right (check DRM version up front and decide which memory manager to set up) to later. --- src/i830_driver.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index a27d8058..1aa06b99 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1234,14 +1234,13 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->mmModeFlags = 0; if (!pI830->directRenderingDisabled) { + pI830->mmModeFlags = I830_KERNEL_TEX; #ifdef XF86DRI_MM Bool tmp = FALSE; if (!IS_I965G(pI830)) pI830->mmModeFlags |= I830_KERNEL_MM; - else #endif - pI830->mmModeFlags |= I830_KERNEL_TEX; from = X_PROBED; From 94c37f35872487c04136fb659526bffefd9c46ad Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 6 Mar 2007 13:57:04 -0800 Subject: [PATCH 37/82] Make the depth buffer X tiled instead of Y, and fix a Y tiling nit on 945. The previous code claimed to set the depth buffer up as Y tiled, but due to lack of implementation in SetFence, it ended up being X tiled. Actually setting the Y tiling flag in the new version broke the depth buffer, so just switch the depth buffer to X tiling, which appears to work fine. --- src/i830_memory.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/i830_memory.c b/src/i830_memory.c index ea6b90d7..f0b50aac 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -1121,8 +1121,8 @@ i830_allocate_depthbuffer(ScrnInfoPtr pScrn) pI830->depth_buffer = i830_allocate_memory_tiled(pScrn, "depth buffer", size, pitch, GTT_PAGE_SIZE, ALIGN_BOTH_ENDS, - TILING_YMAJOR); - pI830->depth_tiled = FENCE_YMAJOR; + TILING_XMAJOR); + pI830->depth_tiled = FENCE_XMAJOR; } /* Otherwise, allocate it linear. */ @@ -1369,7 +1369,9 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset, } } - if (IS_I9XX(pI830)) + if ((IS_I945G(pI830) || IS_I945GM(pI830)) && tile_format == TILING_YMAJOR) + fence_pitch = pitch / 128; + else if (IS_I9XX(pI830)) fence_pitch = pitch / 512; else fence_pitch = pitch / 128; From b07dfbba5df7728232b38211c623185116dcea5c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 6 Mar 2007 13:59:14 -0800 Subject: [PATCH 38/82] Remove leftover code that was disabling tiling after we set it up. --- src/i830_driver.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 1aa06b99..bc6e07cc 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1912,18 +1912,6 @@ RestoreHWState(ScrnInfoPtr pScrn) return TRUE; } -static void -InitRegisterRec(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - int i; - - if (!I830IsPrimary(pScrn)) return; - - for (i = 0; i < 8; i++) - pI830->fence[i] = 0; -} - static void I830PointerMoved(int index, int x, int y) { @@ -2505,8 +2493,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } #endif - InitRegisterRec(pScrn); - #ifdef XF86DRI /* * pI830->directRenderingDisabled is set once in PreInit. Reinitialise From 04f50961e2f1610c39e7e4b45811f2a6b517cad6 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 6 Mar 2007 14:23:06 -0800 Subject: [PATCH 39/82] Bug #9898: Fix a crash with NoAccel set. --- src/i830_driver.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index bc6e07cc..ada334ba 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -537,8 +537,10 @@ I830MapMem(ScrnInfoPtr pScrn) if (!pI830->FbBase) return FALSE; - if (I830IsPrimary(pScrn)) - pI830->LpRing->virtual_start = pI830->FbBase + pI830->LpRing->mem->offset; + if (I830IsPrimary(pScrn) && pI830->LpRing->mem != NULL) { + pI830->LpRing->virtual_start = + pI830->FbBase + pI830->LpRing->mem->offset; + } return TRUE; } From 81722a21d232fa6cfb11fbe3d984abab50e89bcc Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 6 Mar 2007 23:16:53 -0800 Subject: [PATCH 40/82] Remove usage of 'shadow' module. Use xf86CrtcScreenInit. With the new mode setting code, rotation is handled outside of the driver, so the old usage of the 'shadow' module is no longer needed. Code to initialize the crtc structures has been moved out of the driver and into the modes code. --- src/common.h | 1 - src/i810_driver.c | 7 ---- src/i830_dri.c | 79 +------------------------------------- src/i830_driver.c | 97 ++++------------------------------------------- 4 files changed, 8 insertions(+), 176 deletions(-) diff --git a/src/common.h b/src/common.h index 6e8ddbda..f596eb87 100644 --- a/src/common.h +++ b/src/common.h @@ -87,7 +87,6 @@ extern const char *I810ddcSymbols[]; extern const char *I810fbSymbols[]; extern const char *I810xaaSymbols[]; extern const char *I810shadowFBSymbols[]; -extern const char *I810shadowSymbols[]; #ifdef XF86DRI extern const char *I810driSymbols[]; extern const char *I810drmSymbols[]; diff --git a/src/i810_driver.c b/src/i810_driver.c index 04166b78..6666d7f9 100644 --- a/src/i810_driver.c +++ b/src/i810_driver.c @@ -341,12 +341,6 @@ const char *I810driSymbols[] = { #endif /* I830_ONLY */ -const char *I810shadowSymbols[] = { - "shadowSetup", - "shadowAdd", - NULL -}; - const char *I810i2cSymbols[] = { "xf86CreateI2CBusRec", "xf86I2CBusInit", @@ -435,7 +429,6 @@ i810Setup(pointer module, pointer opts, int *errmaj, int *errmin) I810drmSymbols, I810driSymbols, #endif - I810shadowSymbols, I810shadowFBSymbols, I810vbeSymbols, vbeOptionalSymbols, I810ddcSymbols, I810int10Symbols, NULL); diff --git a/src/i830_dri.c b/src/i830_dri.c index f81251a5..680a28e7 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -108,10 +108,6 @@ static void I830DRITransitionTo3d(ScreenPtr pScreen); static void I830DRITransitionMultiToSingle3d(ScreenPtr pScreen); static void I830DRITransitionSingleToMulti3d(ScreenPtr pScreen); -#if 0 -static void I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf); -#endif - extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig * configs, void **configprivs); @@ -981,16 +977,7 @@ I830DRIFinishScreenInit(ScreenPtr pScreen) DPRINTF(PFX, "I830DRIFinishScreenInit\n"); - /* Have shadow run only while there is 3d active. - */ -#if 0 - if (pI830->allowPageFlip && pI830->drmMinor >= 1) { - shadowAdd(pScreen, 0, I830DRIShadowUpdate, 0, 0, 0); - } - else -#endif - pI830->allowPageFlip = 0; - + pI830->allowPageFlip = 0; if (!DRIFinishScreenInit(pScreen)) return FALSE; @@ -1267,70 +1254,6 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, * allocate and free 3d-specific memory on demand. */ - - - - -/* Use the miext/shadow module to maintain a list of dirty rectangles. - * These are blitted to the back buffer to keep both buffers clean - * during page-flipping when the 3d application isn't fullscreen. - * - * Unlike most use of the shadow code, both buffers are in video - * memory. - * - * An alternative to this would be to organize for all on-screen - * drawing operations to be duplicated for the two buffers. That - * might be faster, but seems like a lot more work... - */ - - -#if 0 -/* This should be done *before* XAA syncs, - * Otherwise will have to sync again??? - */ -static void -I830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); - RegionPtr damage = &pBuf->damage; - int i, num = REGION_NUM_RECTS(damage); - BoxPtr pbox = REGION_RECTS(damage); - drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen); - int cmd, br13; - - /* Don't want to do this when no 3d is active and pages are - * right-way-round : - */ - if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0) - return; - - br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16); - - if (pScrn->bitsPerPixel == 32) { - cmd = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - br13 |= 3 << 24; - } else { - cmd = (XY_SRC_COPY_BLT_CMD); - br13 |= 1 << 24; - } - - for (i = 0 ; i < num ; i++, pbox++) { - BEGIN_LP_RING(8); - OUT_RING(cmd); - OUT_RING(br13); - OUT_RING((pbox->y1 << 16) | pbox->x1); - OUT_RING((pbox->y2 << 16) | pbox->x2); - OUT_RING(pI830->back_buffer->offset); - OUT_RING((pbox->y1 << 16) | pbox->x1); - OUT_RING(br13 & 0xffff); - OUT_RING(pI830->front_buffer->offset); - ADVANCE_LP_RING(); - } -} -#endif - static void I830EnablePageFlip(ScreenPtr pScreen) { diff --git a/src/i830_driver.c b/src/i830_driver.c index ada334ba..30558ace 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1297,17 +1297,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) I830SetupOutputs(pScrn); SaveHWState(pScrn); - /* Do an initial detection of the outputs while none are configured on yet. - * This will give us some likely legitimate response for later if both - * pipes are already allocated and we're asked to do a detect. - */ - for (i = 0; i < xf86_config->num_output; i++) - { - xf86OutputPtr output = xf86_config->output[i]; - - output->status = (*output->funcs->detect) (output); - } - if (!xf86InitialConfiguration (pScrn, FALSE)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); @@ -1414,13 +1403,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) pI830->SWCursor = TRUE; } - if (!xf86RandR12PreInit (pScrn)) - { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n"); - PreInitCleanup(pScrn); - return FALSE; - } - if (pScrn->modes == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); PreInitCleanup(pScrn); @@ -1467,7 +1449,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) memset(&req, 0, sizeof(req)); req.majorversion = 2; - req.minorversion = 0; + req.minorversion = 1; if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL, &req, &errmaj, &errmin)) { LoaderErrorMsg(NULL, "exa", errmaj, errmin); @@ -1511,29 +1493,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } #endif - /* rotation requires the newer libshadow */ - if (I830IsPrimary(pScrn)) { - int errmaj, errmin; - pI830->shadowReq.majorversion = 1; - pI830->shadowReq.minorversion = 1; - - if (!LoadSubModule(pScrn->module, "shadow", NULL, NULL, NULL, - &pI830->shadowReq, &errmaj, &errmin)) { - pI830->shadowReq.minorversion = 0; - if (!LoadSubModule(pScrn->module, "shadow", NULL, NULL, NULL, - &pI830->shadowReq, &errmaj, &errmin)) { - LoaderErrorMsg(NULL, "shadow", errmaj, errmin); - return FALSE; - } - } - } else { - I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1); - pI830->shadowReq.majorversion = pI8301->shadowReq.majorversion; - pI830->shadowReq.minorversion = pI8301->shadowReq.minorversion; - pI830->shadowReq.patchlevel = pI8301->shadowReq.patchlevel; - } - xf86LoaderReqSymLists(I810shadowSymbols, NULL); - pI830->preinit = FALSE; return TRUE; @@ -1941,22 +1900,6 @@ I830PointerMoved(int index, int x, int y) (*pI830->PointerMoved)(index, newX, newY); } -static Bool -I830CreateScreenResources (ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); - - pScreen->CreateScreenResources = pI830->CreateScreenResources; - if (!(*pScreen->CreateScreenResources)(pScreen)) - return FALSE; - - if (!xf86RandR12CreateScreenResources (pScreen)) - return FALSE; - - return TRUE; -} - static Bool I830InitFBManager( ScreenPtr pScreen, @@ -2685,38 +2628,12 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = I830CloseScreen; - if (pI830->shadowReq.minorversion >= 1) { - /* Rotation */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n"); - xf86DisableRandR(); /* Disable built-in RandR extension */ - shadowSetup(pScreen); - /* support all rotations */ - xf86RandR12Init (pScreen); - 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; - pScreen->CreateScreenResources = I830CreateScreenResources; - } else { - /* Rotation */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "libshadow is version %d.%d.%d, required 1.1.0 or greater for rotation.\n",pI830->shadowReq.majorversion,pI830->shadowReq.minorversion,pI830->shadowReq.patchlevel); - } + if (!xf86CrtcScreenInit (pScreen)) + return FALSE; + + /* Wrap pointer motion to flip touch screen around */ + pI830->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = I830PointerMoved; if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); From a5f0522b1d34236278861fe15bac2df099f0a2c7 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Wed, 7 Mar 2007 15:49:47 +0000 Subject: [PATCH 41/82] Add some additional checks when XAA is enabled. --- src/i810_accel.c | 3 ++- src/i810_dri.c | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/i810_accel.c b/src/i810_accel.c index efbe2907..1f859b8a 100644 --- a/src/i810_accel.c +++ b/src/i810_accel.c @@ -597,7 +597,8 @@ I810RefreshRing(ScrnInfoPtr pScrn) if (pI810->LpRing->space < 0) pI810->LpRing->space += pI810->LpRing->mem.Size; - pI810->AccelInfoRec->NeedToSync = TRUE; + if (pI810->AccelInfoRec) + pI810->AccelInfoRec->NeedToSync = TRUE; } /* Emit on gaining VT? diff --git a/src/i810_dri.c b/src/i810_dri.c index 3e322837..72718d34 100644 --- a/src/i810_dri.c +++ b/src/i810_dri.c @@ -222,6 +222,7 @@ I810InitVisualConfigs(ScreenPtr pScreen) pConfigs[i].redSize = 5; pConfigs[i].greenSize = 6; pConfigs[i].blueSize = 5; + pConfigs[i].alphaSize = 0; pConfigs[i].redMask = 0x0000F800; pConfigs[i].greenMask = 0x000007E0; pConfigs[i].blueMask = 0x0000001F; @@ -1173,7 +1174,9 @@ I810DRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) pbox++; } I810SelectBuffer(pScrn, I810_SELECT_FRONT); - pI810->AccelInfoRec->NeedToSync = TRUE; + + if (pI810->AccelInfoRec) + pI810->AccelInfoRec->NeedToSync = TRUE; } /* This routine is a modified form of XAADoBitBlt with the calls to @@ -1332,7 +1335,8 @@ I810DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, DEALLOCATE_LOCAL(pboxNew1); } - pI810->AccelInfoRec->NeedToSync = TRUE; + if (pI810->AccelInfoRec) + pI810->AccelInfoRec->NeedToSync = TRUE; } From 14ee9195d203192d3f613919f230b20b900ffdba Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 7 Mar 2007 13:00:03 -0800 Subject: [PATCH 42/82] Bug #10157: Fix cursor corruption on server regen. --- src/i830_driver.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/i830_driver.c b/src/i830_driver.c index 30558ace..18a05ef5 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2962,6 +2962,8 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen) pI830->CursorInfoRec = 0; } + i830_reset_allocations(pScrn); + if (I830IsPrimary(pScrn)) { xf86GARTCloseScreen(scrnIndex); From 1991a90ae90b388c914985d20d6f8c3637856e9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 9 Mar 2007 19:47:13 +0100 Subject: [PATCH 43/82] Update SAREA pipe sizes in i830_crtc_dpms instead of i830PipeSetBase. This allows setting the size to 0 when a pipe gets disabled. --- src/i830_display.c | 26 ++++++++++++++++++++++---- src/i830_exa.c | 2 +- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/i830_display.c b/src/i830_display.c index 8a2494fe..78557126 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -399,14 +399,10 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y) case 0: sPriv->pipeA_x = x; sPriv->pipeA_y = y; - sPriv->pipeA_w = crtc->mode.HDisplay; - sPriv->pipeA_h = crtc->mode.VDisplay; break; case 1: sPriv->pipeB_x = x; sPriv->pipeB_y = y; - sPriv->pipeB_w = crtc->mode.HDisplay; - sPriv->pipeB_h = crtc->mode.VDisplay; break; default: xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -514,6 +510,28 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) usleep(150); break; } + +#ifdef XF86DRI + if (pI830->directRenderingEnabled) { + drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn->pScreen); + Bool enabled = crtc->enabled && mode != DPMSModeOff; + + switch (pipe) { + case 0: + sPriv->pipeA_w = enabled ? crtc->mode.HDisplay : 0; + sPriv->pipeA_h = enabled ? crtc->mode.VDisplay : 0; + break; + case 1: + sPriv->pipeB_w = enabled ? crtc->mode.HDisplay : 0; + sPriv->pipeB_h = enabled ? crtc->mode.VDisplay : 0; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Can't update pipe %d in SAREA\n", pipe); + break; + } + } +#endif } static Bool diff --git a/src/i830_exa.c b/src/i830_exa.c index bef8faef..dfc8f998 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -42,7 +42,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DEBUG_I830FALLBACK 1 #endif -#define ALWAYS_SYNC 1 +#define ALWAYS_SYNC 0 #ifdef DEBUG_I830FALLBACK #define I830FALLBACK(s, arg...) \ From 7518b8959ee7598f3526365a83ea7e143a5d6a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 9 Mar 2007 19:50:03 +0100 Subject: [PATCH 44/82] Revert change accidentally included in previous commit. --- src/i830_exa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_exa.c b/src/i830_exa.c index dfc8f998..bef8faef 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -42,7 +42,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DEBUG_I830FALLBACK 1 #endif -#define ALWAYS_SYNC 0 +#define ALWAYS_SYNC 1 #ifdef DEBUG_I830FALLBACK #define I830FALLBACK(s, arg...) \ From 3c2d6e07bdf8daef6486b594aef0d22460eb2585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 9 Mar 2007 23:49:46 +0100 Subject: [PATCH 45/82] Don't crash when the SAREA pointer is NULL. --- src/i830_display.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/i830_display.c b/src/i830_display.c index 78557126..d230f74f 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -395,6 +395,9 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y) if (pI830->directRenderingEnabled) { drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn->pScreen); + if (!sPriv) + return; + switch (pipe) { case 0: sPriv->pipeA_x = x; @@ -516,6 +519,9 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn->pScreen); Bool enabled = crtc->enabled && mode != DPMSModeOff; + if (!sPriv) + return; + switch (pipe) { case 0: sPriv->pipeA_w = enabled ? crtc->mode.HDisplay : 0; From 0d33fd3d03cef3a7e63d88ae441354390b37a937 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 11 Mar 2007 12:58:02 +1100 Subject: [PATCH 46/82] add XMODES flags to the i2c drivers --- src/ch7017/Makefile.am | 2 +- src/ch7xxx/Makefile.am | 2 +- src/ivch/Makefile.am | 2 +- src/sil164/Makefile.am | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ch7017/Makefile.am b/src/ch7017/Makefile.am index 7fbb4408..45bf699e 100644 --- a/src/ch7017/Makefile.am +++ b/src/ch7017/Makefile.am @@ -3,7 +3,7 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes +AM_CFLAGS = @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes ch7017_la_LTLIBRARIES = ch7017.la ch7017_la_LDFLAGS = -module -avoid-version diff --git a/src/ch7xxx/Makefile.am b/src/ch7xxx/Makefile.am index b827bf8e..68f766c1 100644 --- a/src/ch7xxx/Makefile.am +++ b/src/ch7xxx/Makefile.am @@ -3,7 +3,7 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes +AM_CFLAGS = @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes ch7xxx_la_LTLIBRARIES = ch7xxx.la ch7xxx_la_LDFLAGS = -module -avoid-version diff --git a/src/ivch/Makefile.am b/src/ivch/Makefile.am index 40e26277..ace076c2 100644 --- a/src/ivch/Makefile.am +++ b/src/ivch/Makefile.am @@ -3,7 +3,7 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes +AM_CFLAGS = @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes ivch_la_LTLIBRARIES = ivch.la ivch_la_LDFLAGS = -module -avoid-version diff --git a/src/sil164/Makefile.am b/src/sil164/Makefile.am index 4cf717c4..ac1b33ca 100644 --- a/src/sil164/Makefile.am +++ b/src/sil164/Makefile.am @@ -3,7 +3,7 @@ # -avoid-version prevents gratuitous .0.0.0 version numbers on the end # _ladir passes a dummy rpath to libtool so the thing will actually link # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. -AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes +AM_CFLAGS = @XMODES_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../modes sil164_la_LTLIBRARIES = sil164.la sil164_la_LDFLAGS = -module -avoid-version From 43a80ef9094efcb49027c83f0e726f907fecfbb2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 11 Mar 2007 12:58:26 +1100 Subject: [PATCH 47/82] fixup brace alignment for older X.org --- src/i830_dri.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index 52935744..38e11e73 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -549,8 +549,8 @@ I830DRIScreenInit(ScreenPtr pScreen) pDRIInfo->MoveBuffers = I830DRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; -#if DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1 { +#if DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1 int major, minor, patch; DRIQueryVersion(&major, &minor, &patch); From 797aa6fcb1231587bde1efb47bc8430c4c8d8110 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 11 Mar 2007 12:58:50 +1100 Subject: [PATCH 48/82] fixup missing assert includes --- src/i830_driver.c | 1 + src/i830_memory.c | 1 + src/i830_xaa.c | 1 + src/i965_render.c | 1 + 4 files changed, 4 insertions(+) diff --git a/src/i830_driver.c b/src/i830_driver.c index 599edc38..1be9fddf 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -165,6 +165,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define PRINT_MODE_INFO 0 #endif +#include #include #include #include diff --git a/src/i830_memory.c b/src/i830_memory.c index d6338ec5..e5168e1d 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -99,6 +99,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "config.h" #endif +#include #include #include "xf86.h" diff --git a/src/i830_xaa.c b/src/i830_xaa.c index 46ea7ecb..34403415 100644 --- a/src/i830_xaa.c +++ b/src/i830_xaa.c @@ -48,6 +48,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "config.h" #endif +#include #include "xf86.h" #include "xaarop.h" #include "i830.h" diff --git a/src/i965_render.c b/src/i965_render.c index 78f1146c..8d06c228 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -30,6 +30,7 @@ #include "config.h" #endif +#include #include "xf86.h" #include "i830.h" #include "i915_reg.h" From c4a23c5ef8ce56ee0fe547fbc7c6623c021f801b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Sat, 10 Mar 2007 16:15:33 +0100 Subject: [PATCH 49/82] Remove unused have3DWindows from pI830. --- src/i830.h | 1 - src/i830_dri.c | 3 --- 2 files changed, 4 deletions(-) diff --git a/src/i830.h b/src/i830.h index 82a41664..dc8041c5 100644 --- a/src/i830.h +++ b/src/i830.h @@ -306,7 +306,6 @@ typedef struct _I830Rec { int TexGranularity; int drmMinor; - Bool have3DWindows; int mmModeFlags; int mmSize; diff --git a/src/i830_dri.c b/src/i830_dri.c index 38e11e73..f55fa715 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -1468,7 +1468,6 @@ I830DRITransitionTo3d(ScreenPtr pScreen) I830Ptr pI830 = I830PTR(pScrn); I830DRISetPfMask(pScreen, pI830->allowPageFlip ? 0x3 : 0); - pI830->have3DWindows = 1; } @@ -1488,8 +1487,6 @@ I830DRITransitionTo2d(ScreenPtr pScreen) "[dri] %s: kernel failed to unflip buffers.\n", __func__); I830DRISetPfMask(pScreen, 0); - - pI830->have3DWindows = 0; } static void From ba55ff15df974197bebd871e28bb96d817ae41c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 12 Mar 2007 13:01:00 +0100 Subject: [PATCH 50/82] Fix attempt to flip pages back to normal when the last 3D window disappears. When this succeeds, 2D rendering does not have to be synchronized to back buffers until the next 3D window appears. --- configure.ac | 8 ++++++++ src/i830_dri.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index fbb9c647..52cc07bd 100644 --- a/configure.ac +++ b/configure.ac @@ -180,6 +180,14 @@ if test "$DRI" = yes; then if test "$have_damage_h" = yes; then AC_DEFINE(DAMAGE,1,[Use Damage extension]) fi + + save_CFLAGS="$CFLAGS" + CFLAGS="$DRI_CFLAGS" + AC_CHECK_TYPE(drm_i915_flip_t, + [AC_DEFINE(HAVE_I915_FLIP, 1, + [Have drm_i915_flip_t and related definitions])], + [], [#include ]) + CFLAGS="$save_CFLAGS" fi AM_CONDITIONAL(VIDEO_DEBUG, test x$VIDEO_DEBUG = xyes) diff --git a/src/i830_dri.c b/src/i830_dri.c index f55fa715..52c30ebd 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -81,6 +81,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "i830.h" #include "i830_dri.h" +#include "i915_drm.h" + #include "dristruct.h" static char I830KernelDriverName[] = "i915"; @@ -563,12 +565,13 @@ I830DRIScreenInit(ScreenPtr pScreen) #endif } + pDRIInfo->TransitionTo2d = I830DRITransitionTo2d; + #if DRIINFO_MAJOR_VERSION > 5 || \ (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1) if (!pDRIInfo->ClipNotify) #endif { - pDRIInfo->TransitionTo2d = I830DRITransitionTo2d; pDRIInfo->TransitionTo3d = I830DRITransitionTo3d; pDRIInfo->TransitionSingleToMulti3D = I830DRITransitionSingleToMulti3d; pDRIInfo->TransitionMultiToSingle3D = I830DRITransitionMultiToSingle3d; @@ -1470,6 +1473,22 @@ I830DRITransitionTo3d(ScreenPtr pScreen) I830DRISetPfMask(pScreen, pI830->allowPageFlip ? 0x3 : 0); } +/* This block and the corresponding configure test can be removed when + * libdrm >= 2.3.1 is required. + */ +#ifndef HAVE_I915_FLIP + +#define DRM_VBLANK_FLIP 0x8000000 + +typedef struct drm_i915_flip { + int pipes; +} drm_i915_flip_t; + +#undef DRM_IOCTL_I915_FLIP +#define DRM_IOCTL_I915_FLIP DRM_IOW(DRM_COMMAND_BASE + DRM_I915_FLIP, \ + drm_i915_flip_t) + +#endif static void I830DRITransitionTo2d(ScreenPtr pScreen) @@ -1479,10 +1498,27 @@ I830DRITransitionTo2d(ScreenPtr pScreen) drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); /* Try flipping back to the front page if necessary */ - if (sPriv->pf_current_page == 1) - drmCommandNone(pI830->drmSubFD, DRM_I830_FLIP); + if (sPriv->pf_current_page != 0) { + drm_i915_flip_t flip = { .pipes = 0 }; - if (sPriv->pf_current_page == 1) + if (sPriv->pf_current_page & (0x3 << 2)) { + sPriv->pf_current_page = sPriv->pf_current_page & 0x3; + sPriv->pf_current_page |= (sPriv->third_handle ? 2 : 1) << 2; + + flip.pipes |= 0x2; + } + + if (sPriv->pf_current_page & 0x3) { + sPriv->pf_current_page = sPriv->pf_current_page & (0x3 << 2); + sPriv->pf_current_page |= sPriv->third_handle ? 2 : 1; + + flip.pipes |= 0x1; + } + + drmCommandWrite(pI830->drmSubFD, DRM_I915_FLIP, &flip, sizeof(flip)); + } + + if (sPriv->pf_current_page != 0) xf86DrvMsg(pScreen->myNum, X_WARNING, "[dri] %s: kernel failed to unflip buffers.\n", __func__); From fe59ab9f562fd10118563d80eb3351a4d3b48b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 12 Mar 2007 13:03:47 +0100 Subject: [PATCH 51/82] Disable page flipping if the DRM is older than 1.9. Older versions don't support the functionality we need. --- src/i830_dri.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/i830_dri.c b/src/i830_dri.c index 52c30ebd..5a3aec0f 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -687,6 +687,14 @@ I830DRIScreenInit(ScreenPtr pScreen) pI830->memory_manager = NULL; } } +#ifdef DAMAGE + if (pI830->allowPageFlip && pI830->drmMinor < 9) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "DRM version 1.9 or newer required for Page flipping. " + "Disabling.\n"); + pI830->allowPageFlip = FALSE; + } +#endif drmFreeVersion(version); } } From 7c561956a28e90667fef140bc3cfa0edca464f15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 12 Mar 2007 18:55:27 +0100 Subject: [PATCH 52/82] Defer flipping pages back to normal until the end of the DRI block handler. Doing it earlier can result in the wrong page being visible, giving the appearance of a frozen X server. --- src/i830_dri.c | 60 +++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index 5a3aec0f..96061bd2 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -1167,6 +1167,8 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, } else if (syncType == DRI_2D_SYNC && oldContextType == DRI_NO_CONTEXT && newContextType == DRI_2D_CONTEXT) { + drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); + if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("i830DRISwapContext (out)\n"); @@ -1194,6 +1196,33 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, I830EmitFlush(pScrn); +#ifdef DAMAGE + /* Try flipping back to the front page if necessary */ + if (sPriv && !sPriv->pf_enabled && sPriv->pf_current_page != 0) { + drm_i915_flip_t flip = { .pipes = 0 }; + + if (sPriv->pf_current_page & (0x3 << 2)) { + sPriv->pf_current_page = sPriv->pf_current_page & 0x3; + sPriv->pf_current_page |= (sPriv->third_handle ? 2 : 1) << 2; + + flip.pipes |= 0x2; + } + + if (sPriv->pf_current_page & 0x3) { + sPriv->pf_current_page = sPriv->pf_current_page & (0x3 << 2); + sPriv->pf_current_page |= sPriv->third_handle ? 2 : 1; + + flip.pipes |= 0x1; + } + + drmCommandWrite(pI830->drmSubFD, DRM_I915_FLIP, &flip, sizeof(flip)); + + if (sPriv->pf_current_page != 0) + xf86DrvMsg(pScreen->myNum, X_WARNING, + "[dri] %s: kernel failed to unflip buffers.\n", __func__); + } +#endif + pI830->LockHeld = 0; } else if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("i830DRISwapContext (other)\n"); @@ -1448,7 +1477,7 @@ I830DRISetPfMask(ScreenPtr pScreen, int pfMask) pSAREAPriv->pf_enabled = pI830->allowPageFlip; pSAREAPriv->pf_active = pfMask; } else - pSAREAPriv->pf_enabled = pSAREAPriv->pf_active = 0; + pSAREAPriv->pf_active = 0; } static void @@ -1501,36 +1530,11 @@ typedef struct drm_i915_flip { static void I830DRITransitionTo2d(ScreenPtr pScreen) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); - /* Try flipping back to the front page if necessary */ - if (sPriv->pf_current_page != 0) { - drm_i915_flip_t flip = { .pipes = 0 }; - - if (sPriv->pf_current_page & (0x3 << 2)) { - sPriv->pf_current_page = sPriv->pf_current_page & 0x3; - sPriv->pf_current_page |= (sPriv->third_handle ? 2 : 1) << 2; - - flip.pipes |= 0x2; - } - - if (sPriv->pf_current_page & 0x3) { - sPriv->pf_current_page = sPriv->pf_current_page & (0x3 << 2); - sPriv->pf_current_page |= sPriv->third_handle ? 2 : 1; - - flip.pipes |= 0x1; - } - - drmCommandWrite(pI830->drmSubFD, DRM_I915_FLIP, &flip, sizeof(flip)); - } - - if (sPriv->pf_current_page != 0) - xf86DrvMsg(pScreen->myNum, X_WARNING, - "[dri] %s: kernel failed to unflip buffers.\n", __func__); - I830DRISetPfMask(pScreen, 0); + + sPriv->pf_enabled = 0; } static void From 7aa257154685bd2520649ce87a3a84e55644d02c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 12 Mar 2007 19:00:14 +0100 Subject: [PATCH 53/82] Fix build against released libdrm. --- src/i830_dri.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index 96061bd2..8fae4b7e 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -83,6 +83,23 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "i915_drm.h" +/* This block and the corresponding configure test can be removed when + * libdrm >= 2.3.1 is required. + */ +#ifndef HAVE_I915_FLIP + +#define DRM_VBLANK_FLIP 0x8000000 + +typedef struct drm_i915_flip { + int pipes; +} drm_i915_flip_t; + +#undef DRM_IOCTL_I915_FLIP +#define DRM_IOCTL_I915_FLIP DRM_IOW(DRM_COMMAND_BASE + DRM_I915_FLIP, \ + drm_i915_flip_t) + +#endif + #include "dristruct.h" static char I830KernelDriverName[] = "i915"; @@ -1510,23 +1527,6 @@ I830DRITransitionTo3d(ScreenPtr pScreen) I830DRISetPfMask(pScreen, pI830->allowPageFlip ? 0x3 : 0); } -/* This block and the corresponding configure test can be removed when - * libdrm >= 2.3.1 is required. - */ -#ifndef HAVE_I915_FLIP - -#define DRM_VBLANK_FLIP 0x8000000 - -typedef struct drm_i915_flip { - int pipes; -} drm_i915_flip_t; - -#undef DRM_IOCTL_I915_FLIP -#define DRM_IOCTL_I915_FLIP DRM_IOW(DRM_COMMAND_BASE + DRM_I915_FLIP, \ - drm_i915_flip_t) - -#endif - static void I830DRITransitionTo2d(ScreenPtr pScreen) { From 1ed3843f73a0d8efa405daff3483ebe70bf6134f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 12 Mar 2007 17:47:32 -0700 Subject: [PATCH 54/82] Make the 965 use Y-major tiling for the depth buffer, as required by the spec. An example of the failure can be seen with the reflect demo when set to depth buffer mode. Reported by: Haihao Xiang --- src/i830_memory.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/i830_memory.c b/src/i830_memory.c index e5168e1d..0742d8c0 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -1122,12 +1122,19 @@ i830_allocate_depthbuffer(ScrnInfoPtr pScrn) /* First try allocating it tiled */ if (!pI830->disableTiling && IsTileable(pScrn, pitch)) { + enum tile_format tile_format; + size = ROUND_TO_PAGE(pitch * ALIGN(height, 16)); + /* The 965 requires that the depth buffer be in Y Major format, while + * the rest appear to fail when handed that format. + */ + tile_format = IS_I965G(pI830) ? TILING_YMAJOR: TILING_XMAJOR; + pI830->depth_buffer = i830_allocate_memory_tiled(pScrn, "depth buffer", size, pitch, GTT_PAGE_SIZE, ALIGN_BOTH_ENDS, - TILING_XMAJOR); + tile_format); pI830->depth_tiled = FENCE_XMAJOR; } From 2824ec7ccbf44ba413a6133f735f4a548c73b3cd Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 13 Mar 2007 09:53:35 -0700 Subject: [PATCH 55/82] Fix uninitialized string use in SDVO non-TMDS case. --- src/i830_sdvo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c index b7cf8436..a3db5176 100644 --- a/src/i830_sdvo.c +++ b/src/i830_sdvo.c @@ -1205,6 +1205,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) "%s: No active TMDS outputs (0x%02x%02x)\n", SDVO_NAME(dev_priv), bytes[0], bytes[1]); + name_prefix="Unknown"; } strcpy (name, name_prefix); strcat (name, name_suffix); From 9c17c6e9c63563cad5edff837519a73fe0afe313 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 13 Mar 2007 09:55:49 -0700 Subject: [PATCH 56/82] Add write posting protections to relevant register writes in the mode-set path. --- src/i830_display.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/i830_display.c b/src/i830_display.c index d230f74f..e5390b38 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -447,12 +447,15 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) if ((temp & DPLL_VCO_ENABLE) == 0) { OUTREG(dpll_reg, temp); + (void)INREG(dpll_reg); /* Wait for the clocks to stabilize. */ usleep(150); OUTREG(dpll_reg, temp | DPLL_VCO_ENABLE); + (void)INREG(dpll_reg); /* Wait for the clocks to stabilize. */ usleep(150); OUTREG(dpll_reg, temp | DPLL_VCO_ENABLE); + (void)INREG(dpll_reg); /* Wait for the clocks to stabilize. */ usleep(150); } @@ -490,6 +493,7 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); /* Flush the plane changes */ OUTREG(dspbase_reg, INREG(dspbase_reg)); + (void)INREG(dspbase_reg); } if (!IS_I9XX(pI830)) { @@ -499,15 +503,19 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) /* Next, disable display pipes */ temp = INREG(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) != 0) + if ((temp & PIPEACONF_ENABLE) != 0) { OUTREG(pipeconf_reg, temp & ~PIPEACONF_ENABLE); + (void)INREG(pipeconf_reg); + } /* Wait for vblank for the disable to take effect. */ i830WaitForVblank(pScrn); temp = INREG(dpll_reg); - if ((temp & DPLL_VCO_ENABLE) != 0) + if ((temp & DPLL_VCO_ENABLE) != 0) { OUTREG(dpll_reg, temp & ~DPLL_VCO_ENABLE); + (void)INREG(dpll_reg); + } /* Wait for the clocks to turn off. */ usleep(150); @@ -856,15 +864,6 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, pipeconf |= PIPEACONF_ENABLE; dpll |= DPLL_VCO_ENABLE; #endif - - if (is_lvds) - { - /* The LVDS pin pair needs to be on before the DPLLs are enabled. - * This is an exception to the general rule that mode_set doesn't turn - * things on. - */ - OUTREG(LVDS, INREG(LVDS) | LVDS_PORT_EN | LVDS_PIPEB_SELECT); - } /* Disable the panel fitter if it was on our pipe */ if (i830_panel_fitter_pipe (pI830) == pipe) @@ -877,10 +876,23 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, { OUTREG(fp_reg, fp); OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE); + (void)INREG(dpll_reg); usleep(150); } + + if (is_lvds) + { + /* The LVDS pin pair needs to be on before the DPLLs are enabled. + * This is an exception to the general rule that mode_set doesn't turn + * things on. + */ + OUTREG(LVDS, INREG(LVDS) | LVDS_PORT_EN | LVDS_PIPEB_SELECT); + (void)INREG(LVDS); + } + OUTREG(fp_reg, fp); OUTREG(dpll_reg, dpll); + (void)INREG(dpll_reg); /* Wait for the clocks to stabilize. */ usleep(150); @@ -889,9 +901,10 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, OUTREG(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); } else { - /* write it again -- the BIOS does, after all */ - OUTREG(dpll_reg, dpll); + /* write it again -- the BIOS does, after all */ + OUTREG(dpll_reg, dpll); } + (void)INREG(dpll_reg); /* Wait for the clocks to stabilize. */ usleep(150); @@ -915,8 +928,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, OUTREG(dsppos_reg, 0); OUTREG(pipesrc_reg, ((mode->HDisplay - 1) << 16) | (mode->VDisplay - 1)); OUTREG(pipeconf_reg, pipeconf); + (void)INREG(pipeconf_reg); i830WaitForVblank(pScrn); - + OUTREG(dspcntr_reg, dspcntr); /* Flush the plane changes */ i830PipeSetBase(crtc, x, y); From 9d30f0007203157e6b82fa0ffc57324490eb2ca0 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 13 Mar 2007 10:04:06 -0700 Subject: [PATCH 57/82] Replace #if 0ed LVDS register setting with updated comment. --- src/i830_lvds.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/i830_lvds.c b/src/i830_lvds.c index f554b388..adfbe4f1 100644 --- a/src/i830_lvds.c +++ b/src/i830_lvds.c @@ -225,13 +225,9 @@ i830_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode, I830Ptr pI830 = I830PTR(pScrn); CARD32 pfit_control; -#if 0 - /* The LVDS pin pair needs to be on before the DPLLs are enabled. - * This is an exception to the general rule that mode_set doesn't turn - * things on. + /* The LVDS pin pair will already have been turned on in the + * i830_crtc_mode_set since it has a large impact on the DPLL settings. */ - OUTREG(LVDS, INREG(LVDS) | LVDS_PORT_EN | LVDS_PIPEB_SELECT); -#endif /* Enable automatic panel scaling so that non-native modes fill the * screen. Should be enabled before the pipe is enabled, according to From cf33abe43bd95c9437fad8e6201a24084ff96cb8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 13 Mar 2007 10:08:57 -0700 Subject: [PATCH 58/82] Add write posting protection for the SDVO DPMS-on path. --- src/i830_sdvo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c index a3db5176..4c543db4 100644 --- a/src/i830_sdvo.c +++ b/src/i830_sdvo.c @@ -695,12 +695,14 @@ i830_sdvo_dpms(xf86OutputPtr output, int mode) if ((temp & SDVO_ENABLE) == 0) { OUTREG(dev_priv->output_device, temp | SDVO_ENABLE); + (void)INREG(dev_priv->output_device); #if 0 /* Do it again! If we remove this below register write, or the exact * same one 2 lines up, the mac mini SDVO output doesn't turn on. */ OUTREG(dev_priv->output_device, INREG(dev_priv->output_device) | SDVO_ENABLE); + (void)INREG(dev_priv->output_device); #endif } for (i = 0; i < 2; i++) From 578da7ca705c5a58c0bd397b0831e2f95140f8ae Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 13 Mar 2007 10:11:29 -0700 Subject: [PATCH 59/82] Add PCI write posting protection to i2c putbits. --- src/i830_i2c.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/i830_i2c.c b/src/i830_i2c.c index 450f9de0..7fac63cd 100644 --- a/src/i830_i2c.c +++ b/src/i830_i2c.c @@ -336,6 +336,7 @@ i830I2CPutBits(I2CBusPtr b, int clock, int data) clock_bits = GPIO_CLOCK_DIR_OUT|GPIO_CLOCK_DIR_MASK|GPIO_CLOCK_VAL_MASK; OUTREG(b->DriverPrivate.uval, reserved | data_bits | clock_bits); + (void)INREG(b->DriverPrivate.uval); } #endif From 5135b3a79f9c30ebce78c84c49846bba83607fed Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 13 Mar 2007 10:21:06 -0700 Subject: [PATCH 60/82] Use a POSTING_READ(reg) macro instead of using the (void)INREG(reg) pattern. --- src/common.h | 1 + src/i830_display.c | 28 ++++++++++++++-------------- src/i830_i2c.c | 2 +- src/i830_sdvo.c | 4 ++-- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/common.h b/src/common.h index f596eb87..a6348950 100644 --- a/src/common.h +++ b/src/common.h @@ -233,6 +233,7 @@ union intfloat { #define INREG8(addr) *(volatile CARD8 *)(RecPtr->MMIOBase + (addr)) #define INREG16(addr) *(volatile CARD16 *)(RecPtr->MMIOBase + (addr)) #define INREG(addr) *(volatile CARD32 *)(RecPtr->MMIOBase + (addr)) +#define POSTING_READ(addr) (void)INREG(addr) #define OUTREG8(addr, val) do { \ *(volatile CARD8 *)(RecPtr->MMIOBase + (addr)) = (val); \ diff --git a/src/i830_display.c b/src/i830_display.c index e5390b38..a5d8df84 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -383,12 +383,12 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y) if (IS_I965G(pI830)) { OUTREG(dspbase, Offset); - (void) INREG(dspbase); + POSTING_READ(dspbase); OUTREG(dspsurf, Start); - (void) INREG(dspsurf); + POSTING_READ(dspsurf); } else { OUTREG(dspbase, Start + Offset); - (void) INREG(dspbase); + POSTING_READ(dspbase); } #ifdef XF86DRI @@ -447,15 +447,15 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) if ((temp & DPLL_VCO_ENABLE) == 0) { OUTREG(dpll_reg, temp); - (void)INREG(dpll_reg); + POSTING_READ(dpll_reg); /* Wait for the clocks to stabilize. */ usleep(150); OUTREG(dpll_reg, temp | DPLL_VCO_ENABLE); - (void)INREG(dpll_reg); + POSTING_READ(dpll_reg); /* Wait for the clocks to stabilize. */ usleep(150); OUTREG(dpll_reg, temp | DPLL_VCO_ENABLE); - (void)INREG(dpll_reg); + POSTING_READ(dpll_reg); /* Wait for the clocks to stabilize. */ usleep(150); } @@ -493,7 +493,7 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); /* Flush the plane changes */ OUTREG(dspbase_reg, INREG(dspbase_reg)); - (void)INREG(dspbase_reg); + POSTING_READ(dspbase_reg); } if (!IS_I9XX(pI830)) { @@ -505,7 +505,7 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) temp = INREG(pipeconf_reg); if ((temp & PIPEACONF_ENABLE) != 0) { OUTREG(pipeconf_reg, temp & ~PIPEACONF_ENABLE); - (void)INREG(pipeconf_reg); + POSTING_READ(pipeconf_reg); } /* Wait for vblank for the disable to take effect. */ @@ -514,7 +514,7 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode) temp = INREG(dpll_reg); if ((temp & DPLL_VCO_ENABLE) != 0) { OUTREG(dpll_reg, temp & ~DPLL_VCO_ENABLE); - (void)INREG(dpll_reg); + POSTING_READ(dpll_reg); } /* Wait for the clocks to turn off. */ @@ -876,7 +876,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, { OUTREG(fp_reg, fp); OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE); - (void)INREG(dpll_reg); + POSTING_READ(dpll_reg); usleep(150); } @@ -887,12 +887,12 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, * things on. */ OUTREG(LVDS, INREG(LVDS) | LVDS_PORT_EN | LVDS_PIPEB_SELECT); - (void)INREG(LVDS); + POSTING_READ(LVDS); } OUTREG(fp_reg, fp); OUTREG(dpll_reg, dpll); - (void)INREG(dpll_reg); + POSTING_READ(dpll_reg); /* Wait for the clocks to stabilize. */ usleep(150); @@ -904,7 +904,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, /* write it again -- the BIOS does, after all */ OUTREG(dpll_reg, dpll); } - (void)INREG(dpll_reg); + POSTING_READ(dpll_reg); /* Wait for the clocks to stabilize. */ usleep(150); @@ -928,7 +928,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, OUTREG(dsppos_reg, 0); OUTREG(pipesrc_reg, ((mode->HDisplay - 1) << 16) | (mode->VDisplay - 1)); OUTREG(pipeconf_reg, pipeconf); - (void)INREG(pipeconf_reg); + POSTING_READ(pipeconf_reg); i830WaitForVblank(pScrn); OUTREG(dspcntr_reg, dspcntr); diff --git a/src/i830_i2c.c b/src/i830_i2c.c index 7fac63cd..319e8dab 100644 --- a/src/i830_i2c.c +++ b/src/i830_i2c.c @@ -336,7 +336,7 @@ i830I2CPutBits(I2CBusPtr b, int clock, int data) clock_bits = GPIO_CLOCK_DIR_OUT|GPIO_CLOCK_DIR_MASK|GPIO_CLOCK_VAL_MASK; OUTREG(b->DriverPrivate.uval, reserved | data_bits | clock_bits); - (void)INREG(b->DriverPrivate.uval); + POSTING_READ(b->DriverPrivate.uval); } #endif diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c index 4c543db4..cd0b115a 100644 --- a/src/i830_sdvo.c +++ b/src/i830_sdvo.c @@ -695,14 +695,14 @@ i830_sdvo_dpms(xf86OutputPtr output, int mode) if ((temp & SDVO_ENABLE) == 0) { OUTREG(dev_priv->output_device, temp | SDVO_ENABLE); - (void)INREG(dev_priv->output_device); + POSTING_READ(dev_priv->output_device); #if 0 /* Do it again! If we remove this below register write, or the exact * same one 2 lines up, the mac mini SDVO output doesn't turn on. */ OUTREG(dev_priv->output_device, INREG(dev_priv->output_device) | SDVO_ENABLE); - (void)INREG(dev_priv->output_device); + POSTING_READ(dev_priv->output_device); #endif } for (i = 0; i < 2; i++) From 44708bdd9ebfef0328302c9a964b80deb46e57c6 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 13 Mar 2007 16:55:38 -0700 Subject: [PATCH 61/82] Get SDVO DPMS working on the Mac Mini by writing SDVOB and SDVOC together. Also, add code for setting the encoder power state like the BIOS does, but this doesn't appear to work. We do much more than the BIOS does in powering things down, so perhaps that's interfering somehow. --- src/i830_sdvo.c | 81 ++++++++++++++++++++++++++++++++++++++------ src/i830_sdvo_regs.h | 8 +++++ 2 files changed, 78 insertions(+), 11 deletions(-) diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c index cd0b115a..fb6a7c88 100644 --- a/src/i830_sdvo.c +++ b/src/i830_sdvo.c @@ -79,6 +79,25 @@ struct i830_sdvo_priv { /** @} */ }; +/** + * Writes the SDVOB or SDVOC with the given value, but always writes both + * SDVOB and SDVOC to work around apparent hardware issues (according to + * comments in the BIOS). + */ +static void i830_sdvo_write_sdvox(xf86OutputPtr output, CARD32 val) +{ + ScrnInfoPtr pScrn = output->scrn; + I830OutputPrivatePtr intel_output = output->driver_private; + struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; + I830Ptr pI830 = I830PTR(pScrn); + + if (dev_priv->output_device == SDVOC) + OUTREG(SDVOB, INREG(SDVOB)); + OUTREG(dev_priv->output_device, val); + if (dev_priv->output_device == SDVOB) + OUTREG(SDVOC, INREG(SDVOC)); +} + /** Read a single byte from the given address on the SDVO device. */ static Bool i830_sdvo_read_byte(xf86OutputPtr output, int addr, unsigned char *ch) @@ -163,6 +182,9 @@ const static struct _sdvo_cmd_name { SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS), SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT), SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_POWER_STATES), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODER_POWER_STATE), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODER_POWER_STATE), SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_RESOLUTION_SUPPORT), SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH), }; @@ -346,6 +368,34 @@ i830_sdvo_set_active_outputs(xf86OutputPtr output, return (status == SDVO_CMD_STATUS_SUCCESS); } +static Bool +i830_sdvo_set_encoder_power_state(xf86OutputPtr output, int mode) +{ + CARD8 status; + CARD8 state; + + switch (mode) { + case DPMSModeOn: + state = SDVO_ENCODER_STATE_ON; + break; + case DPMSModeStandby: + state = SDVO_ENCODER_STATE_STANDBY; + break; + case DPMSModeSuspend: + state = SDVO_ENCODER_STATE_SUSPEND; + break; + case DPMSModeOff: + state = SDVO_ENCODER_STATE_OFF; + break; + } + + i830_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state, + sizeof(state)); + status = i830_sdvo_read_response(output, NULL, 0); + + return (status == SDVO_CMD_STATUS_SUCCESS); +} + /** * Returns the pixel clock range limits of the current target input in kHz. */ @@ -669,7 +719,7 @@ i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode, sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; } - OUTREG(dev_priv->output_device, sdvox); + i830_sdvo_write_sdvox(output, sdvox); } static void @@ -683,9 +733,16 @@ i830_sdvo_dpms(xf86OutputPtr output, int mode) if (mode != DPMSModeOn) { i830_sdvo_set_active_outputs(output, 0); - temp = INREG(dev_priv->output_device); - if ((temp & SDVO_ENABLE) != 0) - OUTREG(dev_priv->output_device, temp & ~SDVO_ENABLE); + if (0) + i830_sdvo_set_encoder_power_state(output, mode); + + if (mode == DPMSModeOff) { + temp = INREG(dev_priv->output_device); + if ((temp & SDVO_ENABLE) != 0) { + i830_sdvo_write_sdvox(output, temp & ~SDVO_ENABLE); + POSTING_READ(dev_priv->output_device); + } + } } else { Bool input1, input2; int i; @@ -694,14 +751,15 @@ i830_sdvo_dpms(xf86OutputPtr output, int mode) temp = INREG(dev_priv->output_device); if ((temp & SDVO_ENABLE) == 0) { - OUTREG(dev_priv->output_device, temp | SDVO_ENABLE); + i830_sdvo_write_sdvox(output, temp | SDVO_ENABLE); POSTING_READ(dev_priv->output_device); #if 0 - /* Do it again! If we remove this below register write, or the exact - * same one 2 lines up, the mac mini SDVO output doesn't turn on. + /* Do it again! If we remove this below register write, or the + * exact same one 2 lines up, the mac mini SDVO output doesn't + * turn on. */ - OUTREG(dev_priv->output_device, - INREG(dev_priv->output_device) | SDVO_ENABLE); + i830_sdvo_write_sdvox(output, INREG(dev_priv->output_device) | + SDVO_ENABLE); POSTING_READ(dev_priv->output_device); #endif } @@ -717,6 +775,8 @@ i830_sdvo_dpms(xf86OutputPtr output, int mode) SDVO_NAME(dev_priv)); } + if (0) + i830_sdvo_set_encoder_power_state(output, mode); i830_sdvo_set_active_outputs(output, dev_priv->active_outputs); } } @@ -764,7 +824,6 @@ i830_sdvo_restore(xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; I830OutputPrivatePtr intel_output = output->driver_private; struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - I830Ptr pI830 = I830PTR(pScrn); int o; int i; Bool input1, input2; @@ -794,7 +853,7 @@ i830_sdvo_restore(xf86OutputPtr output) i830_sdvo_set_clock_rate_mult(output, dev_priv->save_sdvo_mult); - OUTREG(dev_priv->output_device, dev_priv->save_SDVOX); + i830_sdvo_write_sdvox(output, dev_priv->save_SDVOX); if (dev_priv->save_SDVOX & SDVO_ENABLE) { diff --git a/src/i830_sdvo_regs.h b/src/i830_sdvo_regs.h index 59b2aa89..437ff503 100644 --- a/src/i830_sdvo_regs.h +++ b/src/i830_sdvo_regs.h @@ -307,6 +307,14 @@ struct i830_sdvo_set_target_input_args { #define SDVO_CMD_SET_TV_FORMAT 0x29 +#define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a +#define SDVO_CMD_GET_ENCODER_POWER_STATE 0x2b +#define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c +# define SDVO_ENCODER_STATE_ON (1 << 0) +# define SDVO_ENCODER_STATE_STANDBY (1 << 1) +# define SDVO_ENCODER_STATE_SUSPEND (1 << 2) +# define SDVO_ENCODER_STATE_OFF (1 << 3) + #define SDVO_CMD_SET_TV_RESOLUTION_SUPPORT 0x93 #define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a From 66fdb08c83d353fbe4e917900c54b555c869eb80 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 13 Mar 2007 17:07:10 -0700 Subject: [PATCH 62/82] Refine the i855 LVDS clock code. In particular, p2 is always 14. This gets correct clocks detected on most harware. The SSC is always assumed to be 66Mhz, which may not be true, but we'll fix that when we find example hardware. --- src/i830_debug.c | 13 +++++------ src/i830_display.c | 55 +++++++++++++++++++++++----------------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/i830_debug.c b/src/i830_debug.c index dccaa7ea..7fd94416 100644 --- a/src/i830_debug.c +++ b/src/i830_debug.c @@ -187,25 +187,24 @@ DEBUGSTRING(i830_debug_dpll) } else { Bool is_lvds = (INREG(LVDS) & LVDS_PORT_EN) && (reg == DPLL_B); - if (val & PLL_P2_DIVIDE_BY_4) - p2 = 4; - else - p2 = 2; - if (is_lvds) { mode = "LVDS"; - /* Map the bit number set from (1, 6) to (-1, 4). */ p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> DPLL_FPA01_P1_POST_DIV_SHIFT); + p2 = 14; } else { mode = "DAC/serial"; if (val & PLL_P1_DIVIDE_BY_TWO) { p1 = 2; } else { - /* Map the number in the field to (1, 31) */ + /* Map the number in the field to (3, 33) */ p1 = ((val & DPLL_FPA01_P1_POST_DIV_MASK_I830) >> DPLL_FPA01_P1_POST_DIV_SHIFT) + 2; } + if (val & PLL_P2_DIVIDE_BY_4) + p2 = 4; + else + p2 = 2; } } diff --git a/src/i830_display.c b/src/i830_display.c index a5d8df84..6e64961b 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -85,15 +85,14 @@ typedef struct { #define I8XX_M2_MAX 16 #define I8XX_P_MIN 4 #define I8XX_P_MAX 128 -/* LVDS p1 value can go from 1 to 6, while DAC goes from 2 to 33. These - * values below get 2 added in the clock calculations. - */ -#define I8XX_P1_MIN 0 -#define I8XX_P1_MAX 31 -#define I8XX_P1_LVDS_MIN -1 -#define I8XX_P1_LVDS_MAX 4 -#define I8XX_P2_SLOW 1 /* this is a bit shift amount */ -#define I8XX_P2_FAST 0 /* this is a bit shift amount */ +#define I8XX_P1_MIN 2 +#define I8XX_P1_MAX 33 +#define I8XX_P1_LVDS_MIN 1 +#define I8XX_P1_LVDS_MAX 6 +#define I8XX_P2_SLOW 4 +#define I8XX_P2_FAST 2 +#define I8XX_P2_LVDS_SLOW 14 +#define I8XX_P2_LVDS_FAST 14 /* No fast option */ #define I8XX_P2_SLOW_LIMIT 165000 #define I9XX_DOT_MIN 20000 @@ -149,7 +148,7 @@ static const intel_limit_t intel_limits[] = { .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX }, .p1 = { .min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX }, .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, - .p2_slow = I8XX_P2_FAST, .p2_fast = I8XX_P2_FAST }, + .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, }, { /* INTEL_LIMIT_I9XX_SDVO_DAC */ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, @@ -206,7 +205,7 @@ static const intel_limit_t *intel_limit (xf86CrtcPtr crtc) static void i8xx_clock(int refclk, intel_clock_t *clock) { clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); - clock->p = (clock->p1 + 2) << (clock->p2 + 1); + clock->p = clock->p1 * clock->p2; clock->vco = refclk * clock->m / (clock->n + 2); clock->dot = clock->vco / clock->p; } @@ -797,15 +796,15 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); } else { if (is_lvds) { - /* map (-1 to 4) to ((1 << 0) to (1 << 5)). */ - dpll |= (1 << (clock.p1 + 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; + dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; } else { - if (clock.p1 == 0) + if (clock.p1 == 2) dpll |= PLL_P1_DIVIDE_BY_TWO; else - dpll |= clock.p1 << DPLL_FPA01_P1_POST_DIV_SHIFT; + dpll |= (clock.p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT; + if (clock.p2 == 4) + dpll |= PLL_P2_DIVIDE_BY_4; } - dpll |= clock.p2 << 23; } if (is_tv) @@ -1255,26 +1254,28 @@ i830_crtc_clock_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc) Bool is_lvds = (pipe == 1) && (INREG(LVDS) & LVDS_PORT_EN); if (is_lvds) { - /* Map the bit number set from (1, 6) to (-1, 4). */ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> - DPLL_FPA01_P1_POST_DIV_SHIFT) - 2; - clock.p2 = 0; + DPLL_FPA01_P1_POST_DIV_SHIFT); + clock.p2 = 14; + + if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) + i8xx_clock(66000, &clock); /* XXX: might not be 66MHz */ + else + i8xx_clock(48000, &clock); } else { if (dpll & PLL_P1_DIVIDE_BY_TWO) { - clock.p1 = 0; + clock.p1 = 2; } else { - /* Map the number in the field to (1, 31) */ clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >> - DPLL_FPA01_P1_POST_DIV_SHIFT); + DPLL_FPA01_P1_POST_DIV_SHIFT) + 2; } if (dpll & PLL_P2_DIVIDE_BY_4) - clock.p2 = 1; + clock.p2 = 4; else - clock.p2 = 0; - } + clock.p2 = 2; - /* XXX: Deal with other refclocks */ - i8xx_clock(48000, &clock); + i8xx_clock(48000, &clock); + } } /* XXX: It would be nice to validate the clocks, but we can't reuse From 555b801a75cafa082808bc9bb683e700fc97d79a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 14 Mar 2007 11:41:50 +0100 Subject: [PATCH 63/82] Make sure the legacy texture area is there when needed. This currently only matters when the DRM memory manager is not available and Option "Legacy3D" "off" is specified, but that hasn't always been the case and might change again in the future. --- src/i830.h | 1 + src/i830_dri.c | 10 ++++++++++ src/i830_memory.c | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/i830.h b/src/i830.h index dc8041c5..d4be4034 100644 --- a/src/i830.h +++ b/src/i830.h @@ -591,6 +591,7 @@ void i830_free_3d_memory(ScrnInfoPtr pScrn); void i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem); extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn); Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn); +Bool i830_allocate_texture_memory(ScrnInfoPtr pScrn); Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn); extern Bool I830IsPrimary(ScrnInfoPtr pScrn); diff --git a/src/i830_dri.c b/src/i830_dri.c index 8fae4b7e..b24c8391 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -702,6 +702,16 @@ I830DRIScreenInit(ScreenPtr pScreen) i830_free_memory(pScrn, pI830->memory_manager); pI830->memory_manager = NULL; + + if (!(pI830->mmModeFlags & I830_KERNEL_TEX)) { + pI830->mmModeFlags |= I830_KERNEL_TEX; + + if (!i830_allocate_texture_memory(pScrn)) { + I830DRICloseScreen(pScreen); + drmFreeVersion(version); + return FALSE; + } + } } } #ifdef DAMAGE diff --git a/src/i830_memory.c b/src/i830_memory.c index 0742d8c0..a20e7432 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -1156,7 +1156,7 @@ i830_allocate_depthbuffer(ScrnInfoPtr pScrn) return TRUE; } -static Bool +Bool i830_allocate_texture_memory(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); From 9fbef2de9edbbed9c2f6a80c4074b9b245547c45 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 14 Mar 2007 12:34:34 -0700 Subject: [PATCH 64/82] Bump to 1.9.92 for RC2. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 52cc07bd..451179df 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ AC_PREREQ(2.57) AC_INIT([xf86-video-intel], - 1.9.91, + 1.9.92, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xf86-video-intel) From 8ae6ad93329e2842c6f2d5b20ffeb0c14d10c0de Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 15 Mar 2007 00:00:51 -0700 Subject: [PATCH 65/82] Use new driver-independent CRTC-based cursor layer. This eliminates all of the cursor rotation code and other cursor management infrastructure, leaving a fairly simple hardware layer in its place. --- src/i830.h | 28 +- src/i830_cursor.c | 651 +++++++++++---------------------------------- src/i830_display.c | 7 + src/i830_driver.c | 19 +- 4 files changed, 194 insertions(+), 511 deletions(-) diff --git a/src/i830.h b/src/i830.h index d4be4034..661d27e5 100644 --- a/src/i830.h +++ b/src/i830.h @@ -229,6 +229,7 @@ typedef struct _I830CrtcPrivateRec { i830_memory *cursor_mem; i830_memory *cursor_mem_argb; + Bool cursor_is_argb; } I830CrtcPrivateRec, *I830CrtcPrivatePtr; #define I830CrtcPrivate(c) ((I830CrtcPrivatePtr) (c)->driver_private) @@ -328,9 +329,7 @@ typedef struct _I830Rec { int backPitch; Bool CursorNeedsPhysical; - Bool CursorIsARGB; - CursorPtr pCurs; - + DGAModePtr DGAModes; int numDGAModes; Bool DGAactive; @@ -366,7 +365,6 @@ typedef struct _I830Rec { Bool useEXA; Bool noAccel; Bool SWCursor; - Bool cursorOn; #ifdef I830_USE_XAA XAAInfoRecPtr AccelInfoRec; @@ -382,7 +380,6 @@ typedef struct _I830Rec { int w, int h); void (*xaa_done_composite)(PixmapPtr pDst); #endif - xf86CursorInfoPtr CursorInfoRec; CloseScreenProcPtr CloseScreen; #ifdef I830_USE_EXA @@ -542,6 +539,27 @@ extern void I830EmitInvarientState(ScrnInfoPtr pScrn); extern void I915EmitInvarientState(ScrnInfoPtr pScrn); extern void I830SelectBuffer(ScrnInfoPtr pScrn, int buffer); +/* CRTC-based cursor functions */ +void +i830_crtc_load_cursor_image (xf86CrtcPtr crtc, unsigned char *src); + +#ifdef ARGB_CURSOR +void +i830_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image); +#endif + +void +i830_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y); + +void +i830_crtc_show_cursor (xf86CrtcPtr crtc); + +void +i830_crtc_hide_cursor (xf86CrtcPtr crtc); + +void +i830_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg); + extern void I830RefreshRing(ScrnInfoPtr pScrn); extern void I830EmitFlush(ScrnInfoPtr pScrn); diff --git a/src/i830_cursor.c b/src/i830_cursor.c index 85785112..9cc92dc9 100644 --- a/src/i830_cursor.c +++ b/src/i830_cursor.c @@ -68,17 +68,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "i830.h" -static void I830LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src); -static void I830ShowCursor(ScrnInfoPtr pScrn); -static void I830HideCursor(ScrnInfoPtr pScrn); -static void I830SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb); -static void I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y); -static Bool I830UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs); -#ifdef ARGB_CURSOR -static void I830LoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs); -static Bool I830UseHWCursorARGB(ScreenPtr pScrn, CursorPtr pCurs); -#endif - static void I830SetPipeCursorBase (xf86CrtcPtr crtc) { @@ -86,533 +75,207 @@ I830SetPipeCursorBase (xf86CrtcPtr crtc) I830CrtcPrivatePtr intel_crtc = crtc->driver_private; int pipe = intel_crtc->pipe; I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int cursor_base = (pipe == 0 ? CURSOR_A_BASE : CURSOR_B_BASE); i830_memory *cursor_mem; + CARD32 value; - if (pipe >= xf86_config->num_crtc) - FatalError("Bad pipe number for cursor base setting\n"); - - if (pI830->CursorIsARGB) + if (intel_crtc->cursor_is_argb) cursor_mem = intel_crtc->cursor_mem_argb; else cursor_mem = intel_crtc->cursor_mem; - if (pI830->CursorNeedsPhysical) { - OUTREG(cursor_base, cursor_mem->bus_addr); - } else { - OUTREG(cursor_base, cursor_mem->offset); - } -} - -void -I830SetPipeCursor (xf86CrtcPtr crtc, Bool force) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - int pipe = intel_crtc->pipe; - I830Ptr pI830 = I830PTR(pScrn); - CARD32 temp; - Bool show; + if (pI830->CursorNeedsPhysical) + value = cursor_mem->bus_addr; + else + value = cursor_mem->offset; - if (!crtc->enabled) - return; - - show = pI830->cursorOn && crtc->cursorInRange; - if (show && (force || !crtc->cursorShown)) - { - if (IS_MOBILE(pI830) || IS_I9XX(pI830)) { - int cursor_control; - if (pipe == 0) - cursor_control = CURSOR_A_CONTROL; - else - cursor_control = CURSOR_B_CONTROL; - temp = INREG(cursor_control); - temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); - if (pI830->CursorIsARGB) { - temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; - } else - temp |= CURSOR_MODE_64_4C_AX; - - temp |= (pipe << 28); /* Connect to correct pipe */ - /* Need to set mode, then address. */ - OUTREG(cursor_control, temp); - } else { - temp = INREG(CURSOR_CONTROL); - temp &= ~(CURSOR_FORMAT_MASK); - temp |= CURSOR_ENABLE; - if (pI830->CursorIsARGB) { - temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; - } else - temp |= CURSOR_FORMAT_3C; - OUTREG(CURSOR_CONTROL, temp); - } - crtc->cursorShown = TRUE; - } - else if (!show && (force || crtc->cursorShown)) - { - if (IS_MOBILE(pI830) || IS_I9XX(pI830)) - { - int cursor_control; - if (pipe == 0) - cursor_control = CURSOR_A_CONTROL; - else - cursor_control = CURSOR_B_CONTROL; - temp = INREG(cursor_control); - temp &= ~(CURSOR_MODE|MCURSOR_GAMMA_ENABLE); - temp |= CURSOR_MODE_DISABLE; - OUTREG(cursor_control, temp); - } else { - temp = INREG(CURSOR_CONTROL); - temp &= ~(CURSOR_ENABLE|CURSOR_GAMMA_ENABLE); - OUTREG(CURSOR_CONTROL, temp); - } - crtc->cursorShown = FALSE; - } - - /* Flush cursor changes. */ - I830SetPipeCursorBase(crtc); + OUTREG(cursor_base, value); } void I830InitHWCursor(ScrnInfoPtr pScrn) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - CARD32 temp; - int i; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + I830Ptr pI830 = I830PTR(pScrn); + CARD32 temp; + int i; - DPRINTF(PFX, "I830InitHWCursor\n"); - for (i = 0; i < xf86_config->num_crtc; i++) - xf86_config->crtc[i]->cursorShown = FALSE; + DPRINTF(PFX, "I830InitHWCursor\n"); - /* Initialise the HW cursor registers, leaving the cursor hidden. */ - if (IS_MOBILE(pI830) || IS_I9XX(pI830)) { - for (i = 0; i < xf86_config->num_crtc; i++) - { - int cursor_control = i == 0 ? CURSOR_A_CONTROL : CURSOR_B_CONTROL; - temp = INREG(cursor_control); - temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | - MCURSOR_MEM_TYPE_LOCAL | - MCURSOR_PIPE_SELECT); - temp |= (i << 28); - if (pI830->CursorIsARGB) - temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; - else - temp |= CURSOR_MODE_64_4C_AX; - /* Need to set control, then address. */ - OUTREG(cursor_control, temp); - I830SetPipeCursorBase(xf86_config->crtc[i]); - } - } else { - temp = INREG(CURSOR_CONTROL); - temp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE | - CURSOR_ENABLE | CURSOR_STRIDE_MASK); - if (pI830->CursorIsARGB) - temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; - else - temp |= CURSOR_FORMAT_3C; - /* This initialises the format and leave the cursor disabled. */ - OUTREG(CURSOR_CONTROL, temp); - /* Need to set address and size after disabling. */ - I830SetPipeCursorBase(xf86_config->crtc[0]); - temp = ((I810_CURSOR_X & CURSOR_SIZE_MASK) << CURSOR_SIZE_HSHIFT) | - ((I810_CURSOR_Y & CURSOR_SIZE_MASK) << CURSOR_SIZE_VSHIFT); - OUTREG(CURSOR_SIZE, temp); - } + /* Initialise the HW cursor registers, leaving the cursor hidden. */ + for (i = 0; i < xf86_config->num_crtc; i++) + { + int cursor_control = i == 0 ? CURSOR_A_CONTROL : CURSOR_B_CONTROL; + + temp = INREG(cursor_control); + if (IS_MOBILE(pI830) || IS_I9XX(pI830)) + { + temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | + MCURSOR_MEM_TYPE_LOCAL | + MCURSOR_PIPE_SELECT); + temp |= (i << 28); + temp |= CURSOR_MODE_DISABLE; + } + else + { + temp &= ~(CURSOR_ENABLE|CURSOR_GAMMA_ENABLE); + } + + /* Need to set control, then address. */ + OUTREG(cursor_control, temp); + I830SetPipeCursorBase(xf86_config->crtc[i]); + } } Bool I830CursorInit(ScreenPtr pScreen) { - ScrnInfoPtr pScrn; - I830Ptr pI830; - xf86CursorInfoPtr infoPtr; - - DPRINTF(PFX, "I830CursorInit\n"); - pScrn = xf86Screens[pScreen->myNum]; - pI830 = I830PTR(pScrn); - pI830->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec(); - if (!infoPtr) - return FALSE; - - infoPtr->MaxWidth = I810_CURSOR_X; - infoPtr->MaxHeight = I810_CURSOR_Y; - infoPtr->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | - HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | - HARDWARE_CURSOR_INVERT_MASK | - HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | - HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | - HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | 0); - - infoPtr->SetCursorColors = I830SetCursorColors; - infoPtr->SetCursorPosition = I830SetCursorPosition; - infoPtr->LoadCursorImage = I830LoadCursorImage; - infoPtr->HideCursor = I830HideCursor; - infoPtr->ShowCursor = I830ShowCursor; - infoPtr->UseHWCursor = I830UseHWCursor; -#ifdef ARGB_CURSOR - infoPtr->UseHWCursorARGB = I830UseHWCursorARGB; - infoPtr->LoadCursorARGB = I830LoadCursorARGB; -#endif - - pI830->pCurs = NULL; - - - I830HideCursor(pScrn); - - return xf86InitCursor(pScreen, infoPtr); + return xf86_cursors_init (pScreen, I810_CURSOR_X, I810_CURSOR_Y, + (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | + HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | + HARDWARE_CURSOR_INVERT_MASK | + HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | + HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | + HARDWARE_CURSOR_ARGB)); } -static Bool -I830UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) +void +i830_crtc_load_cursor_image (xf86CrtcPtr crtc, unsigned char *src) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); + ScrnInfoPtr scrn = crtc->scrn; + I830Ptr pI830 = I830PTR(scrn); + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + CARD8 *pcurs = (CARD8 *) (pI830->FbBase + + intel_crtc->cursor_mem->offset); - pI830->pCurs = pCurs; - - return TRUE; + intel_crtc->cursor_is_argb = FALSE; + memcpy (pcurs, src, I810_CURSOR_X * I810_CURSOR_Y / 4); } -static void -I830CRTCLoadCursorImage(xf86CrtcPtr crtc, unsigned char *src) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - CARD8 *pcurs = (CARD8 *) (pI830->FbBase + intel_crtc->cursor_mem->offset); - int x, y; - - DPRINTF(PFX, "I830LoadCursorImage\n"); - #ifdef ARGB_CURSOR - pI830->CursorIsARGB = FALSE; -#endif - - memset(pcurs, 0, 64 * 64 / 4); - -#define GetBit(image, x, y)\ - ((int)((*(image + ((x) / 8) + ((y) * (128/8))) &\ - (1 << ( 7 -((x) % 8) ))) ? 1 : 0)) - -#define SetBit(image, x, y)\ - (*(image + (x) / 8 + (y) * (128/8)) |=\ - (int) (1 << (7-((x) % 8)))) - - switch (crtc->rotation) { - case RR_Rotate_90: - for (y = 0; y < 64; y++) { - for (x = 0; x < 64; x++) { - if (GetBit(src, 64 - y - 1, x)) - SetBit(pcurs, x, y); - if (GetBit(src, 128 - y - 1, x)) - SetBit(pcurs, x + 64, y); - } - } - - return; - case RR_Rotate_180: - for (y = 0; y < 64; y++) { - for (x = 0; x < 64; x++) { - if (GetBit(src, 64 - x - 1, 64 - y - 1)) - SetBit(pcurs, x, y); - if (GetBit(src, 128 - x - 1, 64 - y - 1)) - SetBit(pcurs, x + 64, y); - } - } - - return; - case RR_Rotate_270: - for (y = 0; y < 64; y++) { - for (x = 0; x < 64; x++) { - if (GetBit(src, y, 64 - x - 1)) - SetBit(pcurs, x, y); - if (GetBit(src, y + 64, 64 - x - 1)) - SetBit(pcurs, x + 64, y); - } - } - - return; - } - - for (y = 0; y < 64; y++) { - for (x = 0; x < 64 / 4; x++) { - *pcurs++ = *src++; - } - } -} - -static void -I830LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) +void +i830_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int pipe; + ScrnInfoPtr scrn = crtc->scrn; + I830Ptr pI830 = I830PTR(scrn); + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + CARD32 *pcurs = (CARD32 *) (pI830->FbBase + + intel_crtc->cursor_mem_argb->offset); - for (pipe = 0; pipe < xf86_config->num_crtc; pipe++) { - I830CRTCLoadCursorImage(xf86_config->crtc[pipe], src); + intel_crtc->cursor_is_argb = TRUE; + memcpy (pcurs, image, I810_CURSOR_Y * I810_CURSOR_X * 4); +} +#endif + +void +i830_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y) +{ + ScrnInfoPtr scrn = crtc->scrn; + I830Ptr pI830 = I830PTR(scrn); + I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc); + CARD32 temp; + + temp = 0; + if (x < 0) { + temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT); + x = -x; } -} + if (y < 0) { + temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT); + y = -y; + } + temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT); + temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); -#ifdef ARGB_CURSOR -#include "cursorstr.h" - -static Bool I830UseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; - - DPRINTF(PFX, "I830UseHWCursorARGB\n"); - - pI830->pCurs = pCurs; - - /* Check that our ARGB allocations succeeded */ - for (i = 0; i < xf86_config->num_crtc; i++) { - I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; - - if (intel_crtc->cursor_mem_argb == NULL) - return FALSE; - } - - if (pScrn->bitsPerPixel == 8) - return FALSE; - - if (pCurs->bits->height <= 64 && pCurs->bits->width <= 64) - return TRUE; - - return FALSE; -} - -static void I830CRTCLoadCursorARGB (xf86CrtcPtr crtc, CursorPtr pCurs) -{ - I830Ptr pI830 = I830PTR(crtc->scrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - CARD32 *dst = (CARD32 *) (pI830->FbBase + - intel_crtc->cursor_mem_argb->offset); - CARD32 *image = (CARD32 *)pCurs->bits->argb; - int x, y, w, h; - - DPRINTF(PFX, "I830LoadCursorARGB\n"); - - if (!image) - return; /* XXX can't happen */ + switch (intel_crtc->pipe) { + case 0: + OUTREG(CURSOR_A_POSITION, temp); + break; + case 1: + OUTREG(CURSOR_B_POSITION, temp); + break; + } - pI830->CursorIsARGB = TRUE; - - w = pCurs->bits->width; - h = pCurs->bits->height; - - switch (crtc->rotation) { - case RR_Rotate_90: - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) - dst[(y) + ((64 - x - 1) * 64)] = *image++; - for(; x < 64; x++) - dst[(y) + ((64 - x - 1) * 64)] = 0; - } - for(; y < 64; y++) { - for(x = 0; x < 64; x++) - dst[(y) + ((64 - x - 1) * 64)] = 0; - } - return; - - case RR_Rotate_180: - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) - dst[(64 - x - 1) + ((64 - y - 1) * 64)] = *image++; - for(; x < 64; x++) - dst[(64 - x - 1) + ((64 - y - 1) * 64)] = 0; - } - for(; y < 64; y++) { - for(x = 0; x < 64; x++) - dst[(64 - x - 1) + ((64 - y - 1) * 64)] = 0; - } - return; - - case RR_Rotate_270: - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) - dst[(64 - y - 1) + (x * 64)] = *image++; - for(; x < 64; x++) - dst[(64 - y - 1) + (x * 64)] = 0; - } - for(; y < 64; y++) { - for(x = 0; x < 64; x++) - dst[(64 - y - 1) + (x * 64)] = 0; - } - return; - } - - for(y = 0; y < h; y++) { - for(x = 0; x < w; x++) - *dst++ = *image++; - for(; x < 64; x++) - *dst++ = 0; - } - - for(; y < 64; y++) { - for(x = 0; x < 64; x++) - *dst++ = 0; - } + if (crtc->cursor_shown) + I830SetPipeCursorBase (crtc); } -static void -I830LoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs) +void +i830_crtc_show_cursor (xf86CrtcPtr crtc) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int pipe; - - for (pipe = 0; pipe < xf86_config->num_crtc; pipe++) { - I830CRTCLoadCursorARGB(xf86_config->crtc[pipe], pCurs); - } -} -#endif - -static void -I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - CARD32 temp; - Bool inrange; - int root_x = x, root_y = y; - int pipe; - - root_x = x + pScrn->frameX0; /* undo what xf86HWCurs did */ - root_y = y + pScrn->frameY0; - - for (pipe = 0; pipe < xf86_config->num_crtc; pipe++) + ScrnInfoPtr scrn = crtc->scrn; + I830Ptr pI830 = I830PTR(scrn); + I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc); + int pipe = intel_crtc->pipe; + CARD32 temp; + int cursor_control = (pipe == 0 ? CURSOR_A_CONTROL : + CURSOR_B_CONTROL); + + temp = INREG(cursor_control); + + if (IS_MOBILE(pI830) || IS_I9XX(pI830)) { - xf86CrtcPtr crtc = xf86_config->crtc[pipe]; - DisplayModePtr mode = &crtc->mode; - int thisx = 0; - int thisy = 0; - int hotspotx = 0, hotspoty = 0; + temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); + if (intel_crtc->cursor_is_argb) + temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + else + temp |= CURSOR_MODE_64_4C_AX; - if (!crtc->enabled) - continue; - - switch (crtc->rotation) { - case RR_Rotate_0: - thisx = (root_x - crtc->x); - thisy = (root_y - crtc->y); - break; - case RR_Rotate_90: - thisx = (root_y - crtc->y); - thisy = mode->VDisplay - (root_x - crtc->x); - hotspoty = I810_CURSOR_X; - break; - case RR_Rotate_180: - thisx = mode->HDisplay - (root_x - crtc->x); - thisy = mode->VDisplay - (root_y - crtc->y); - hotspotx = I810_CURSOR_X; - hotspoty = I810_CURSOR_Y; - break; - case RR_Rotate_270: - thisx = mode->HDisplay - (root_y - crtc->y); - thisy = (root_x - crtc->x); - hotspotx = I810_CURSOR_Y; - break; - } - - thisx -= hotspotx; - thisy -= hotspoty; - - /* - * There is a screen display problem when the cursor position is set - * wholely outside of the viewport. We trap that here, turning the - * cursor off when that happens, and back on when it comes back into - * the viewport. - */ - inrange = TRUE; - if (thisx >= mode->HDisplay || - thisy >= mode->VDisplay || - thisx <= -I810_CURSOR_X || thisy <= -I810_CURSOR_Y) - { - inrange = FALSE; - thisx = 0; - thisy = 0; - } - - temp = 0; - if (thisx < 0) { - temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT); - thisx = -thisx; - } - if (thisy < 0) { - temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT); - thisy = -thisy; - } - temp |= ((thisx & CURSOR_POS_MASK) << CURSOR_X_SHIFT); - temp |= ((thisy & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); - - if (pipe == 0) - OUTREG(CURSOR_A_POSITION, temp); - if (pipe == 1) - OUTREG(CURSOR_B_POSITION, temp); - - crtc->cursorInRange = inrange; - - I830SetPipeCursor (crtc, FALSE); + temp |= (pipe << 28); /* Connect to correct pipe */ } + else + { + temp &= ~(CURSOR_FORMAT_MASK); + temp |= CURSOR_ENABLE; + if (intel_crtc->cursor_is_argb) + temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; + else + temp |= CURSOR_FORMAT_3C; + } + + /* Need to set mode, then address. */ + OUTREG(cursor_control, temp); + I830SetPipeCursorBase (crtc); } -static void -I830ShowCursor(ScrnInfoPtr pScrn) +void +i830_crtc_hide_cursor (xf86CrtcPtr crtc) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - int pipe; + ScrnInfoPtr scrn = crtc->scrn; + I830Ptr pI830 = I830PTR(scrn); + I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc); + int pipe = intel_crtc->pipe; + CARD32 temp; + int cursor_control = (pipe == 0 ? CURSOR_A_CONTROL : + CURSOR_B_CONTROL); + + temp = INREG(cursor_control); + + if (IS_MOBILE(pI830) || IS_I9XX(pI830)) + { + temp &= ~(CURSOR_MODE|MCURSOR_GAMMA_ENABLE); + temp |= CURSOR_MODE_DISABLE; + } + else + temp &= ~(CURSOR_ENABLE|CURSOR_GAMMA_ENABLE); - DPRINTF(PFX, "I830ShowCursor\n"); - - pI830->cursorOn = TRUE; - for (pipe = 0; pipe < xf86_config->num_crtc; pipe++) - I830SetPipeCursor (xf86_config->crtc[pipe], TRUE); + /* Need to set mode, then address. */ + OUTREG(cursor_control, temp); + I830SetPipeCursorBase (crtc); } -static void -I830HideCursor(ScrnInfoPtr pScrn) +void +i830_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - int pipe; + ScrnInfoPtr scrn = crtc->scrn; + I830Ptr pI830 = I830PTR(scrn); + I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc); + int pipe = intel_crtc->pipe; + int pal0 = pipe == 0 ? CURSOR_A_PALETTE0 : CURSOR_B_PALETTE0; - DPRINTF(PFX, "I830HideCursor\n"); - - pI830->cursorOn = FALSE; - for (pipe = 0; pipe < xf86_config->num_crtc; pipe++) - I830SetPipeCursor (xf86_config->crtc[pipe], TRUE); -} - -static void -I830SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - int pipe; - -#ifdef ARGB_CURSOR - /* Don't recolour cursors set with SetCursorARGB. */ - if (pI830->CursorIsARGB) - return; -#endif - - DPRINTF(PFX, "I830SetCursorColors\n"); - - for (pipe = 0; pipe < xf86_config->num_crtc; pipe++) - { - xf86CrtcPtr crtc = xf86_config->crtc[pipe]; - int pal0 = pipe == 0 ? CURSOR_A_PALETTE0 : CURSOR_B_PALETTE0; - - if (crtc->enabled) - { - OUTREG(pal0 + 0, bg & 0x00ffffff); - OUTREG(pal0 + 4, fg & 0x00ffffff); - OUTREG(pal0 + 8, fg & 0x00ffffff); - OUTREG(pal0 + 12, bg & 0x00ffffff); - } - } + OUTREG(pal0 + 0, bg & 0x00ffffff); + OUTREG(pal0 + 4, fg & 0x00ffffff); + OUTREG(pal0 + 8, fg & 0x00ffffff); + OUTREG(pal0 + 12, bg & 0x00ffffff); } diff --git a/src/i830_display.c b/src/i830_display.c index 6e64961b..2fc81b98 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -578,6 +578,7 @@ static void i830_crtc_commit (xf86CrtcPtr crtc) { crtc->funcs->dpms (crtc, DPMSModeOn); + xf86_reload_cursors (crtc->scrn->pScreen); } void @@ -1334,6 +1335,12 @@ static const xf86CrtcFuncsRec i830_crtc_funcs = { .shadow_create = i830_crtc_shadow_create, .shadow_allocate = i830_crtc_shadow_allocate, .shadow_destroy = i830_crtc_shadow_destroy, + .set_cursor_colors = i830_crtc_set_cursor_colors, + .set_cursor_position = i830_crtc_set_cursor_position, + .show_cursor = i830_crtc_show_cursor, + .hide_cursor = i830_crtc_hide_cursor, +/* .load_cursor_image = i830_crtc_load_cursor_image, */ + .load_cursor_argb = i830_crtc_load_cursor_argb, .destroy = NULL, /* XXX */ }; diff --git a/src/i830_driver.c b/src/i830_driver.c index 1be9fddf..497a4ab9 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1563,9 +1563,8 @@ ResetState(ScrnInfoPtr pScrn, Bool flush) OUTREG(LP_RING + RING_HEAD, 0); OUTREG(LP_RING + RING_TAIL, 0); OUTREG(LP_RING + RING_START, 0); - - if (pI830->CursorInfoRec && pI830->CursorInfoRec->HideCursor) - pI830->CursorInfoRec->HideCursor(pScrn); + + xf86_hide_cursors (pScrn); } static void @@ -2585,9 +2584,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } - if (!I830EnterVT(scrnIndex, 0)) - return FALSE; - miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); xf86SetSilkenMouse(pScreen); @@ -2601,6 +2597,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } else xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing SW Cursor!\n"); + if (!I830EnterVT(scrnIndex, 0)) + return FALSE; + DPRINTF(PFX, "assert( if(!miCreateDefColormap(pScreen)) )\n"); if (!miCreateDefColormap(pScreen)) return FALSE; @@ -2785,8 +2784,7 @@ I830LeaveVT(int scrnIndex, int flags) } #endif - if (pI830->CursorInfoRec && pI830->CursorInfoRec->HideCursor) - pI830->CursorInfoRec->HideCursor(pScrn); + xf86_hide_cursors (pScrn); ResetState(pScrn, TRUE); @@ -2981,10 +2979,7 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen) pI830->EXADriverPtr = NULL; } #endif - if (pI830->CursorInfoRec) { - xf86DestroyCursorInfoRec(pI830->CursorInfoRec); - pI830->CursorInfoRec = 0; - } + xf86_cursors_fini (pScreen); i830_reset_allocations(pScrn); From 8b06ab50bbd79dfaf4c90a6f76116ace64b85b77 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 15 Mar 2007 10:12:14 -0700 Subject: [PATCH 66/82] Fix sparse warnings about using 0 for NULL. --- src/i810_driver.c | 14 +++++++------- src/i830_driver.c | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/i810_driver.c b/src/i810_driver.c index 6666d7f9..3689446f 100644 --- a/src/i810_driver.c +++ b/src/i810_driver.c @@ -2217,7 +2217,7 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } - fbPictureInit(pScreen, 0, 0); + fbPictureInit(pScreen, NULL, 0); xf86SetBlackWhitePixels(pScreen); @@ -2276,18 +2276,18 @@ I810ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Use driver specific palette load routines for Direct Color support. -jens */ if (pScrn->bitsPerPixel == 16) { if (pScrn->depth == 15) { - if (!xf86HandleColormaps(pScreen, 256, 8, I810LoadPalette15, 0, + if (!xf86HandleColormaps(pScreen, 256, 8, I810LoadPalette15, NULL, CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; } else { - if (!xf86HandleColormaps(pScreen, 256, 8, I810LoadPalette16, 0, + if (!xf86HandleColormaps(pScreen, 256, 8, I810LoadPalette16, NULL, CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; } } else { - if (!xf86HandleColormaps(pScreen, 256, 8, I810LoadPalette24, 0, + if (!xf86HandleColormaps(pScreen, 256, 8, I810LoadPalette24, NULL, CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; @@ -2535,19 +2535,19 @@ I810CloseScreen(int scrnIndex, ScreenPtr pScreen) if (pI810->ScanlineColorExpandBuffers) { xfree(pI810->ScanlineColorExpandBuffers); - pI810->ScanlineColorExpandBuffers = 0; + pI810->ScanlineColorExpandBuffers = NULL; } if (infoPtr) { if (infoPtr->ScanlineColorExpandBuffers) xfree(infoPtr->ScanlineColorExpandBuffers); XAADestroyInfoRec(infoPtr); - pI810->AccelInfoRec = 0; + pI810->AccelInfoRec = NULL; } if (pI810->CursorInfoRec) { xf86DestroyCursorInfoRec(pI810->CursorInfoRec); - pI810->CursorInfoRec = 0; + pI810->CursorInfoRec = NULL; } /* Free all allocated video ram. diff --git a/src/i830_driver.c b/src/i830_driver.c index 497a4ab9..5650faf5 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -555,7 +555,7 @@ I830UnmapMMIO(ScrnInfoPtr pScrn) xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI830->MMIOBase, I810_REG_SIZE); - pI830->MMIOBase = 0; + pI830->MMIOBase = NULL; } static Bool @@ -565,7 +565,7 @@ I830UnmapMem(ScrnInfoPtr pScrn) xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI830->FbBase, pI830->FbMapSize); - pI830->FbBase = 0; + pI830->FbBase = NULL; I830UnmapMMIO(pScrn); return TRUE; } @@ -903,7 +903,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } else pI830->entityPrivate = NULL; - if (xf86RegisterResources(pI830->pEnt->index, 0, ResNone)) { + if (xf86RegisterResources(pI830->pEnt->index, NULL, ResNone)) { PreInitCleanup(pScrn); return FALSE; } @@ -2568,7 +2568,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } } - fbPictureInit(pScreen, 0, 0); + fbPictureInit(pScreen, NULL, 0); xf86SetBlackWhitePixels(pScreen); @@ -2605,7 +2605,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) return FALSE; DPRINTF(PFX, "assert( if(!xf86HandleColormaps(pScreen, ...)) )\n"); - if (!xf86HandleColormaps(pScreen, 256, 8, I830LoadPalette, 0, + if (!xf86HandleColormaps(pScreen, 256, 8, I830LoadPalette, NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)) { return FALSE; @@ -2962,7 +2962,7 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen) if (pI830->ScanlineColorExpandBuffers) { xfree(pI830->ScanlineColorExpandBuffers); - pI830->ScanlineColorExpandBuffers = 0; + pI830->ScanlineColorExpandBuffers = NULL; } #ifdef I830_USE_XAA if (infoPtr) { From 316ee682d342556b65cbd60409201591e916aac5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 15 Mar 2007 18:53:55 -0700 Subject: [PATCH 67/82] Don't reload the cursors if we haven't set up the screen yet. This avoids a crash during preinit if we set a mode for load detecting. --- src/i830_display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i830_display.c b/src/i830_display.c index 2fc81b98..98137a22 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -578,7 +578,8 @@ static void i830_crtc_commit (xf86CrtcPtr crtc) { crtc->funcs->dpms (crtc, DPMSModeOn); - xf86_reload_cursors (crtc->scrn->pScreen); + if (crtc->scrn->pScreen != NULL) + xf86_reload_cursors (crtc->scrn->pScreen); } void From 213394fbaaf353404cbb3aaa4c20860f48ee1079 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 15 Mar 2007 19:13:28 -0700 Subject: [PATCH 68/82] Fix crashes and other failures when a cursor allocation fails. Now, we allocate one single block of memory for cursors, and either succeed or fail once, rather than trying to support partial fallback modes that generally resulted in pain due to being untested. In particular, this fixes cursors on FreeBSD, which only allowed one large physically-contiguous allocation. --- src/i830.h | 11 ++++- src/i830_cursor.c | 35 +++++++--------- src/i830_memory.c | 105 +++++++++++++++++++--------------------------- 3 files changed, 65 insertions(+), 86 deletions(-) diff --git a/src/i830.h b/src/i830.h index 661d27e5..f8416dec 100644 --- a/src/i830.h +++ b/src/i830.h @@ -227,8 +227,14 @@ typedef struct _I830CrtcPrivateRec { ExaOffscreenArea *rotate_mem_exa; #endif - i830_memory *cursor_mem; - i830_memory *cursor_mem_argb; + /* Card virtual address of the cursor */ + unsigned long cursor_offset; + unsigned long cursor_argb_offset; + /* Physical or virtual addresses of the cursor for setting in the cursor + * registers. + */ + unsigned long cursor_addr; + unsigned long cursor_argb_addr; Bool cursor_is_argb; } I830CrtcPrivateRec, *I830CrtcPrivatePtr; @@ -276,6 +282,7 @@ typedef struct _I830Rec { i830_memory *front_buffer; i830_memory *front_buffer_2; + i830_memory *cursor_mem; i830_memory *xaa_scratch; i830_memory *xaa_scratch_2; #ifdef I830_USE_EXA diff --git a/src/i830_cursor.c b/src/i830_cursor.c index 9cc92dc9..dec619fe 100644 --- a/src/i830_cursor.c +++ b/src/i830_cursor.c @@ -75,21 +75,14 @@ I830SetPipeCursorBase (xf86CrtcPtr crtc) I830CrtcPrivatePtr intel_crtc = crtc->driver_private; int pipe = intel_crtc->pipe; I830Ptr pI830 = I830PTR(pScrn); - int cursor_base = (pipe == 0 ? CURSOR_A_BASE : CURSOR_B_BASE); - i830_memory *cursor_mem; - CARD32 value; + int cursor_base; - if (intel_crtc->cursor_is_argb) - cursor_mem = intel_crtc->cursor_mem_argb; - else - cursor_mem = intel_crtc->cursor_mem; - - if (pI830->CursorNeedsPhysical) - value = cursor_mem->bus_addr; - else - value = cursor_mem->offset; + cursor_base = (pipe == 0) ? CURSOR_A_BASE : CURSOR_B_BASE; - OUTREG(cursor_base, value); + if (intel_crtc->cursor_is_argb) + OUTREG(cursor_base, intel_crtc->cursor_argb_addr); + else + OUTREG(cursor_base, intel_crtc->cursor_addr); } void @@ -143,11 +136,11 @@ I830CursorInit(ScreenPtr pScreen) void i830_crtc_load_cursor_image (xf86CrtcPtr crtc, unsigned char *src) { - ScrnInfoPtr scrn = crtc->scrn; - I830Ptr pI830 = I830PTR(scrn); + I830Ptr pI830 = I830PTR(crtc->scrn); I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - CARD8 *pcurs = (CARD8 *) (pI830->FbBase + - intel_crtc->cursor_mem->offset); + CARD8 *pcurs; + + pcurs = pI830->FbBase + intel_crtc->cursor_offset; intel_crtc->cursor_is_argb = FALSE; memcpy (pcurs, src, I810_CURSOR_X * I810_CURSOR_Y / 4); @@ -157,11 +150,11 @@ i830_crtc_load_cursor_image (xf86CrtcPtr crtc, unsigned char *src) void i830_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) { - ScrnInfoPtr scrn = crtc->scrn; - I830Ptr pI830 = I830PTR(scrn); + I830Ptr pI830 = I830PTR(crtc->scrn); I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - CARD32 *pcurs = (CARD32 *) (pI830->FbBase + - intel_crtc->cursor_mem_argb->offset); + CARD32 *pcurs; + + pcurs = pI830->FbBase + intel_crtc->cursor_argb_offset; intel_crtc->cursor_is_argb = TRUE; memcpy (pcurs, image, I810_CURSOR_Y * I810_CURSOR_X * 4); diff --git a/src/i830_memory.c b/src/i830_memory.c index a20e7432..440618a5 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -62,10 +62,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * The allocations we might do: * * - Ring buffer - * - HW cursor 1 - * - HW cursor 2 - * - HW ARGB cursor 1 - * - HW ARGB cursor 2 + * - HW cursor block * - Overlay registers * - XAA linear allocator (optional) * - EXA 965 state buffer @@ -214,8 +211,6 @@ void i830_reset_allocations(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; /* While there is any memory between the start and end markers, free it. */ while (pI830->memory_list->next->next != NULL) @@ -224,13 +219,7 @@ i830_reset_allocations(ScrnInfoPtr pScrn) /* Null out the pointers for all the allocations we just freed. This is * kind of gross, but at least it's just one place now. */ - for (i = 0; i < xf86_config->num_crtc; i++) { - I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private; - - intel_crtc->cursor_mem = NULL; - intel_crtc->cursor_mem_argb = NULL; - } - + pI830->cursor_mem = NULL; pI830->front_buffer = NULL; pI830->front_buffer_2 = NULL; pI830->xaa_scratch = NULL; @@ -849,51 +838,51 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, } static Bool -i830_allocate_cursor_buffers(xf86CrtcPtr crtc) +i830_allocate_cursor_buffers(ScrnInfoPtr pScrn) { - ScrnInfoPtr pScrn = crtc->scrn; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; I830Ptr pI830 = I830PTR(pScrn); - long size; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0; + int i; + long size; - if (pI830->SWCursor) - return FALSE; - - /* Mouse cursor -- The i810-i830 need a physical address in system - * memory from which to upload the cursor. We get this from - * the agpgart module using a special memory type. + /* Try to allocate one big blob for our cursor memory. This works + * around a limitation in the FreeBSD AGP driver that allows only one + * physical allocation larger than a page, and could allos us + * to pack the cursors smaller. */ + size = xf86_config->num_crtc * (HWCURSOR_SIZE + HWCURSOR_SIZE_ARGB); - size = HWCURSOR_SIZE; + pI830->cursor_mem = i830_allocate_memory(pScrn, "HW cursors", + size, GTT_PAGE_SIZE, + flags); + if (pI830->cursor_mem != NULL) { + unsigned long cursor_offset_base = pI830->cursor_mem->offset; + unsigned long cursor_addr_base, offset = 0; - if (intel_crtc->cursor_mem == NULL) { - intel_crtc->cursor_mem = i830_allocate_memory(pScrn, "HW cursor", - size, GTT_PAGE_SIZE, - flags); - if (intel_crtc->cursor_mem == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate HW cursor space.\n"); - return FALSE; + if (pI830->CursorNeedsPhysical) + cursor_addr_base = pI830->cursor_mem->bus_addr; + else + cursor_addr_base = pI830->cursor_mem->offset; + + /* Set up the offsets for our cursors in each CRTC. */ + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + + intel_crtc->cursor_argb_addr = cursor_addr_base + offset; + intel_crtc->cursor_argb_offset = cursor_offset_base + offset; + offset += HWCURSOR_SIZE_ARGB; + + intel_crtc->cursor_addr = cursor_addr_base + offset; + intel_crtc->cursor_offset = cursor_offset_base + offset; + offset += HWCURSOR_SIZE; } + + return TRUE; } - if (intel_crtc->cursor_mem_argb == NULL) { - /* Allocate the ARGB cursor space. Its success is optional -- we won't - * set SWCursor if it fails. - */ - intel_crtc->cursor_mem_argb = i830_allocate_memory(pScrn, - "HW ARGB cursor", - HWCURSOR_SIZE_ARGB, - GTT_PAGE_SIZE, - flags); - if (intel_crtc->cursor_mem_argb == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate HW (ARGB) cursor space.\n"); - } - } - - return TRUE; + return FALSE; } /* @@ -904,10 +893,8 @@ Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); unsigned int pitch = pScrn->displayWidth * pI830->cpp; long size; - int i; if (!pI830->StolenOnly && (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex))) { @@ -923,19 +910,11 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) i830_allocate_ringbuffer(pScrn); /* Next, allocate other fixed-size allocations we have. */ - if (!pI830->SWCursor) { - /* Allocate cursor memory */ - for (i = 0; i < xf86_config->num_crtc; i++) { - if (!i830_allocate_cursor_buffers(xf86_config->crtc[i]) && - !pI830->SWCursor) - { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Disabling HW cursor because the cursor memory " - "allocation failed.\n"); - pI830->SWCursor = TRUE; - break; - } - } + if (!pI830->SWCursor && !i830_allocate_cursor_buffers(pScrn)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Disabling HW cursor because the cursor memory " + "allocation failed.\n"); + pI830->SWCursor = TRUE; } /* Space for the X Server's 3D context. 32k is fine for right now. */ From 29446cdb4f72e12c5249b0d4b79ea56d9fe19934 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 16 Mar 2007 19:18:37 -0700 Subject: [PATCH 69/82] Fix compile failure due to needed types being in inttypes.h on Linux. --- src/reg_dumper/reg_dumper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reg_dumper/reg_dumper.h b/src/reg_dumper/reg_dumper.h index a52d6622..07ddf6fd 100644 --- a/src/reg_dumper/reg_dumper.h +++ b/src/reg_dumper/reg_dumper.h @@ -25,7 +25,7 @@ * */ -#include +#include #include #include #include From a117bc9e3eb824f2056ee6416859ea3ab1fdcc30 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 16 Mar 2007 19:39:34 -0700 Subject: [PATCH 70/82] Add the (afaict) correct ch7017 I2C slave address. --- src/i830_dvo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_dvo.c b/src/i830_dvo.c index 629e9c7d..04750e5d 100644 --- a/src/i830_dvo.c +++ b/src/i830_dvo.c @@ -72,7 +72,7 @@ struct _I830DVODriver i830_dvo_drivers[] = */ /* { I830_DVO_CHIP_LVDS, "ch7017", "ch7017_methods", - (CH7017_ADDR_1 << 1), ch7017_symbols, NULL, NULL, NULL } + 0xea, ch7017_symbols, NULL, NULL, NULL } */ }; From 9d6d9ace4bd3180a4484321c3b96a83bc4adaf84 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 16 Mar 2007 19:41:54 -0700 Subject: [PATCH 71/82] Move vendor ID check in the utils to after pci_device_probe. Even current libpciaccess seems to require this. --- src/bios_reader/bios_dumper.c | 6 +++--- src/reg_dumper/main.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bios_reader/bios_dumper.c b/src/bios_reader/bios_dumper.c index 071419bc..c0dbdcf8 100644 --- a/src/bios_reader/bios_dumper.c +++ b/src/bios_reader/bios_dumper.c @@ -60,15 +60,15 @@ int main(int argc, char **argv) if (dev == NULL) errx(1, "Couldn't find graphics card"); - if (dev->vendor_id != 0x8086) - errx(1, "Graphics card is non-intel"); - err = pci_device_probe(dev); if (err != 0) { fprintf(stderr, "Couldn't probe graphics card: %s\n", strerror(err)); exit(1); } + if (dev->vendor_id != 0x8086) + errx(1, "Graphics card is non-intel"); + bios = malloc(dev->rom_size); if (bios == NULL) errx(1, "Couldn't allocate memory for BIOS data\n"); diff --git a/src/reg_dumper/main.c b/src/reg_dumper/main.c index 50c79236..b3c50dee 100644 --- a/src/reg_dumper/main.c +++ b/src/reg_dumper/main.c @@ -52,15 +52,15 @@ int main(int argc, char **argv) if (dev == NULL) errx(1, "Couldn't find graphics card"); - if (dev->vendor_id != 0x8086) - errx(1, "Graphics card is non-intel"); - err = pci_device_probe(dev); if (err != 0) { fprintf(stderr, "Couldn't probe graphics card: %s\n", strerror(err)); exit(1); } + if (dev->vendor_id != 0x8086) + errx(1, "Graphics card is non-intel"); + i830.PciInfo = &i830.pci_info_rec; i830.PciInfo->chipType = dev->device_id; From a58befe9d243bd562cb4b2f08ec5c9f754148c20 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Mar 2007 17:12:37 -0700 Subject: [PATCH 72/82] Remove extra (and incorrect) I2C ByteTimeout setting. Setting the value correctly and then immediately breaking it caused many I2C transactions to timeout with slow monitors. Oops. --- src/i830_i2c.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i830_i2c.c b/src/i830_i2c.c index 319e8dab..08ff522e 100644 --- a/src/i830_i2c.c +++ b/src/i830_i2c.c @@ -368,10 +368,14 @@ I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name) /* Assume all busses are used for DDCish stuff */ + /* + * These were set incorrectly in the server pre-1.3, Having + * duplicate settings is sub-optimal, but this lets the driver + * work with older servers + */ pI2CBus->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */ pI2CBus->StartTimeout = 550; pI2CBus->BitTimeout = 40; - pI2CBus->ByteTimeout = 40; pI2CBus->AcknTimeout = 40; if (!xf86I2CBusInit(pI2CBus)) From 44d1b544cec2e75735d2e27d66a9240317b962c2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Mar 2007 17:15:43 -0700 Subject: [PATCH 73/82] Build fix for pre-XF86DRI_MM environments. Misplaced brace broke builds with older DRM libraries. --- src/i830_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_driver.c b/src/i830_driver.c index 5650faf5..c6aea5cf 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1280,8 +1280,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) "\tfor the DRM memory manager.\n", pI830->mmSize); } - } #endif + } #endif From d05bb5362e986c9d27bc03c7e1a939ba28824810 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Mar 2007 20:21:59 -0700 Subject: [PATCH 74/82] Increase DDC I2C RiseFallTime to handle older monitors Changing this value slows the entire I2C bus down, making it far more reliable on older monitors. Note the same change has been made in the core X server code; this change is included here to ensure that older X servers work reliably with this driver. --- src/i830_i2c.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/i830_i2c.c b/src/i830_i2c.c index 08ff522e..da8f38e6 100644 --- a/src/i830_i2c.c +++ b/src/i830_i2c.c @@ -377,6 +377,7 @@ I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name) pI2CBus->StartTimeout = 550; pI2CBus->BitTimeout = 40; pI2CBus->AcknTimeout = 40; + pI2CBus->RiseFallTime = 20; if (!xf86I2CBusInit(pI2CBus)) return FALSE; From 05e0021147a89254182c277007236448f315231c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Mar 2007 21:31:04 -0700 Subject: [PATCH 75/82] Cast ARGB cursor address to CARD32 * to eliminate warning. While we're just doing a memcpy, it's nice for the two argument types to match. --- src/i830_cursor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i830_cursor.c b/src/i830_cursor.c index dec619fe..d97b2462 100644 --- a/src/i830_cursor.c +++ b/src/i830_cursor.c @@ -154,7 +154,7 @@ i830_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) I830CrtcPrivatePtr intel_crtc = crtc->driver_private; CARD32 *pcurs; - pcurs = pI830->FbBase + intel_crtc->cursor_argb_offset; + pcurs = (CARD32 *) (pI830->FbBase + intel_crtc->cursor_argb_offset); intel_crtc->cursor_is_argb = TRUE; memcpy (pcurs, image, I810_CURSOR_Y * I810_CURSOR_X * 4); From 62a5399d70ac3f8579441d617f8d80c94942a32a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Mar 2007 21:32:36 -0700 Subject: [PATCH 76/82] Elide I830DRIClipNotify for older DRI versions. I830DRIClipNotify is passed to newer versions of DRI; don't include it in the server when building against older versions. --- src/i830_dri.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index b24c8391..0fcce58c 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -126,7 +126,14 @@ static void I830DRITransitionTo2d(ScreenPtr pScreen); static void I830DRITransitionTo3d(ScreenPtr pScreen); static void I830DRITransitionMultiToSingle3d(ScreenPtr pScreen); static void I830DRITransitionSingleToMulti3d(ScreenPtr pScreen); +#if DRIINFO_MAJOR_VERSION > 5 || \ + (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1) +#define DRI_SUPPORTS_CLIP_NOTIFY 1 +#endif + +#ifdef DRI_SUPPORTS_CLIP_NOTIFY static void I830DRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num); +#endif extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig * configs, @@ -576,8 +583,7 @@ I830DRIScreenInit(ScreenPtr pScreen) if (minor >= 1) #endif -#if DRIINFO_MAJOR_VERSION > 5 || \ - (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1) +#if DRI_SUPPORTS_CLIP_NOTIFY pDRIInfo->ClipNotify = I830DRIClipNotify; #endif } @@ -1547,6 +1553,7 @@ I830DRITransitionTo2d(ScreenPtr pScreen) sPriv->pf_enabled = 0; } +#if DRI_SUPPORTS_CLIP_NOTIFY static void I830DRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num) { @@ -1595,7 +1602,7 @@ I830DRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num) I830DRISetPfMask(pScreen, pfMask); } - +#endif /* DRI_SUPPORTS_CLIP_NOTIFY */ /** * Update the SAREA fields with the most recent values. From 9118122a232d4cf7760bcb0874fe970c25251378 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Mar 2007 21:34:03 -0700 Subject: [PATCH 77/82] Allocate 4 separate buffers for HW Cursors on Linux. Linux cannot allocate a large fixed buffer for the HW cursors as needed for FreeBSD; instead, allocate four separate buffers. The code now prefers to allocate one buffer (less overhead) and falls back to separate buffers only when necessary. --- src/i830.h | 5 ++++- src/i830_memory.c | 49 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/i830.h b/src/i830.h index f8416dec..e75eb89a 100644 --- a/src/i830.h +++ b/src/i830.h @@ -226,7 +226,6 @@ typedef struct _I830CrtcPrivateRec { #ifdef I830_USE_EXA ExaOffscreenArea *rotate_mem_exa; #endif - /* Card virtual address of the cursor */ unsigned long cursor_offset; unsigned long cursor_argb_offset; @@ -282,7 +281,11 @@ typedef struct _I830Rec { i830_memory *front_buffer; i830_memory *front_buffer_2; + /* One big buffer for all cursors for kernels that support this */ i830_memory *cursor_mem; + /* separate small buffers for kernels that support this */ + i830_memory *cursor_mem_classic[2]; + i830_memory *cursor_mem_argb[2]; i830_memory *xaa_scratch; i830_memory *xaa_scratch_2; #ifdef I830_USE_EXA diff --git a/src/i830_memory.c b/src/i830_memory.c index 440618a5..b26dd00c 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -62,7 +62,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * The allocations we might do: * * - Ring buffer - * - HW cursor block + * - HW cursor block (either one block or four) * - Overlay registers * - XAA linear allocator (optional) * - EXA 965 state buffer @@ -211,6 +211,7 @@ void i830_reset_allocations(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); + int p; /* While there is any memory between the start and end markers, free it. */ while (pI830->memory_list->next->next != NULL) @@ -220,6 +221,10 @@ i830_reset_allocations(ScrnInfoPtr pScrn) * kind of gross, but at least it's just one place now. */ pI830->cursor_mem = NULL; + for (p = 0; p < 2; p++) { + pI830->cursor_mem_classic[p] = NULL; + pI830->cursor_mem_argb[p] = NULL; + } pI830->front_buffer = NULL; pI830->front_buffer_2 = NULL; pI830->xaa_scratch = NULL; @@ -882,7 +887,47 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn) return TRUE; } - return FALSE; + /* + * Allocate four separate buffers when the kernel doesn't support + * large allocations as on Linux. If any of these fail, just + * bail back to software cursors everywhere + */ + for (i = 0; i < xf86_config->num_crtc; i++) + { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + I830CrtcPrivatePtr intel_crtc = crtc->driver_private; + + pI830->cursor_mem_classic[i] = i830_allocate_memory (pScrn, + "Core cursor", + HWCURSOR_SIZE, + GTT_PAGE_SIZE, + flags); + if (!pI830->cursor_mem_classic[i]) + return FALSE; + pI830->cursor_mem_argb[i] = i830_allocate_memory (pScrn, "ARGB cursor", + HWCURSOR_SIZE_ARGB, + GTT_PAGE_SIZE, + flags); + if (!pI830->cursor_mem_argb[i]) + return FALSE; + + /* + * Set up the pointers into the allocations + */ + if (pI830->CursorNeedsPhysical) + { + intel_crtc->cursor_addr = pI830->cursor_mem_classic[i]->bus_addr; + intel_crtc->cursor_argb_addr = pI830->cursor_mem_argb[i]->bus_addr; + } + else + { + intel_crtc->cursor_addr = pI830->cursor_mem_classic[i]->offset; + intel_crtc->cursor_argb_addr = pI830->cursor_mem_argb[i]->offset; + } + intel_crtc->cursor_offset = pI830->cursor_mem_classic[i]->offset; + intel_crtc->cursor_argb_offset = pI830->cursor_mem_argb[i]->offset; + } + return TRUE; } /* From 991719c21a6cc1b5d9b7cbe30d4b333718b3e686 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 18 Mar 2007 23:05:33 -0700 Subject: [PATCH 78/82] Make i830_sdvo_write_sdvox write everything twice. For some reason, certain chips don't correctly enable the SDVO hardware when this register is written only once. We're following what the BIOS code does and writing it twice now, but with extra posting reads to boot. Yes, this is cult-and-paste, but it fixes problems found on deployed hardware. --- src/i830_sdvo.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c index fb6a7c88..b67ecbc4 100644 --- a/src/i830_sdvo.c +++ b/src/i830_sdvo.c @@ -90,12 +90,26 @@ static void i830_sdvo_write_sdvox(xf86OutputPtr output, CARD32 val) I830OutputPrivatePtr intel_output = output->driver_private; struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; I830Ptr pI830 = I830PTR(pScrn); + CARD32 bval = val, cval = val; + int i; - if (dev_priv->output_device == SDVOC) - OUTREG(SDVOB, INREG(SDVOB)); - OUTREG(dev_priv->output_device, val); if (dev_priv->output_device == SDVOB) - OUTREG(SDVOC, INREG(SDVOC)); + cval = INREG(SDVOC); + else + bval = INREG(SDVOB); + + /* + * Write the registers twice for luck. Sometimes, + * writing them only once doesn't appear to 'stick'. + * The BIOS does this too. Yay, magic + */ + for (i = 0; i < 2; i++) + { + OUTREG(SDVOB, bval); + POSTING_READ(SDVOB); + OUTREG(SDVOC, cval); + POSTING_READ(SDVOC); + } } /** Read a single byte from the given address on the SDVO device. */ @@ -740,7 +754,6 @@ i830_sdvo_dpms(xf86OutputPtr output, int mode) temp = INREG(dev_priv->output_device); if ((temp & SDVO_ENABLE) != 0) { i830_sdvo_write_sdvox(output, temp & ~SDVO_ENABLE); - POSTING_READ(dev_priv->output_device); } } } else { @@ -750,19 +763,7 @@ i830_sdvo_dpms(xf86OutputPtr output, int mode) temp = INREG(dev_priv->output_device); if ((temp & SDVO_ENABLE) == 0) - { i830_sdvo_write_sdvox(output, temp | SDVO_ENABLE); - POSTING_READ(dev_priv->output_device); -#if 0 - /* Do it again! If we remove this below register write, or the - * exact same one 2 lines up, the mac mini SDVO output doesn't - * turn on. - */ - i830_sdvo_write_sdvox(output, INREG(dev_priv->output_device) | - SDVO_ENABLE); - POSTING_READ(dev_priv->output_device); -#endif - } for (i = 0; i < 2; i++) i830WaitForVblank(pScrn); From c21b88d838fda1f00f6f6bcfe7855d32543c6f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 19 Mar 2007 10:45:58 +0100 Subject: [PATCH 79/82] Fix build when DAMAGE is not defined. --- src/i830_dri.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/i830_dri.c b/src/i830_dri.c index 0fcce58c..ccc1faca 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -126,8 +126,8 @@ static void I830DRITransitionTo2d(ScreenPtr pScreen); static void I830DRITransitionTo3d(ScreenPtr pScreen); static void I830DRITransitionMultiToSingle3d(ScreenPtr pScreen); static void I830DRITransitionSingleToMulti3d(ScreenPtr pScreen); -#if DRIINFO_MAJOR_VERSION > 5 || \ - (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1) +#if defined(DAMAGE) && (DRIINFO_MAJOR_VERSION > 5 || \ + (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1)) #define DRI_SUPPORTS_CLIP_NOTIFY 1 #endif @@ -576,7 +576,8 @@ I830DRIScreenInit(ScreenPtr pScreen) pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; { -#if DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1 +#if DRI_SUPPORTS_CLIP_NOTIFY && DRIINFO_MAJOR_VERSION == 5 && \ + DRIINFO_MINOR_VERSION >= 1 int major, minor, patch; DRIQueryVersion(&major, &minor, &patch); @@ -1200,7 +1201,9 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType, } else if (syncType == DRI_2D_SYNC && oldContextType == DRI_NO_CONTEXT && newContextType == DRI_2D_CONTEXT) { +#ifdef DAMAGE drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); +#endif if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("i830DRISwapContext (out)\n"); From 3ce802414a20ca8af128a00e6925a099dd90ceb4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 19 Mar 2007 11:35:11 -0700 Subject: [PATCH 80/82] Add debug output for ADPA. --- src/i830_debug.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/i830_debug.c b/src/i830_debug.c index 7fd94416..c746d35d 100644 --- a/src/i830_debug.c +++ b/src/i830_debug.c @@ -254,6 +254,17 @@ DEBUGSTRING(i830_debug_dpll_test) dpllbndiv, dpllbmdiv, dpllbinput); } +DEBUGSTRING(i830_debug_adpa) +{ + char pipe = (val & ADPA_PIPE_B_SELECT) ? 'B' : 'A'; + char *enable = (val & ADPA_DAC_ENABLE) ? "enabled" : "disabled"; + char hsync = (val & ADPA_HSYNC_ACTIVE_HIGH) ? '+' : '-'; + char vsync = (val & ADPA_VSYNC_ACTIVE_HIGH) ? '+' : '-'; + + return XNFprintf("%s, pipe %c, %chsync, %cvsync", + enable, pipe, hsync, vsync); +} + DEBUGSTRING(i830_debug_lvds) { char pipe = val & LVDS_PIPEB_SELECT ? 'B' : 'A'; @@ -313,7 +324,7 @@ static struct i830SnapshotRec { DEFINEREG(DSPFW2), DEFINEREG(DSPFW3), - DEFINEREG(ADPA), + DEFINEREG2(ADPA, i830_debug_adpa), DEFINEREG2(LVDS, i830_debug_lvds), DEFINEREG(DVOA), DEFINEREG(DVOB), From 64c14204453bea3f98d19861c450612e718e6c69 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 19 Mar 2007 13:35:43 -0700 Subject: [PATCH 81/82] Print the mode actually being set per pipe. --- src/i830_display.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/i830_display.c b/src/i830_display.c index 98137a22..faa3781e 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -870,8 +870,17 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, if (i830_panel_fitter_pipe (pI830) == pipe) OUTREG(PFIT_CONTROL, 0); +#if 1 + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); + xf86PrintModeline(pScrn->scrnIndex, mode); + if (!xf86ModesEqual(mode, adjusted_mode)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Adjusted mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); + xf86PrintModeline(pScrn->scrnIndex, mode); + } i830PrintPll("chosen", &clock); - ErrorF("clock regs: 0x%08x, 0x%08x\n", (int)dpll, (int)fp); +#endif if (dpll & DPLL_VCO_ENABLE) { From 4c4faf260eb4dad1b1919c6168fa9ef477b98a39 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 19 Mar 2007 13:36:37 -0700 Subject: [PATCH 82/82] Set the CURSOR_SIZE register when present. Failure to do so gets you a lot of pretty colors. --- src/i830_cursor.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/i830_cursor.c b/src/i830_cursor.c index d97b2462..667b0a6c 100644 --- a/src/i830_cursor.c +++ b/src/i830_cursor.c @@ -95,6 +95,9 @@ I830InitHWCursor(ScrnInfoPtr pScrn) DPRINTF(PFX, "I830InitHWCursor\n"); + if (!IS_I9XX(pI830)) + OUTREG(CURSOR_SIZE, (I810_CURSOR_Y << 12) | I810_CURSOR_X); + /* Initialise the HW cursor registers, leaving the cursor hidden. */ for (i = 0; i < xf86_config->num_crtc; i++) {