summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Barnes <jesse.barnes@intel.com>2007-08-03 20:40:45 -0700
committerJesse Barnes <jesse.barnes@intel.com>2007-08-03 20:40:45 -0700
commit3d3c0e8c55f639a501c0756948b518abd903d7d0 (patch)
treed43002abbaf2829e2a6a979f17b32ef2f13760eb
parent0da4f2b0cd7203377ad10407928a367b8c6d310e (diff)
Tiled rendering & fbc fixes:
- actually enable tiling in DSP(A|B)CNTR if needed - add logic to EXA routines for tiled case (still needs work) - enable/disable fbc on DPMS events (meant moving functions higher in file) - fix fence register pitch programming (use correct pitch instead of kludged value)
-rw-r--r--src/i810_reg.h4
-rw-r--r--src/i830.h1
-rw-r--r--src/i830_display.c234
-rw-r--r--src/i830_exa.c54
-rw-r--r--src/i830_memory.c5
-rw-r--r--src/i830_reg.h7
6 files changed, 186 insertions, 119 deletions
diff --git a/src/i810_reg.h b/src/i810_reg.h
index d1fed22c..03e10d64 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -2029,6 +2029,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DSPBCNTR 0x71180
#define DISPLAY_PLANE_ENABLE (1<<31)
#define DISPLAY_PLANE_DISABLE 0
+#define DISPLAY_PLANE_TILED (1<<10)
#define DISPPLANE_GAMMA_ENABLE (1<<30)
#define DISPPLANE_GAMMA_DISABLE 0
#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
@@ -2168,12 +2169,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|(0x4))
#define XY_COLOR_BLT_WRITE_ALPHA (1<<21)
#define XY_COLOR_BLT_WRITE_RGB (1<<20)
+#define XY_COLOR_BLT_TILED (1<<11)
#define XY_SETUP_CLIP_BLT_CMD ((2<<29)|(3<<22)|1)
#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
+#define XY_SRC_COPY_BLT_SRC_TILED (1<<15)
+#define XY_SRC_COPY_BLT_DST_TILED (1<<11)
#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|0x4)
#define SRC_COPY_BLT_WRITE_ALPHA (1<<21)
diff --git a/src/i830.h b/src/i830.h
index a8de0e6c..64a36909 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -407,6 +407,7 @@ typedef struct _I830Rec {
#ifdef I830_USE_EXA
unsigned int copy_src_pitch;
unsigned int copy_src_off;
+ unsigned int copy_src_tiled;
ExaDriverPtr EXADriverPtr;
#endif
diff --git a/src/i830_display.c b/src/i830_display.c
index 26873fef..6fe7be74 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -498,6 +498,123 @@ i830_pipe_a_require_deactivate (ScrnInfoPtr scrn)
return;
}
+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_PLANEA : FBC_CTL_PLANEB);
+
+ if (!pI830->fb_compression)
+ return FALSE;
+
+ /* 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 */
+ 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
+ * - 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)
+ * - 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
+ */
+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 = 0;
+ unsigned long compressed_stride;
+ int pipe = intel_crtc->pipe;
+ /* FIXME: plane & pipe might not always be equal */
+ int plane = (pipe == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB);
+ 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;
+
+ if (uncompressed_stride < compressed_stride)
+ compressed_stride = uncompressed_stride;
+
+ /* FBC_CTL wants 64B units */
+ compressed_stride = (compressed_stride / 64) - 1;
+
+ /* Set it up... */
+ /* Wait for compressing bit to clear */
+ while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
+ ; /* nothing */
+ i830WaitForVblank(pScrn);
+ OUTREG(FBC_CFB_BASE, pI830->compressed_front_buffer->bus_addr);
+ OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr + 6);
+ OUTREG(FBC_CONTROL2, FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_FULL |
+ FBC_CTL_CPU_FENCE | plane);
+
+ /* Zero buffers */
+ memset(pI830->FbBase + pI830->compressed_front_buffer->offset, 0,
+ pI830->compressed_front_buffer->size);
+ memset(pI830->FbBase + pI830->compressed_ll_buffer->offset, 0,
+ pI830->compressed_ll_buffer->size);
+
+ /* enable it... */
+ 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;
+ fbc_ctl |= FBC_CTL_UNCOMPRESSIBLE;
+ OUTREG(FBC_CONTROL, fbc_ctl);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on plane %c\n", pipe ?
+ 'b' : 'a');
+}
+
+static void
+i830_disable_fb_compression(xf86CrtcPtr crtc)
+{
+ 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);
+ fbc_ctl &= ~FBC_CTL_EN;
+ OUTREG(FBC_CONTROL, fbc_ctl);
+
+ /* Wait for compressing bit to clear */
+ while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
+ ; /* nothing */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on pipe %c\n", pipe);
+}
/**
* Sets the power management mode of the pipe and plane.
@@ -561,8 +678,16 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
/* Give the overlay scaler a chance to enable if it's on this pipe */
i830_crtc_dpms_video(crtc, TRUE);
+
+ /* Reenable compression if needed */
+ if (i830_use_fb_compression(crtc))
+ i830_enable_fb_compression(crtc);
break;
case DPMSModeOff:
+ /* Shut off compression if in use */
+ if (i830_use_fb_compression(crtc))
+ i830_disable_fb_compression(crtc);
+
/* Give the overlay scaler a chance to disable if it's on this pipe */
i830_crtc_dpms_video(crtc, FALSE);
@@ -656,112 +781,6 @@ 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_PLANEA : FBC_CTL_PLANEB);
-
- if (!pI830->fb_compression)
- return FALSE;
-
- /* 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 */
- 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
- * - 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)
- * - 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
- */
-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_PLANEA : FBC_CTL_PLANEB);
- 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;
-
- 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 + FBC_LL_PAD);
- 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);
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc enabled on pipe %c\n", pipe ?
- 'b' : 'a');
-}
-
-static void
-i830_disable_fb_compression(xf86CrtcPtr crtc)
-{
- 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);
- fbc_ctl &= ~FBC_CTL_EN;
- OUTREG(FBC_CONTROL, fbc_ctl);
-
- /* Wait for compressing bit to clear */
- while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING)
- ; /* nothing */
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on pipe %c\n", pipe);
-}
-
static void
i830_crtc_prepare (xf86CrtcPtr crtc)
{
@@ -1059,6 +1078,9 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
else
dspcntr |= DISPPLANE_SEL_PIPE_B;
+ if (pI830->tiling)
+ dspcntr |= DISPLAY_PLANE_TILED;
+
pipeconf = INREG(pipeconf_reg);
if (pipe == 0 && !IS_I965G(pI830))
{
diff --git a/src/i830_exa.c b/src/i830_exa.c
index fed4067b..5da153e0 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -97,6 +97,16 @@ const int I830PatternROP[16] =
ROP_1
};
+static Bool
+exaPixmapInFrontbuffer(PixmapPtr p)
+{
+ ScreenPtr pScreen = p->drawable.pScreen;
+
+ if (p == pScreen->GetScreenPixmap(pScreen))
+ return TRUE;
+ return FALSE;
+}
+
/**
* I830EXASync - wait for a command to finish
* @pScreen: current screen
@@ -162,16 +172,26 @@ I830EXASolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
unsigned long offset;
+ uint32_t cmd;
offset = exaGetPixmapOffset(pPixmap);
{
BEGIN_LP_RING(6);
+
+ cmd = XY_COLOR_BLT_CMD;
+
if (pPixmap->drawable.bitsPerPixel == 32)
- OUT_RING(XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA
- | XY_COLOR_BLT_WRITE_RGB);
- else
- OUT_RING(XY_COLOR_BLT_CMD);
+ cmd |= XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB;
+
+ if (pI830->tiling && exaPixmapInFrontbuffer(pPixmap)) {
+ /* Fixup pitch for destination if tiled */
+ pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) |
+ (pI830->BR[13] & 0xffff0000);
+ cmd |= XY_COLOR_BLT_TILED;
+ }
+
+ OUT_RING(cmd);
OUT_RING(pI830->BR[13]);
OUT_RING((y1 << 16) | (x1 & 0xffff));
@@ -208,6 +228,8 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap);
pI830->copy_src_off = exaGetPixmapOffset(pSrcPixmap);
+ pI830->copy_src_tiled = (pI830->tiling &&
+ exaPixmapInFrontbuffer(pSrcPixmap));
pI830->BR[13] = exaGetPixmapPitch(pDstPixmap);
pI830->BR[13] |= I830CopyROP[alu] << 16;
@@ -231,6 +253,7 @@ I830EXACopy(PixmapPtr pDstPixmap, int src_x1, int src_y1, int dst_x1,
{
ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
+ uint32_t cmd;
int dst_x2, dst_y2;
unsigned int dst_off;
@@ -242,11 +265,26 @@ I830EXACopy(PixmapPtr pDstPixmap, int src_x1, int src_y1, int dst_x1,
{
BEGIN_LP_RING(8);
+ cmd = XY_SRC_COPY_BLT_CMD;
+
if (pDstPixmap->drawable.bitsPerPixel == 32)
- OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
- else
- OUT_RING(XY_SRC_COPY_BLT_CMD);
+ cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB;
+
+ if (pI830->tiling && exaPixmapInFrontbuffer(pDstPixmap)) {
+ /* Fixup pitch for destination if tiled */
+ pI830->BR[13] = (ROUND_TO(pI830->BR[13] & 0xffff, 512) >> 2) |
+ (pI830->BR[13] & 0xffff0000);
+ cmd |= XY_SRC_COPY_BLT_DST_TILED;
+ }
+
+ if (pI830->copy_src_tiled) {
+ pI830->copy_src_pitch =
+ (ROUND_TO(pI830->copy_src_pitch & 0xffff, 512) >> 2) |
+ (pI830->copy_src_pitch & 0xffff0000);
+ cmd |= XY_SRC_COPY_BLT_SRC_TILED;
+ }
+
+ OUT_RING(cmd);
OUT_RING(pI830->BR[13]);
OUT_RING((dst_y1 << 16) | (dst_x1 & 0xffff));
diff --git a/src/i830_memory.c b/src/i830_memory.c
index b38a5dfe..ccd26b39 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -1453,11 +1453,6 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset,
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 --git a/src/i830_reg.h b/src/i830_reg.h
index 8a2a98ac..df22ed41 100644
--- a/src/i830_reg.h
+++ b/src/i830_reg.h
@@ -36,6 +36,7 @@
#define FBC_CTL_EN (1<<31)
#define FBC_CTL_PERIODIC (1<<30)
#define FBC_CTL_INTERVAL_SHIFT (16)
+#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
#define FBC_CTL_STRIDE_SHIFT (5)
#define FBC_CTL_FENCENO (1<<0)
#define FBC_COMMAND 0x0320c
@@ -46,9 +47,15 @@
#define FBC_STAT_MODIFIED (1<<29)
#define FBC_STAT_CURRENT_LINE (1<<0)
#define FBC_CONTROL2 0x03214
+#define FBC_CTL_FENCE_DBL (0<<4)
+#define FBC_CTL_IDLE_IMM (0<<2)
+#define FBC_CTL_IDLE_FULL (1<<2)
+#define FBC_CTL_IDLE_LINE (2<<2)
+#define FBC_CTL_IDLE_DEBUG (3<<2)
#define FBC_CTL_CPU_FENCE (1<<1)
#define FBC_CTL_PLANEA (0<<0)
#define FBC_CTL_PLANEB (1<<0)
+#define FBC_FENCE_OFF 0x0321b
#define FBC_LL_SIZE (1536)
#define FBC_LL_PAD (32)