diff --git a/src/i830.h b/src/i830.h index 64a3690..6b79792 100644 --- a/src/i830.h +++ b/src/i830.h @@ -408,6 +408,11 @@ typedef struct _I830Rec { unsigned int copy_src_pitch; unsigned int copy_src_off; unsigned int copy_src_tiled; + unsigned int exa_offscreen_tiled; + int pixmap_private_index; + CreatePixmapProcPtr OldCreatePixmap; + DestroyPixmapProcPtr OldDestroyPixmap; + CreateScreenResourcesProcPtr OldCreateScreenResources; ExaDriverPtr EXADriverPtr; #endif @@ -548,6 +553,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 @@ -741,6 +760,13 @@ static inline int i830_fb_compression_supported(I830Ptr pI830) return TRUE; } +static inline Bool i830_pixmap_tiled(PixmapPtr p) +{ + struct i830_pixmap_private *priv = I830PixmapPrivate(p); + + return priv->tiled; +} + extern const int I830PatternROP[16]; extern const int I830CopyROP[16]; 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..421c6e7 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, diff --git a/src/i830_exa.c b/src/i830_exa.c index 3486537..8e7ffe4 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 @@ -153,7 +138,7 @@ I830EXAPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) if ( pitch % pI830->EXADriverPtr->pixmapPitchAlign != 0) I830FALLBACK("pixmap pitch not aligned"); - if (exaPixmapTiled(pPixmap)) + if (i830_pixmap_tiled(pPixmap)) pitch /= 4; pI830->BR[13] = (pitch & 0xffff); switch (pPixmap->drawable.bitsPerPixel) { @@ -191,7 +176,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 (exaPixmapTiled(pPixmap)) + if (i830_pixmap_tiled(pPixmap)) cmd |= XY_COLOR_BLT_TILED; OUT_RING(cmd); @@ -230,14 +215,14 @@ I830EXAPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, I830FALLBACK("planemask is not solid"); pI830->copy_src_pitch = exaGetPixmapPitch(pSrcPixmap); - if (exaPixmapTiled(pSrcPixmap)) + if (i830_pixmap_tiled(pSrcPixmap)) pI830->copy_src_pitch /= 4; pI830->copy_src_off = exaGetPixmapOffset(pSrcPixmap); - pI830->copy_src_tiled = exaPixmapTiled(pSrcPixmap); + pI830->copy_src_tiled = i830_pixmap_tiled(pSrcPixmap); pI830->BR[13] = exaGetPixmapPitch(pDstPixmap); - if (exaPixmapTiled(pDstPixmap)) + if (i830_pixmap_tiled(pDstPixmap)) pI830->BR[13] /= 4; pI830->BR[13] |= I830CopyROP[alu] << 16; @@ -278,7 +263,7 @@ I830EXACopy(PixmapPtr pDstPixmap, int src_x1, int src_y1, int dst_x1, if (pDstPixmap->drawable.bitsPerPixel == 32) cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB; - if (exaPixmapTiled(pDstPixmap)) + if (i830_pixmap_tiled(pDstPixmap)) cmd |= XY_SRC_COPY_BLT_DST_TILED; if (pI830->copy_src_tiled) @@ -421,6 +406,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: @@ -552,6 +569,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 744501a..06df7b6 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -399,9 +399,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); @@ -409,11 +411,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; @@ -641,6 +655,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)); @@ -667,6 +683,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)); @@ -695,6 +713,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));