xf86-video-intel: 14 commits - man/intel.man src/i830_display.c src/i830_driver.c src/i830.h src/i830_memory.c src/i830_reg.h src/i915_render.c src/i915_video.c

Jesse Barnes jbarnes at kemper.freedesktop.org
Fri Jul 6 15:52:13 PDT 2007


 man/intel.man      |   12 +++++
 src/i830.h         |   27 ++++++++++++
 src/i830_display.c |  113 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/i830_driver.c  |   52 +++++++++++++++++++++---
 src/i830_memory.c  |   76 ++++++++++++++++++++++++++++++++---
 src/i830_reg.h     |   24 +++++++++++
 src/i915_render.c  |    2 
 src/i915_video.c   |    8 +--
 8 files changed, 296 insertions(+), 18 deletions(-)

New commits:
diff-tree b426866fe1be2ad3861559beff69186379a6afad (from 377c58373daa6bef5d37ead2b6f9a769a905b6fa)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Jul 6 20:48:40 2007 -0700

    Fix manpage to reflect default behavior.

diff --git a/man/intel.man b/man/intel.man
index 8bd3f28..33dc319 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -80,12 +80,12 @@ This option controls whether the framebu
 If possible, the front buffer will be allocated in a tiled format and compressed
 periodically to save memory bandwidth and power.
 This option is only available on mobile chipsets.
-Default: disabled.
+Default: enabled on supported configurations.
 .TP
 .BI "Option \*qTiling\*q \*q" boolean \*q
 This option controls whether memory buffers are allocated in tiled mode.  In
 many cases (especially for complex rendering), tiling can improve performance.
-Default: enabled.
+Default: enabled on supported configurations.
 .TP
 .BI "Option \*qDRI\*q \*q" boolean \*q
 Disable or enable DRI support.
diff-tree 377c58373daa6bef5d37ead2b6f9a769a905b6fa (from 9c0388dc8d4c6495fae21af6da644b34e20173d1)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Jul 6 20:39:19 2007 -0700

    Fix naming of FBC plane enable bits (mistakenly called them pipes earlier).

diff --git a/src/i830_display.c b/src/i830_display.c
index dc52c0b..853f4e4 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -661,13 +661,13 @@ i830_use_fb_compression(xf86CrtcPtr crtc
     I830Ptr pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
     int pipe = intel_crtc->pipe;
-    int plane = (pipe == 0 ? FBC_CTL_PIPEA : FBC_CTL_PIPEB);
+    int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
 
     if (!pI830->fb_compression)
 	return FALSE;
 
-    /* Pre-965 only supports plane A, which is synonymous with pipe A for now */
-    if (!IS_I965GM(pI830) && plane != FBC_CTL_PIPEA)
+    /* Pre-965 only supports plane A */
+    if (!IS_I965GM(pI830) && plane != FBC_CTL_PLANEA)
 	return FALSE;
 
     /* Need 15, 16, or 32 (w/alpha) pixel format */
@@ -704,7 +704,7 @@ i830_enable_fb_compression(xf86CrtcPtr c
     uint32_t fbc_ctl;
     unsigned long compressed_stride;
     int pipe = intel_crtc->pipe;
-    int plane = (pipe == 0 ? FBC_CTL_PIPEA : FBC_CTL_PIPEB);
+    int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
     unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp;
     unsigned long interval = 1000;
 
diff --git a/src/i830_reg.h b/src/i830_reg.h
index d1670c3..8a2a98a 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -47,8 +47,8 @@
 #define   FBC_STAT_CURRENT_LINE	(1<<0)
 #define FBC_CONTROL2		0x03214
 #define   FBC_CTL_CPU_FENCE	(1<<1)
-#define   FBC_CTL_PIPEA		(0<<0)
-#define   FBC_CTL_PIPEB		(1<<0)
+#define   FBC_CTL_PLANEA	(0<<0)
+#define   FBC_CTL_PLANEB	(1<<0)
 
 #define FBC_LL_SIZE		(1536)
 #define FBC_LL_PAD		(32)
diff-tree 9c0388dc8d4c6495fae21af6da644b34e20173d1 (from cecbc71fdc9af832cef23427696f6f654f7d6104)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Jul 6 20:38:41 2007 -0700

    Update man page with current behavior.

diff --git a/man/intel.man b/man/intel.man
index 3173bc7..8bd3f28 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -75,12 +75,17 @@ driver attempts to allocate space for at
 HD-sized XV video.  The default used for a specific configuration can be found
 by examining the __xservername__ log file.
 .TP
-.BI "Option \*qFrameBufferCompression\*q \*q" boolean \*q
+.BI "Option \*qFramebufferCompression\*q \*q" boolean \*q
 This option controls whether the framebuffer compression feature is enabled.
 If possible, the front buffer will be allocated in a tiled format and compressed
 periodically to save memory bandwidth and power.
-.TP
 This option is only available on mobile chipsets.
+Default: disabled.
+.TP
+.BI "Option \*qTiling\*q \*q" boolean \*q
+This option controls whether memory buffers are allocated in tiled mode.  In
+many cases (especially for complex rendering), tiling can improve performance.
+Default: enabled.
 .TP
 .BI "Option \*qDRI\*q \*q" boolean \*q
 Disable or enable DRI support.
diff-tree cecbc71fdc9af832cef23427696f6f654f7d6104 (from 4359df9419d2d02a2f9d9adc7f5a49ecf07ddd30)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Jul 6 16:36:34 2007 -0700

    Fix debug output in fbc enable/disable routines.  Add logic to make sure fbc
    isn't enabled twice on two different pipes.

diff --git a/src/i830_display.c b/src/i830_display.c
index c79676d..dc52c0b 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -708,6 +708,14 @@ i830_enable_fb_compression(xf86CrtcPtr c
     unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp;
     unsigned long interval = 1000;
 
+    if (INREG(FBC_CONTROL) & FBC_CTL_EN) {
+	char cur_pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "fbc already enabled on "
+		   "pipe %c, not enabling on pipe %c\n", cur_pipe, pipe ? 'b' :
+		   'a');
+	return;
+    }
+
     compressed_stride = pI830->compressed_front_buffer->size /
 	FBC_LL_SIZE;
 
@@ -730,7 +738,7 @@ i830_enable_fb_compression(xf86CrtcPtr c
     OUTREG(FBC_CONTROL, fbc_ctl);
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on pipe %c\n", pipe ?
-	       "a" : "b");
+	       'b' : 'a');
 }
 
 static void
