diff --git a/src/i810_reg.h b/src/i810_reg.h index d1fed22..d5f6e76 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -2168,12 +2168,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 a8de0e6..64a3690 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..9619a96 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -97,6 +97,17 @@ const int I830PatternROP[16] = ROP_1 }; +static Bool +exaPixmapInFrontbuffer(PixmapPtr p) +{ + ScreenPtr pScreen = p->drawable.pScreen; + + return FALSE; + if (p == pScreen->GetScreenPixmap(pScreen)) + return TRUE; + return FALSE; +} + /** * I830EXASync - wait for a command to finish * @pScreen: current screen @@ -162,16 +173,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 +229,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 +254,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 +266,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 b38a5df..fd88e7c 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -1447,17 +1447,12 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset, CARD32 fence_mask = 0; unsigned int fence_pitch; - DPRINTF(PFX, "i830_set_fence(): %d, 0x%08x, %d, %d kByte\n", + ErrorF("i830_set_fence(): %d, 0x%08x, %d, %d kByte\n", nr, offset, pitch, size / 1024); 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); @@ -1466,6 +1461,9 @@ i830_set_fence(ScrnInfoPtr pScrn, int nr, unsigned int offset, switch (tile_format) { case TILING_XMAJOR: + if (pitch % 512) + ErrorF("bad pitch value %d, not a multiple of tile width\n", + pitch); pI830->fence[nr] = (((pitch / 128) - 1) << 2) | offset | 1; pI830->fence[nr] |= I965_FENCE_X_MAJOR; break;