diff --git a/src/i810_reg.h b/src/i810_reg.h index 248df04..de6b90d 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -2160,12 +2160,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 bf072a1..3b27854 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_exa.c b/src/i830_exa.c index fed4067..84c60fa 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -97,6 +97,21 @@ const int I830PatternROP[16] = ROP_1 }; +static Bool +exaPixmapIsOffscreen(PixmapPtr p) +{ + ScrnInfoPtr pScrn = xf86Screens[p->drawable.pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + + /* NULL private means offscreen */ + if (!p->devPrivate.ptr) + return TRUE; + + return ((unsigned long) ((CARD8 *) p->devPrivate.ptr - + (CARD8 *) pI830->EXADriverPtr->memoryBase) < + pI830->EXADriverPtr->memorySize); +} + /** * I830EXASync - wait for a command to finish * @pScreen: current screen @@ -162,16 +177,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 && !exaPixmapIsOffscreen(pPixmap)) { + /* Fixup pitch for destination if tiled */ + pI830->BR[13] = ((pI830->BR[13] & 0xffff) >> 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 +233,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 && + !exaPixmapIsOffscreen(pSrcPixmap)); pI830->BR[13] = exaGetPixmapPitch(pDstPixmap); pI830->BR[13] |= I830CopyROP[alu] << 16; @@ -231,6 +258,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 +270,25 @@ 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 && !exaPixmapIsOffscreen(pDstPixmap)) { + /* Fixup pitch for destination if tiled */ + pI830->BR[13] = ((pI830->BR[13] & 0xffff) >> 2) | + (pI830->BR[13] & 0xffff0000); + cmd |= XY_SRC_COPY_BLT_DST_TILED; + } + + if (pI830->copy_src_tiled) { + pI830->copy_src_pitch = ((pI830->copy_src_pitch & 0xffff) >> 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_xaa.c b/src/i830_xaa.c index ec8a879..682f103 100644 --- a/src/i830_xaa.c +++ b/src/i830_xaa.c @@ -296,6 +296,8 @@ CheckTiling(ScrnInfoPtr pScrn) pI830->depth_tiled == FENCE_XMAJOR) { tiled = 1; } + if (pI830->tiling) + tiled = 1; } return tiled;