@@ -739,6 +747,7 @@ i830_disable_fb_compression(xf86CrtcPtr 
     ScrnInfoPtr pScrn = crtc->scrn;
     I830Ptr pI830 = I830PTR(pScrn);
     uint32_t fbc_ctl;
+    char pipe = (INREG(FBC_CONTROL2) & 1) ? 'b' : 'a';;
 
     /* Disable compression */
     fbc_ctl = INREG(FBC_CONTROL);
@@ -748,7 +757,7 @@ i830_disable_fb_compression(xf86CrtcPtr 
     /* Wait for compressing bit to clear */
     while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
 	; /* nothing */
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled\n");
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on pipe %c\n", pipe);
 }
 
 static void
diff-tree 4359df9419d2d02a2f9d9adc7f5a49ecf07ddd30 (from ca593a5219549df94a6d234ebbcf9e7c44723c9b)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Jul 6 16:17:45 2007 -0700

    Fix tiling and fb compression defaults for 965 (not yet fully supported).

diff --git a/src/i830.h b/src/i830.h
index 4748b81..8b6c5e6 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -727,6 +727,8 @@ static inline int i830_tiling_supported(
 
 static inline int i830_fb_compression_supported(I830Ptr pI830)
 {
+    if (!i830_tiling_supported(pI830))
+	return FALSE;
     if (!IS_MOBILE(pI830))
 	return FALSE;
     if (IS_I810(pI830) || IS_I815(pI830) || IS_I830(pI830))
diff --git a/src/i830_driver.c b/src/i830_driver.c
index a380971..dcbed22 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2334,9 +2334,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
        pI830->fb_compression = TRUE;
    else
        pI830->fb_compression = FALSE;
-   /* ... but disable if requested */
-   if (!xf86ReturnOptValBool(pI830->Options, OPTION_FBC, TRUE))
-       pI830->fb_compression = FALSE;
+
+   if (xf86ReturnOptValBool(pI830->Options, OPTION_FBC, FALSE))
+       pI830->fb_compression = TRUE;
 
    if (pI830->fb_compression) {
        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Framebuffer compression enabled, "
diff-tree ca593a5219549df94a6d234ebbcf9e7c44723c9b (from 8798ef11321ee6957919279076758d47ad956cf3)
Author: Jesse Barnes <jesse.barnes at intel.com>
Date:   Fri Jul 6 16:10:52 2007 -0700

    FBC and tiling changes
      - change framebuffer option name to "FramebufferCompression"
      - add new "Tiling" option (controls all tiling, not just front buffer)
      - add debug message to fb compression enable/disable routines
      - update man page with new options

diff --git a/src/i830.h b/src/i830.h
index 1358e3e..4748b81 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -343,7 +343,7 @@ typedef struct _I830Rec {
    Bool NeedRingBufferLow;
    Bool allowPageFlip;
    Bool TripleBuffer;
-   Bool disableTiling;
+   Bool tiling;
    Bool fb_compression;
 
    int backPitch;
@@ -718,6 +718,22 @@ i830_get_transformed_coordinates(int x, 
 
 void i830_enter_render(ScrnInfoPtr);
 
+static inline int i830_tiling_supported(I830Ptr pI830)
+{
+    if (IS_I965G(pI830))
+	return FALSE;
+    return TRUE;
+}
+
+static inline int i830_fb_compression_supported(I830Ptr pI830)
+{
+    if (!IS_MOBILE(pI830))
+	return FALSE;
+    if (IS_I810(pI830) || IS_I815(pI830) || IS_I830(pI830))
+	return FALSE;
+    return TRUE;
+}
+
 extern const int I830PatternROP[16];
 extern const int I830CopyROP[16];
 
diff --git a/src/i830_display.c b/src/i830_display.c
index 0befef9..c79676d 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -728,6 +728,9 @@ i830_enable_fb_compression(xf86CrtcPtr c
     fbc_ctl |= (compressed_stride & 0xff) << FBC_CTL_STRIDE_SHIFT;
     fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
     OUTREG(FBC_CONTROL, fbc_ctl);
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on pipe %c\n", pipe ?
+	       "a" : "b");
 }
 
 static void
@@ -745,6 +748,7 @@ i830_disable_fb_compression(xf86CrtcPtr 
     /* Wait for compressing bit to clear */
     while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
 	; /* nothing */
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled\n");
 }
 
 static void
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 5f934fe..a380971 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -287,6 +287,7 @@ typedef enum {
    OPTION_CHECKDEVICES,
    OPTION_MODEDEBUG,
    OPTION_FBC,
+   OPTION_TILING,
 #ifdef XF86DRI_MM
    OPTION_INTELTEXPOOL,
    OPTION_INTELMMSIZE,
@@ -308,7 +309,8 @@ static OptionInfoRec I830Options[] = {
    {OPTION_VIDEO_KEY,	"VideoKey",	OPTV_INTEGER,	{0},	FALSE},
    {OPTION_CHECKDEVICES, "CheckDevices",OPTV_BOOLEAN,	{0},	FALSE},
    {OPTION_MODEDEBUG,	"ModeDebug",	OPTV_BOOLEAN,	{0},	FALSE},
-   {OPTION_FBC,		"FrameBufferCompression", OPTV_BOOLEAN, {0}, FALSE},
+   {OPTION_FBC,		"FramebufferCompression", OPTV_BOOLEAN, {0}, TRUE},
+   {OPTION_TILING,	"Tiling",	OPTV_BOOLEAN,	{0},	TRUE},
 #ifdef XF86DRI_MM
    {OPTION_INTELTEXPOOL,"Legacy3D",     OPTV_BOOLEAN,	{0},	FALSE},
    {OPTION_INTELMMSIZE, "AperTexSize",  OPTV_INTEGER,	{0},	FALSE},
@@ -2318,12 +2320,34 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       pI830->CacheLines = -1;
    }
 
-   if (xf86ReturnOptValBool(pI830->Options, OPTION_FBC, FALSE))
+   /* Enable tiling by default where supported or if the user forced it on */
+   if (i830_tiling_supported(pI830))
+       pI830->tiling = TRUE;
+   else
+       pI830->tiling = FALSE;
+
+   if (xf86ReturnOptValBool(pI830->Options, OPTION_TILING, FALSE))
+       pI830->tiling = TRUE;
+
+   /* Enable FB compression if possible */
+   if (i830_fb_compression_supported(pI830))
        pI830->fb_compression = TRUE;
    else
        pI830->fb_compression = FALSE;
+   /* ... but disable if requested */
+   if (!xf86ReturnOptValBool(pI830->Options, OPTION_FBC, TRUE))
+       pI830->fb_compression = FALSE;
 
-   pI830->disableTiling = FALSE;
+   if (pI830->fb_compression) {
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Framebuffer compression enabled, "
+		  "forcing tiling on.\n");
+       pI830->tiling = TRUE;
+   }
+
+   xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Framebuffer compression %sabled\n",
+	      pI830->fb_compression ? "en" : "dis");
+   xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Tiling %sabled\n", pI830->tiling ?
+	      "en" : "dis");
 
    if (I830IsPrimary(pScrn)) {
       /* Alloc our pointers for the primary head */
@@ -2413,7 +2437,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
        * 3: untiled, small
        */
 
-      pI830->disableTiling = FALSE;
 #ifdef XF86DRI_MM
       savedMMSize = pI830->mmSize;
 #define MM_TURNS 4
@@ -2426,7 +2449,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
 
 	 if (i >= MM_TURNS/2) {
 	    /* For further allocations, disable tiling */
-	    pI830->disableTiling = TRUE;
+	    pI830->tiling = FALSE;
 	    pScrn->displayWidth = savedDisplayWidth;
 	    if (pI830->allowPageFlip)
 	       xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -2481,9 +2504,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
 #endif
 	 pI830->directRenderingDisabled = TRUE;
       }
-   } else
+   }
 #endif
-      pI830->disableTiling = TRUE; /* no DRI - so disableTiling */
 
    if (!allocation_done) {
       if (!i830_allocate_2d_memory(pScrn)) {
@@ -2501,7 +2523,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
    if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		 "Cannot support DRI with frame buffer width > 2048.\n");
-      pI830->disableTiling = TRUE;
+      pI830->tiling = FALSE;
       pI830->directRenderingDisabled = TRUE;
    }
 
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 7134600..a589738 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -903,9 +903,7 @@ i830_allocate_framebuffer(ScrnInfoPtr pS
     name = secondary ? "secondary front buffer" : "front buffer";
 
     /* Attempt to allocate it tiled first if we have page flipping on. */
-    if ((!pI830->disableTiling && pI830->allowPageFlip &&
-	 IsTileable(pScrn, pitch)) || pI830->fb_compression)
-    {
+    if (pI830->tiling && IsTileable(pScrn, pitch)) {
 	/* XXX: probably not the case on 965 */
 	if (IS_I9XX(pI830))
 	    align = MB(1);
@@ -1253,7 +1251,7 @@ i830_allocate_backbuffer(ScrnInfoPtr pSc
 	height = pScrn->virtualX;
 
     /* Try to allocate on the best tile-friendly boundaries. */
-    if (!pI830->disableTiling && IsTileable(pScrn, pitch))
+    if (pI830->tiling && IsTileable(pScrn, pitch))
     {
 	size = ROUND_TO_PAGE(pitch * ALIGN(height, 16));
 	*buffer = i830_allocate_memory_tiled(pScrn, name, size, pitch,
@@ -1294,7 +1292,7 @@ i830_allocate_depthbuffer(ScrnInfoPtr pS
 	height = pScrn->virtualX;
 
     /* First try allocating it tiled */
-    if (!pI830->disableTiling && IsTileable(pScrn, pitch))
+    if (pI830->tiling && IsTileable(pScrn, pitch))
     {
 	enum tile_format tile_format;
 
diff --git a/src/i915_render.c b/src/i915_render.c
index b2dacfe..2148883 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -287,7 +287,7 @@ i915_texture_setup(PicturePtr pPict, Pix
     pI830->mapstate[unit * 3 + 1] = format |
 	((pPix->drawable.height - 1) << MS3_HEIGHT_SHIFT) |
 	((pPix->drawable.width - 1) << MS3_WIDTH_SHIFT);
-    if (!pI830->disableTiling)
+    if (pI830->tiling)
 	pI830->samplerstate[unit * 3 + 1] |= MS3_USE_FENCE_REGS;
     pI830->mapstate[unit * 3 + 2] = ((pitch / 4) - 1) << MS4_PITCH_SHIFT;
 
diff --git a/src/i915_video.c b/src/i915_video.c
index f1bf4cc..e116fe2 100644
--- a/src/i915_video.c
+++ b/src/i915_video.c
@@ -160,7 +160,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       }
       ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
-      if (!pI830->disableTiling)
+      if (pI830->tiling)
 	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
       OUT_RING(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);
@@ -251,7 +251,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       ms3 = MAPSURF_8BIT | MT_8BIT_I8;
       ms3 |= (height - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width - 1) << MS3_WIDTH_SHIFT;
-      if (!pI830->disableTiling)
+      if (pI830->tiling)
 	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
       OUT_RING(((video_pitch * 2 / 4) - 1) << MS4_PITCH_SHIFT);
@@ -260,7 +260,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       ms3 = MAPSURF_8BIT | MT_8BIT_I8;
       ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
-      if (!pI830->disableTiling)
+      if (pI830->tiling)
 	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
       OUT_RING(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);
@@ -269,7 +269,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pSc
       ms3 = MAPSURF_8BIT | MT_8BIT_I8;
       ms3 |= (height / 2 - 1) << MS3_HEIGHT_SHIFT;
       ms3 |= (width / 2 - 1) << MS3_WIDTH_SHIFT;
-      if (!pI830->disableTiling)
+      if (pI830->tiling)
 	 ms3 |= MS3_USE_FENCE_REGS;
       OUT_RING(ms3);
       OUT_RING(((video_pitch / 4) - 1) << MS4_PITCH_SHIFT);
diff-tree 8798ef11321ee6957919279076758d47ad956cf3 (from parents)
Merge: 8919b2292147add41a1c1c6e5e673257cb6c6c6e 3c552af65d28fafec1d09484a8914b690b961349
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Thu Jul 5 12:21:31 2007 -0700

    Merge branch 'master' into fbc

diff-tree 8919b2292147add41a1c1c6e5e673257cb6c6c6e (from 407b124af8f7bb42abe4eecc87476c4c3e555cd0)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Thu Jul 5 12:21:06 2007 -0700

    Re-add tiling kludge, but only for 965.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 904476a..7134600 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1450,6 +1450,11 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr
     assert(tile_format != TILING_NONE);
 
     if (IS_I965G(pI830)) {
+        if (tile_format == TILING_XMAJOR)
+            pitch = 512;
+        else
+            pitch = 128;
+ 
 	if (nr < 0 || nr >= FENCE_NEW_NR) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		       "i830_set_fence(): fence %d out of range\n",nr);
diff-tree 407b124af8f7bb42abe4eecc87476c4c3e555cd0 (from 7a87b9d2a2eb4d281dce67586756ff5653b2805a)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Thu Jul 5 11:31:34 2007 -0700

    Remove tiling kludge.  May need more fixes for 965.

diff --git a/src/i830_memory.c b/src/i830_memory.c
index f4271ef..904476a 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1444,8 +1444,6 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr
     CARD32 fence_mask = 0;
     unsigned int fence_pitch;
 
-    pitch = 512;
-
     DPRINTF(PFX, "i830_set_fence(): %d, 0x%08x, %d, %d kByte\n",
 	    nr, offset, pitch, size / 1024);
 
diff-tree 7a87b9d2a2eb4d281dce67586756ff5653b2805a (from fecf964534f5ba6d40480cb13adc89094946a51e)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Thu Jul 5 11:23:06 2007 -0700

    Revert discard alpha change, requires other fixes to work.

diff --git a/src/i830_display.c b/src/i830_display.c
index 6bfa7e6..db02402 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -1032,10 +1032,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	    dspcntr |= DISPPLANE_16BPP;
 	break;
     case 32:
-	if (pI830->fb_compression)
-	    dspcntr |= DISPPLANE_32BPP;
-	else
-	    dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+	dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
 	break;
     default:
 	FatalError("unknown display bpp\n");
diff-tree fecf964534f5ba6d40480cb13adc89094946a51e (from 60ee7b6a91b2b8c447130c60cd8b19eb68119777)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Thu Jul 5 10:59:23 2007 -0700

    FBC fixes:
      - properly check several FBC enablement constraints
      - don't use alpha discard if FBC is in use

diff --git a/src/i830_display.c b/src/i830_display.c
index 1feb13b..6bfa7e6 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -654,6 +654,34 @@ i830_crtc_unlock (xf86CrtcPtr crtc)
 #endif
 }
 
+static Bool
+i830_use_fb_compression(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
+    int pipe = intel_crtc->pipe;
+    int plane = (pipe == 0 ? FBC_CTL_PIPEA : FBC_CTL_PIPEB);
+
+    if (!pI830->fb_compression)
+	return FALSE;
+
+    /* Pre-965 only supports plane A, which is synonymous with pipe A for now */
+    if (!IS_I965GM(pI830) && plane != FBC_CTL_PIPEA)
+	return FALSE;
+
+    /* Need 15, 16, or 32 (w/alpha) pixel format */
+    if (!(pScrn->bitsPerPixel == 16 || /* covers 15 bit mode as well */
+	  pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */
+	return FALSE;
+
+    /*
+     * No checks for pixel multiply, incl. horizontal, or interlaced modes
+     * since they're currently unused.
+     */
+    return TRUE;
+}
+
 /*
  * Several restrictions:
  *   - DSP[AB]CNTR - no line duplication && no pixel multiplier
@@ -661,6 +689,9 @@ i830_crtc_unlock (xf86CrtcPtr crtc)
  *   - no alpha buffer discard
  *   - no dual wide display
  *   - progressive mode only (DSP[AB]CNTR)
+ *   - uncompressed fb is <= 2048 in width, 0 mod 8
+ *   - uncompressed fb is <= 1536 in height, 0 mod 2
+ *   - SR display watermarks must be equal between 16bpp and 32bpp?
  *
  * FIXME: verify above conditions are true
  */
@@ -719,20 +750,14 @@ i830_disable_fb_compression(xf86CrtcPtr 
 static void
 i830_crtc_prepare (xf86CrtcPtr crtc)
 {
-    ScrnInfoPtr pScrn = crtc->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
-    crtc->funcs->dpms (crtc, DPMSModeOff);
-
     /* Temporarily turn off FB compression during modeset */
-    if (pI830->fb_compression)
-	i830_disable_fb_compression(crtc);
+    i830_disable_fb_compression(crtc);
+    crtc->funcs->dpms (crtc, DPMSModeOff);
 }
 
 static void
 i830_crtc_commit (xf86CrtcPtr crtc)
 {
-    ScrnInfoPtr pScrn = crtc->scrn;
-    I830Ptr pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
     Bool		deactivate = FALSE;
 
@@ -748,7 +773,7 @@ i830_crtc_commit (xf86CrtcPtr crtc)
 	i830_pipe_a_require_deactivate (crtc->scrn);
 
     /* Reenable FB compression if possible */
-    if (pI830->fb_compression)
+    if (i830_use_fb_compression(crtc))
 	i830_enable_fb_compression(crtc);
 }
 
@@ -1007,7 +1032,10 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
 	    dspcntr |= DISPPLANE_16BPP;
 	break;
     case 32:
-	dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+	if (pI830->fb_compression)
+	    dspcntr |= DISPPLANE_32BPP;
+	else
+	    dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
 	break;
     default:
 	FatalError("unknown display bpp\n");
diff-tree 60ee7b6a91b2b8c447130c60cd8b19eb68119777 (from f02036aedcd7866c567a6adc070eda3dad872105)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Tue Jul 3 14:20:34 2007 -0700

    Fixup line length buffer padding, add kludge for front buffer tile
    pitch.

diff --git a/src/i830_display.c b/src/i830_display.c
index 5b1d6ea..1feb13b 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -678,7 +678,7 @@ i830_enable_fb_compression(xf86CrtcPtr c
     unsigned long interval = 1000;
 
     compressed_stride = pI830->compressed_front_buffer->size /
-	FBC_COMPRESSED_LINES;
+	FBC_LL_SIZE;
 
     if (uncompressed_stride < compressed_stride)
 	compressed_stride = uncompressed_stride;
@@ -688,7 +688,7 @@ i830_enable_fb_compression(xf86CrtcPtr c
 
     /* Set it up... */
     OUTREG(FBC_CFB_BASE, pI830->compressed_front_buffer->bus_addr);
-    OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr);
+    OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr + FBC_LL_PAD);
     OUTREG(FBC_CONTROL2, FBC_CTL_CPU_FENCE | plane);
 
     /* enable it... */
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 8703f2d..f4271ef 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1052,8 +1052,7 @@ static void i830_setup_fb_compression(Sc
      */
     pI830->compressed_front_buffer =
 	i830_allocate_memory(pScrn, "compressed frame buffer",
-			     MB(6), KB(4),
-			     NEED_PHYSICAL_ADDR);
+			     MB(6), KB(4), NEED_PHYSICAL_ADDR);
 
     if (!pI830->compressed_front_buffer) {
 	pI830->fb_compression = FALSE;
@@ -1062,7 +1061,8 @@ static void i830_setup_fb_compression(Sc
 
     pI830->compressed_ll_buffer =
 	i830_allocate_memory(pScrn, "compressed ll buffer",
-			     1568, KB(4), NEED_PHYSICAL_ADDR);
+			     FBC_LL_SIZE + FBC_LL_PAD, KB(4),
+			     NEED_PHYSICAL_ADDR);
     if (!pI830->compressed_ll_buffer) {
 	i830_free_memory(pScrn, pI830->compressed_front_buffer);
 	pI830->fb_compression = FALSE;
@@ -1444,6 +1444,8 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr
     CARD32 fence_mask = 0;
     unsigned int fence_pitch;
 
+    pitch = 512;
+
     DPRINTF(PFX, "i830_set_fence(): %d, 0x%08x, %d, %d kByte\n",
 	    nr, offset, pitch, size / 1024);
 
diff --git a/src/i830_reg.h b/src/i830_reg.h
index b5fa1b9..d1670c3 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -50,7 +50,8 @@
 #define   FBC_CTL_PIPEA		(0<<0)
 #define   FBC_CTL_PIPEB		(1<<0)
 
-#define FBC_COMPRESSED_LINES	(1536+32)
+#define FBC_LL_SIZE		(1536)
+#define FBC_LL_PAD		(32)
 
 #define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
 
diff-tree f02036aedcd7866c567a6adc070eda3dad872105 (from b384c608978dcd3d2ea6c0018179673cb4735f4c)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Mon Jul 2 15:42:02 2007 -0700

    Framebuffer compression changes:
      - move FBC register definitions to i830_reg.h
      - add fix from Arjan for 965 depth buffer tiling
      - add VT switch and clear-at-server-start code for FBC registers

diff --git a/src/i830.h b/src/i830.h
index 29982ec..1358e3e 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -530,6 +530,10 @@ typedef struct _I830Rec {
    CARD32 savePaletteB[256];
    CARD32 saveSWF[17];
    CARD32 saveBLC_PWM_CTL;
+   CARD32 saveFBC_CFB_BASE;
+   CARD32 saveFBC_LL_BASE;
+   CARD32 saveFBC_CONTROL2;
+   CARD32 saveFBC_CONTROL;
 
    enum last_3d *last_3d;
 
diff --git a/src/i830_display.c b/src/i830_display.c
index f3b24b2..5b1d6ea 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -38,6 +38,7 @@
 
 #include "xf86.h"
 #include "i830.h"
+#include "i830_reg.h"
 #include "i830_bios.h"
 #include "i830_display.h"
 #include "i830_debug.h"
@@ -653,28 +654,6 @@ i830_crtc_unlock (xf86CrtcPtr crtc)
 #endif
 }
 
-#define FBC_CFB_BASE		0x03200 /* 4k page aligned */
-#define FBC_LL_BASE		0x03204 /* 4k page aligned */
-#define FBC_CONTROL		0x03208
-#define   FBC_CTL_EN		(1<<31)
-#define   FBC_CTL_PERIODIC	(1<<30)
-#define   FBC_CTL_INTERVAL_SHIFT (16)
-#define   FBC_CTL_STRIDE_SHIFT	(5)
-#define   FBC_CTL_FENCENO	(1<<0)
-#define FBC_COMMAND		0x0320c
-#define   FBC_CMD_COMPRESS	(1<<0)
-#define FBC_STATUS		0x03210
-#define   FBC_STAT_COMPRESSING	(1<<31)
-#define   FBC_STAT_COMPRESSED	(1<<30)
-#define   FBC_STAT_MODIFIED	(1<<29)
-#define   FBC_STAT_CURRENT_LINE	(1<<0)
-#define FBC_CONTROL2		0x03214
-#define   FBC_CTL_CPU_FENCE	(1<<1)
-#define   FBC_CTL_PIPEA		(0<<0)
-#define   FBC_CTL_PIPEB		(1<<0)
-
-#define FBC_COMPRESSED_LINES	(1536+32)
-
 /*
  * Several restrictions:
  *   - DSP[AB]CNTR - no line duplication && no pixel multiplier
@@ -718,9 +697,6 @@ i830_enable_fb_compression(xf86CrtcPtr c
     fbc_ctl |= (compressed_stride & 0xff) << FBC_CTL_STRIDE_SHIFT;
     fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
     OUTREG(FBC_CONTROL, fbc_ctl);
-
-    /* and request immediate compression */
-    OUTREG(FBC_COMMAND, FBC_CMD_COMPRESS);
 }
 
 static void
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 42d0f87..5f934fe 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -192,6 +192,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "vbe.h"
 #include "shadow.h"
 #include "i830.h"
+#include "i830_reg.h"
 #include "i830_display.h"
 #include "i830_debug.h"
 #include "i830_bios.h"
@@ -1750,6 +1751,11 @@ SaveHWState(ScrnInfoPtr pScrn)
    vgaRegPtr vgaReg = &hwp->SavedReg;
    int i;
 
+   pI830->saveFBC_CFB_BASE = INREG(FBC_CFB_BASE);
+   pI830->saveFBC_LL_BASE = INREG(FBC_LL_BASE);
+   pI830->saveFBC_CONTROL2 = INREG(FBC_CONTROL2);
+   pI830->saveFBC_CONTROL = INREG(FBC_CONTROL);
+
    /* Save video mode information for native mode-setting. */
    pI830->saveDSPACNTR = INREG(DSPACNTR);
    pI830->savePIPEACONF = INREG(PIPEACONF);
@@ -1974,6 +1980,11 @@ RestoreHWState(ScrnInfoPtr pScrn)
    OUTREG(SWF31, pI830->saveSWF[15]);
    OUTREG(SWF32, pI830->saveSWF[16]);
 
+   OUTREG(FBC_CFB_BASE, pI830->saveFBC_CFB_BASE);
+   OUTREG(FBC_LL_BASE, pI830->saveFBC_LL_BASE);
+   OUTREG(FBC_CONTROL2, pI830->saveFBC_CONTROL2);
+   OUTREG(FBC_CONTROL, pI830->saveFBC_CONTROL);
+
    vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
    vgaHWLock(hwp);
 
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 5e553f1..8703f2d 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -104,6 +104,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
 #include "i830.h"
 #include "i810_reg.h"
+#include "i830_reg.h"
 
 #define ALIGN(i,m)    (((i) + (m) - 1) & ~((m) - 1))
 
@@ -1032,6 +1033,12 @@ static void i830_setup_fb_compression(Sc
 	goto out;
     }
 
+    /* Clear out any stale state */
+    OUTREG(FBC_CFB_BASE, 0);
+    OUTREG(FBC_LL_BASE, 0);
+    OUTREG(FBC_CONTROL2, 0);
+    OUTREG(FBC_CONTROL, 0);
+
     /*
      * Compressed framebuffer limitations:
      *   - contiguous, physical, uncached memory
@@ -1302,7 +1309,8 @@ i830_allocate_depthbuffer(ScrnInfoPtr pS
 	    i830_allocate_memory_tiled(pScrn, "depth buffer", size, pitch,
 				       GTT_PAGE_SIZE, ALIGN_BOTH_ENDS,
 				       tile_format);
-	pI830->depth_tiled = FENCE_XMAJOR;
+	pI830->depth_tiled = (tile_format == TILING_YMAJOR) ? FENCE_YMAJOR :
+	    FENCE_XMAJOR;
     }
 
     /* Otherwise, allocate it linear. */
diff --git a/src/i830_reg.h b/src/i830_reg.h
index 7a8df9f..b5fa1b9 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -29,6 +29,29 @@
 #ifndef _I830_REG_H_
 #define _I830_REG_H_
 
+/* Framebuffer compression */
+#define FBC_CFB_BASE		0x03200 /* 4k page aligned */
+#define FBC_LL_BASE		0x03204 /* 4k page aligned */
+#define FBC_CONTROL		0x03208
+#define   FBC_CTL_EN		(1<<31)
+#define   FBC_CTL_PERIODIC	(1<<30)
+#define   FBC_CTL_INTERVAL_SHIFT (16)
+#define   FBC_CTL_STRIDE_SHIFT	(5)
+#define   FBC_CTL_FENCENO	(1<<0)
+#define FBC_COMMAND		0x0320c
+#define   FBC_CMD_COMPRESS	(1<<0)
+#define FBC_STATUS		0x03210
+#define   FBC_STAT_COMPRESSING	(1<<31)
+#define   FBC_STAT_COMPRESSED	(1<<30)
+#define   FBC_STAT_MODIFIED	(1<<29)
+#define   FBC_STAT_CURRENT_LINE	(1<<0)
+#define FBC_CONTROL2		0x03214
+#define   FBC_CTL_CPU_FENCE	(1<<1)
+#define   FBC_CTL_PIPEA		(0<<0)
+#define   FBC_CTL_PIPEB		(1<<0)
+
+#define FBC_COMPRESSED_LINES	(1536+32)
+
 #define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value)
 
 #define CMD_3D (0x3<<29)
diff-tree b384c608978dcd3d2ea6c0018179673cb4735f4c (from 1e2e301348b4168aeed38b3fdc6b0e43d5678a86)
Author: Jesse Barnes <jbarnes at nietzche.virtuousgeek.org>
Date:   Mon Jul 2 09:32:28 2007 -0700

    Enable framebuffer compression (use Option "FrameBufferCompression"
    "true" in your xorg.conf).  Should save ~0.5W during typical 2D usage.

diff --git a/man/intel.man b/man/intel.man
index 8991619..3e443cd 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -77,6 +77,13 @@ driver attempts to allocate space for at
 HD-sized XV video.  The default used for a specific configuration can be found
 by examining the __xservername__ log file.
 .TP
+.BI "Option \*qFrameBufferCompression\*q \*q" boolean \*q
+This option controls whether the framebuffer compression feature is enabled.
+If possible, the front buffer will be allocated in a tiled format and compressed
+periodically to save memory bandwidth and power.
+.TP
+This option is only available on mobile chipsets.
+.TP
 .BI "Option \*qDRI\*q \*q" boolean \*q
 Disable or enable DRI support.
 Default: DRI is enabled for configurations where it is supported.
diff --git a/src/i830.h b/src/i830.h
index 9dda33a..29982ec 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -287,6 +287,8 @@ typedef struct _I830Rec {
 
    i830_memory *front_buffer;
    i830_memory *front_buffer_2;
+   i830_memory *compressed_front_buffer;
+   i830_memory *compressed_ll_buffer;
    /* One big buffer for all cursors for kernels that support this */
    i830_memory *cursor_mem;
    /* separate small buffers for kernels that support this */
@@ -342,6 +344,7 @@ typedef struct _I830Rec {
    Bool allowPageFlip;
    Bool TripleBuffer;
    Bool disableTiling;
+   Bool fb_compression;
 
    int backPitch;
 
diff --git a/src/i830_display.c b/src/i830_display.c
index aba86ae..f3b24b2 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -653,15 +653,110 @@ i830_crtc_unlock (xf86CrtcPtr crtc)
 #endif
 }
 
+#define FBC_CFB_BASE		0x03200 /* 4k page aligned */
+#define FBC_LL_BASE		0x03204 /* 4k page aligned */
+#define FBC_CONTROL		0x03208
+#define   FBC_CTL_EN		(1<<31)
+#define   FBC_CTL_PERIODIC	(1<<30)
+#define   FBC_CTL_INTERVAL_SHIFT (16)
+#define   FBC_CTL_STRIDE_SHIFT	(5)
+#define   FBC_CTL_FENCENO	(1<<0)
+#define FBC_COMMAND		0x0320c
+#define   FBC_CMD_COMPRESS	(1<<0)
+#define FBC_STATUS		0x03210
+#define   FBC_STAT_COMPRESSING	(1<<31)
+#define   FBC_STAT_COMPRESSED	(1<<30)
+#define   FBC_STAT_MODIFIED	(1<<29)
+#define   FBC_STAT_CURRENT_LINE	(1<<0)
+#define FBC_CONTROL2		0x03214
+#define   FBC_CTL_CPU_FENCE	(1<<1)
+#define   FBC_CTL_PIPEA		(0<<0)
+#define   FBC_CTL_PIPEB		(1<<0)
+
+#define FBC_COMPRESSED_LINES	(1536+32)
+
+/*
+ * Several restrictions:
+ *   - DSP[AB]CNTR - no line duplication && no pixel multiplier
+ *   - pixel format == 15 bit, 16 bit, or 32 bit xRGB_8888
+ *   - no alpha buffer discard
+ *   - no dual wide display
+ *   - progressive mode only (DSP[AB]CNTR)
+ *
+ * FIXME: verify above conditions are true
+ */
+static void
+i830_enable_fb_compression(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
+    uint32_t fbc_ctl;
+    unsigned long compressed_stride;
+    int pipe = intel_crtc->pipe;
+    int plane = (pipe == 0 ? FBC_CTL_PIPEA : FBC_CTL_PIPEB);
+    unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp;
+    unsigned long interval = 1000;
+
+    compressed_stride = pI830->compressed_front_buffer->size /
+	FBC_COMPRESSED_LINES;
+
+    if (uncompressed_stride < compressed_stride)
+	compressed_stride = uncompressed_stride;
+
+    /* FBC_CTL wants 64B units */
+    compressed_stride = (compressed_stride / 64) - 1;
+
+    /* Set it up... */
+    OUTREG(FBC_CFB_BASE, pI830->compressed_front_buffer->bus_addr);
+    OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr);
+    OUTREG(FBC_CONTROL2, FBC_CTL_CPU_FENCE | plane);
+
+    /* enable it... */
+    fbc_ctl = INREG(FBC_CONTROL);
+    fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC;
+    fbc_ctl |= (compressed_stride & 0xff) << FBC_CTL_STRIDE_SHIFT;
+    fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
+    OUTREG(FBC_CONTROL, fbc_ctl);
+
+    /* and request immediate compression */
+    OUTREG(FBC_COMMAND, FBC_CMD_COMPRESS);
+}
+
+static void
+i830_disable_fb_compression(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    uint32_t fbc_ctl;
+
+    /* Disable compression */
+    fbc_ctl = INREG(FBC_CONTROL);
+    fbc_ctl &= ~FBC_CTL_EN;
+    OUTREG(FBC_CONTROL, fbc_ctl);
+
+    /* Wait for compressing bit to clear */
+    while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
+	; /* nothing */
+}
+
 static void
 i830_crtc_prepare (xf86CrtcPtr crtc)
 {
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
     crtc->funcs->dpms (crtc, DPMSModeOff);
+
+    /* Temporarily turn off FB compression during modeset */
+    if (pI830->fb_compression)
+	i830_disable_fb_compression(crtc);
 }
 
 static void
 i830_crtc_commit (xf86CrtcPtr crtc)
 {
+    ScrnInfoPtr pScrn = crtc->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
     I830CrtcPrivatePtr	intel_crtc = crtc->driver_private;
     Bool		deactivate = FALSE;
 
@@ -675,6 +770,10 @@ i830_crtc_commit (xf86CrtcPtr crtc)
 	xf86_reload_cursors (crtc->scrn->pScreen);
     if (deactivate)
 	i830_pipe_a_require_deactivate (crtc->scrn);
+
+    /* Reenable FB compression if possible */
+    if (pI830->fb_compression)
+	i830_enable_fb_compression(crtc);
 }
 
 void
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 7f1fe2c..42d0f87 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -285,6 +285,7 @@ typedef enum {
    OPTION_COLOR_KEY,
    OPTION_CHECKDEVICES,
    OPTION_MODEDEBUG,
+   OPTION_FBC,
 #ifdef XF86DRI_MM
    OPTION_INTELTEXPOOL,
    OPTION_INTELMMSIZE,
@@ -306,6 +307,7 @@ static OptionInfoRec I830Options[] = {
    {OPTION_VIDEO_KEY,	"VideoKey",	OPTV_INTEGER,	{0},	FALSE},
    {OPTION_CHECKDEVICES, "CheckDevices",OPTV_BOOLEAN,	{0},	FALSE},
    {OPTION_MODEDEBUG,	"ModeDebug",	OPTV_BOOLEAN,	{0},	FALSE},
+   {OPTION_FBC,		"FrameBufferCompression", OPTV_BOOLEAN, {0}, FALSE},
 #ifdef XF86DRI_MM
    {OPTION_INTELTEXPOOL,"Legacy3D",     OPTV_BOOLEAN,	{0},	FALSE},
    {OPTION_INTELMMSIZE, "AperTexSize",  OPTV_INTEGER,	{0},	FALSE},
@@ -2305,6 +2307,11 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       pI830->CacheLines = -1;
    }
 
+   if (xf86ReturnOptValBool(pI830->Options, OPTION_FBC, FALSE))
+       pI830->fb_compression = TRUE;
+   else
+       pI830->fb_compression = FALSE;
+
    pI830->disableTiling = FALSE;
 
    if (I830IsPrimary(pScrn)) {
diff --git a/src/i830_memory.c b/src/i830_memory.c
index afdd93d..5e553f1 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -902,8 +902,8 @@ i830_allocate_framebuffer(ScrnInfoPtr pS
     name = secondary ? "secondary front buffer" : "front buffer";
 
     /* Attempt to allocate it tiled first if we have page flipping on. */
-    if (!pI830->disableTiling && pI830->allowPageFlip &&
-	IsTileable(pScrn, pitch))
+    if ((!pI830->disableTiling && pI830->allowPageFlip &&
+	 IsTileable(pScrn, pitch)) || pI830->fb_compression)
     {
 	/* XXX: probably not the case on 965 */
 	if (IS_I9XX(pI830))
@@ -1022,6 +1022,56 @@ i830_allocate_cursor_buffers(ScrnInfoPtr
     return TRUE;
 }
 
+static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+
+    /* Only mobile chips since 845 support this feature */
+    if (!IS_MOBILE(pI830)) {
+	pI830->fb_compression = FALSE;
+	goto out;
+    }
+
+    /*
+     * Compressed framebuffer limitations:
+     *   - contiguous, physical, uncached memory
+     *   - ideally as large as the front buffer(s), smaller sizes cache less
+     *   - uncompressed buffer must be tiled w/pitch 2k-16k
+     *   - uncompressed fb is <= 2048 in width, 0 mod 8
+     *   - uncompressed fb is <= 1536 in height, 0 mod 2
+     *   - compressed fb stride is <= uncompressed stride
+     *   - SR display watermarks must be equal between 16bpp and 32bpp?
+     *   - both compressed and line buffers must be in stolen memory
+     */
+    pI830->compressed_front_buffer =
+	i830_allocate_memory(pScrn, "compressed frame buffer",
+			     MB(6), KB(4),
+			     NEED_PHYSICAL_ADDR);
+
+    if (!pI830->compressed_front_buffer) {
+	pI830->fb_compression = FALSE;
+	goto out;
+    }
+
+    pI830->compressed_ll_buffer =
+	i830_allocate_memory(pScrn, "compressed ll buffer",
+			     1568, KB(4), NEED_PHYSICAL_ADDR);
+    if (!pI830->compressed_ll_buffer) {
+	i830_free_memory(pScrn, pI830->compressed_front_buffer);
+	pI830->fb_compression = FALSE;
+	goto out;
+    }
+
+out:
+    if (pI830->fb_compression)
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Framebuffer compression "
+		   "enabled\n");
+    else
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Allocation error, framebuffer"
+		   " compression disabled\n");
+	
+    return;
+}
 /*
  * Allocate memory for 2D operation.  This includes the (front) framebuffer,
  * ring buffer, scratch memory, HW cursor.
@@ -1046,6 +1096,9 @@ i830_allocate_2d_memory(ScrnInfoPtr pScr
     /* Allocate the ring buffer first, so it ends up in stolen mem. */
     i830_allocate_ringbuffer(pScrn);
 
+    if (pI830->fb_compression)
+	i830_setup_fb_compression(pScrn);
+
     /* Next, allocate other fixed-size allocations we have. */
     if (!pI830->SWCursor && !i830_allocate_cursor_buffers(pScrn)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,


More information about the xorg-commit mailing list