diff --git a/src/i830.h b/src/i830.h index c2321d4..990d392 100644 --- a/src/i830.h +++ b/src/i830.h @@ -407,6 +407,11 @@ typedef struct _I830Rec { #ifdef I830_USE_EXA ExaDriverPtr EXADriverPtr; PixmapPtr pSrcPixmap; + unsigned int exa_offscreen_tiled; + int pixmap_private_index; + CreatePixmapProcPtr OldCreatePixmap; + DestroyPixmapProcPtr OldDestroyPixmap; + CreateScreenResourcesProcPtr OldCreateScreenResources; #endif I830WriteIndexedByteFunc writeControl; @@ -546,6 +551,20 @@ typedef struct _I830Rec { #define I830PTR(p) ((I830Ptr)((p)->driverPrivate)) +struct i830_pixmap_private { + Bool tiled; +}; + +static inline struct i830_pixmap_private *I830PixmapPrivate(PixmapPtr p) +{ + ScreenPtr pScreen = p->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + + return (struct i830_pixmap_private *) + p->devPrivates[pI830->pixmap_private_index].ptr; +} + #define I830_SELECT_FRONT 0 #define I830_SELECT_BACK 1 #define I830_SELECT_DEPTH 2 @@ -739,6 +758,20 @@ static inline int i830_fb_compression_supported(I830Ptr pI830) return TRUE; } +static inline Bool i830_pixmap_tiled(PixmapPtr p) +{ + ScreenPtr pScreen = p->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + + if (!pI830->tiling) + return FALSE; + + if (p == pScreen->GetScreenPixmap(pScreen)) + return TRUE; + return FALSE; +} + extern const int I830PatternROP[16]; extern const int I830CopyROP[16]; diff --git a/src/i830_debug.c b/src/i830_debug.c index 055ca93..9a9829d 100644 --- a/src/i830_debug.c +++ b/src/i830_debug.c @@ -431,6 +431,9 @@ static struct i830SnapshotRec { DEFINEREG(VCLK_POST_DIV), DEFINEREG2(VGACNTRL, i830_debug_vgacntrl), + DEFINEREG(BLC_PWM_CTL), + DEFINEREG(BLC_PWM_CTL2), + DEFINEREG(TV_CTL), DEFINEREG(TV_DAC), DEFINEREG(TV_CSC_Y), diff --git a/src/i830_display.c b/src/i830_display.c index 6fe7be7..4fc9983 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -498,6 +498,23 @@ i830_pipe_a_require_deactivate (ScrnInfoPtr scrn) return; } +/* FIXME: use pixmap private instead if possible */ +static Bool +i830_display_tiled(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + I830Ptr pI830 = I830PTR(pScrn); + + if (!pI830->tiling) + return FALSE; + + /* Rotated data is currently linear, allocated either via XAA or EXA */ + if (crtc->rotatedData) + return FALSE; + + return TRUE; +} + static Bool i830_use_fb_compression(xf86CrtcPtr crtc) { @@ -510,6 +527,9 @@ i830_use_fb_compression(xf86CrtcPtr crtc) if (!pI830->fb_compression) return FALSE; + if (!i830_display_tiled(crtc)) + return FALSE; + /* Pre-965 only supports plane A */ if (!IS_I965GM(pI830) && plane != FBC_CTL_PLANEA) return FALSE; @@ -1078,7 +1098,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, else dspcntr |= DISPPLANE_SEL_PIPE_B; - if (pI830->tiling) + if (i830_display_tiled(crtc)) dspcntr |= DISPLAY_PLANE_TILED; pipeconf = INREG(pipeconf_reg); diff --git a/src/i830_driver.c b/src/i830_driver.c index f293bfd..d97df1b 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2067,6 +2067,35 @@ I830InitFBManager( return ret; } +static Bool i830_create_screen_resources(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + PixmapPtr screen_pixmap; + struct i830_pixmap_private *priv; + Bool ret; + + if (!pI830->OldCreateScreenResources) + return FALSE; + + ret = pI830->OldCreateScreenResources(pScreen); + if (ret) + return ret; + + /* + * The old CSR should have setup a real screen pixmap for us, now + * set the appropriate tiled value. + */ + screen_pixmap = pScreen->GetScreenPixmap(pScreen); + priv = I830PixmapPrivate(screen_pixmap); + if (pI830->tiling) + priv->tiled = 1; + else + priv->tiled = 0; + + return FALSE; +} + /** * Intialiazes the hardware for the 3D pipeline use in the 2D driver. * @@ -2646,6 +2675,21 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (pScrn->virtualX > pScrn->displayWidth) pScrn->displayWidth = pScrn->virtualX; +#ifdef I830_USE_EXA + if (pI830->useEXA) { + pI830->pixmap_private_index = AllocatePixmapPrivateIndex(); + if (!AllocatePixmapPrivate(pScreen, pI830->pixmap_private_index, + sizeof(struct i830_pixmap_private))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to init pixmap private\n"); + return FALSE; + } + + pI830->OldCreateScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = i830_create_screen_resources; + } +#endif + DPRINTF(PFX, "assert( if(!fbScreenInit(pScreen, ...) )\n"); if (!fbScreenInit(pScreen, pI830->FbBase + pScrn->fbOffset, pScrn->virtualX, pScrn->virtualY, @@ -2914,6 +2958,8 @@ I830EnterVT(int scrnIndex, int flags) SaveHWState(pScrn); } + RestoreHWState(pScrn); + pI830->leaving = FALSE; if (I830IsPrimary(pScrn)) diff --git a/src/i830_exa.c b/src/i830_exa.c index b0029d1..3028cc4 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -97,21 +97,6 @@ const int I830PatternROP[16] = ROP_1 }; -static Bool -exaPixmapTiled(PixmapPtr p) -{ - ScreenPtr pScreen = p->drawable.pScreen; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); - - if (!pI830->tiling) - return FALSE; - - if (p == pScreen->GetScreenPixmap(pScreen)) - return TRUE; - return FALSE; -} - /** * I830EXASync - wait for a command to finish * @pScreen: current screen @@ -189,7 +174,7 @@ I830EXASolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) if (pPixmap->drawable.bitsPerPixel == 32) cmd |= XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB; - if (IS_I965G(pI830) && exaPixmapTiled(pPixmap)) { + if (IS_I965G(pI830) && i830_pixmap_tiled(pPixmap)) { assert((pitch % 512) == 0); pitch >>= 2; cmd |= XY_COLOR_BLT_TILED; @@ -274,13 +259,13 @@ I830EXACopy(PixmapPtr pDstPixmap, int src_x1, int src_y1, int dst_x1, cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB; if (IS_I965G(pI830)) { - if (exaPixmapTiled(pDstPixmap)) { + if (i830_pixmap_tiled(pDstPixmap)) { assert((dst_pitch % 512) == 0); dst_pitch >>= 2; cmd |= XY_SRC_COPY_BLT_DST_TILED; } - if (exaPixmapTiled(pI830->pSrcPixmap)) { + if (i830_pixmap_tiled(pI830->pSrcPixmap)) { assert((src_pitch % 512) == 0); src_pitch >>= 2; cmd |= XY_SRC_COPY_BLT_SRC_TILED; @@ -424,6 +409,38 @@ i830_upload_to_screen(PixmapPtr pDst, int x, int y, int w, int h, char *src, return TRUE; } +Bool exaPixmapIsOffscreen(PixmapPtr p); + +static PixmapPtr i830_pixmap_create(ScreenPtr pScreen, int w, int h, + int depth) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + PixmapPtr p; + struct i830_pixmap_private *priv; + + p = pI830->OldCreatePixmap(pScreen, w, h, depth); + if (!p) + return NULL; + + priv = I830PixmapPrivate(p); + + priv->tiled = FENCE_LINEAR; + + if (exaPixmapIsOffscreen(p)) + priv->tiled = pI830->exa_offscreen_tiled; + + return p; +} + +static Bool i830_pixmap_destroy(PixmapPtr p) +{ + ScreenPtr pScreen = p->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + + return pI830->OldDestroyPixmap(p); +} /* * TODO: @@ -534,7 +551,7 @@ I830EXAInit(ScreenPtr pScreen) pI830->EXADriverPtr->PrepareComposite = i915_prepare_composite; pI830->EXADriverPtr->Composite = i830_composite; pI830->EXADriverPtr->DoneComposite = i830_done_composite; - } else { + } else if (!pI830->tiling) { pI830->EXADriverPtr->CheckComposite = i965_check_composite; pI830->EXADriverPtr->PrepareComposite = i965_prepare_composite; pI830->EXADriverPtr->Composite = i965_composite; @@ -556,6 +573,11 @@ I830EXAInit(ScreenPtr pScreen) } } + pI830->OldCreatePixmap = pScreen->CreatePixmap; + pI830->OldDestroyPixmap = pScreen->DestroyPixmap; + pScreen->CreatePixmap = i830_pixmap_create; + pScreen->DestroyPixmap = i830_pixmap_destroy; + I830SelectBuffer(pScrn, I830_SELECT_FRONT); return TRUE; diff --git a/src/i830_memory.c b/src/i830_memory.c index ccd26b3..e88c1a2 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -1182,6 +1182,7 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) "Failed to allocate EXA offscreen memory."); return FALSE; } + pI830->exa_offscreen_tiled = FENCE_LINEAR; } } #endif /* I830_USE_EXA */ diff --git a/src/i965_render.c b/src/i965_render.c index ec64ddd..ad3b53e 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -392,9 +392,11 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, { ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); - CARD32 src_offset, src_pitch; - CARD32 mask_offset = 0, mask_pitch = 0; - CARD32 dst_format, dst_offset, dst_pitch; + CARD32 src_offset, src_pitch, src_tile_format = 0, src_tiled = 0; + CARD32 mask_offset = 0, mask_pitch = 0, mask_tile_format = 0, + mask_tiled = 0; + CARD32 dst_format, dst_offset, dst_pitch, dst_tile_format = 0, + dst_tiled = 0; Bool rotation_program = FALSE; IntelEmitInvarientState(pScrn); @@ -402,11 +404,23 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, src_offset = intel_get_pixmap_offset(pSrc); src_pitch = intel_get_pixmap_pitch(pSrc); + if (i830_pixmap_tiled(pSrc)) { + src_tiled = 1; + src_tile_format = 0; /* Tiled X */ + } dst_offset = intel_get_pixmap_offset(pDst); dst_pitch = intel_get_pixmap_pitch(pDst); + if (i830_pixmap_tiled(pDst)) { + dst_tiled = 1; + dst_tile_format = 0; /* Tiled X */ + } if (pMask) { mask_offset = intel_get_pixmap_offset(pMask); mask_pitch = intel_get_pixmap_pitch(pMask); + if (i830_pixmap_tiled(pMask)) { + mask_tiled = 1; + mask_tile_format = 0; /* Tiled X */ + } } pI830->scale_units[0][0] = pSrc->drawable.width; pI830->scale_units[0][1] = pSrc->drawable.height; @@ -634,6 +648,8 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, dest_surf_state->ss2.mip_count = 0; dest_surf_state->ss2.render_target_rotation = 0; dest_surf_state->ss3.pitch = dst_pitch - 1; + dest_surf_state->ss3.tile_walk = dst_tile_format; + dest_surf_state->ss3.tiled_surface = dst_tiled; dest_surf_state = (void *)(state_base + dest_surf_offset); memcpy (dest_surf_state, &dest_surf_state_local, sizeof (dest_surf_state_local)); @@ -660,6 +676,8 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, src_surf_state->ss2.mip_count = 0; src_surf_state->ss2.render_target_rotation = 0; src_surf_state->ss3.pitch = src_pitch - 1; + src_surf_state->ss3.tile_walk = src_tile_format; + src_surf_state->ss3.tiled_surface = src_tiled; src_surf_state = (void *)(state_base + src_surf_offset); memcpy (src_surf_state, &src_surf_state_local, sizeof (src_surf_state_local)); @@ -688,6 +706,8 @@ i965_prepare_composite(int op, PicturePtr pSrcPicture, mask_surf_state->ss2.mip_count = 0; mask_surf_state->ss2.render_target_rotation = 0; mask_surf_state->ss3.pitch = mask_pitch - 1; + mask_surf_state->ss3.tile_walk = mask_tile_format; + mask_surf_state->ss3.tiled_surface = mask_tiled; mask_surf_state = (void *)(state_base + mask_surf_offset); memcpy (mask_surf_state, &mask_surf_state_local, sizeof (mask_surf_state_local)); diff --git a/src/i965_video.c b/src/i965_video.c index 3084233..615bf26 100644 --- a/src/i965_video.c +++ b/src/i965_video.c @@ -378,6 +378,8 @@ I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, dest_surf_state->ss2.mip_count = 0; dest_surf_state->ss2.render_target_rotation = 0; dest_surf_state->ss3.pitch = pPixmap->devKind - 1; + dest_surf_state->ss3.tiled_surface = i830_pixmap_tiled(pPixmap); + dest_surf_state->ss3.tile_walk = 0; /* TileX */ /* Set up the source surface state buffer */ memset(src_surf_state, 0, sizeof(*src_surf_state));