diff options
author | Alex Deucher <alex@botch2.com> | 2007-03-06 02:24:08 -0500 |
---|---|---|
committer | Alex Deucher <alex@botch2.com> | 2007-03-13 00:17:30 -0400 |
commit | ba0b2492269ea81e91f7ce4fb8da618187a3997f (patch) | |
tree | 4c3da08b9c7897ff04efc08b1fa8aba4ab4975b4 | |
parent | e650ca36da5cf7614e4f1a0a524eadb46b1cc21d (diff) |
first pass at UTS
-rw-r--r-- | src/smi_exa.c | 75 |
1 files changed, 65 insertions, 10 deletions
diff --git a/src/smi_exa.c b/src/smi_exa.c index 759f145..947714c 100644 --- a/src/smi_exa.c +++ b/src/smi_exa.c @@ -444,26 +444,81 @@ SMI_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, { ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; SMIPtr pSmi = SMIPTR(pScrn); + int i, j, dwords, Bpp, queue, dst_pitch; + CARD32 *srcp, *dataport; + unsigned long dst_offset; ENTER_PROC("SMI_UploadToScreen"); DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d src=%d src_pitch=%d\n", x, y, w, h, src, src_pitch)); - char *dst = pDst->devPrivate.ptr; - int dst_pitch = exaGetPixmapPitch(pDst); + /* calculate pitch in pixel unit */ + dst_pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel >> 3); + /* calculate offset in 8 byte (64 bit) unit */ + dst_offset = exaGetPixmapOffset(pDst) >> 3; - exaWaitSync(pDst->drawable.pScreen); + Bpp = pDst->drawable.bitsPerPixel / 8; + dwords = (((w * Bpp) + 3) >> 2) * h; - dst += (y * dst_pitch) + (x * pSmi->Bpp); - w *= pSmi->Bpp; + pSmi->AccelCmd = 0xCC /* GXcopy */ + | SMI_HOSTBLT_WRITE + | SMI_START_ENGINE; - while (h--) { - memcpy(dst, src, w); - src += src_pitch; - dst += dst_pitch; + + WaitQueue(1); + /* Destination Window Width */ + WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16)); + + if (pDst->drawable.bitsPerPixel == 24) { + x *= 3; + w *= 3; + dst_pitch *= 3; + if (pSmi->Chipset == SMI_LYNX) { + y *= 3; + } } - return TRUE; + WaitQueue(9); + /* Destination Row Pitch */ + WRITE_DPR(pSmi, 0x10, (dst_pitch << 16)); + /* Drawing engine data format */ + WRITE_DPR(pSmi, 0x1C, SMI_DEDataFormat(pDst)); + /* Destination Base Address (offset) */ + WRITE_DPR(pSmi, 0x44, dst_offset); + + /* set l/r clipping */ + WRITE_DPR(pSmi, 0x2C, (0xFFFF0000 | x | 0x2000)); + WRITE_DPR(pSmi, 0x30, (0xFFFF0000 | (x + w))); + + WRITE_DPR(pSmi, 0x00, 0); + WRITE_DPR(pSmi, 0x04, (x << 16) | (y * 0xFFFF)); + WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF)); + WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); + + srcp = (CARD32 *)src; + dataport = (CARD32 *)pSmi->DataPortBase; + queue = pSmi->DataPortSize; + while (dwords) { + if (queue < 4) { + /* XXX: check if the hw is ok with this */ + dataport = (CARD32 *)pSmi->DataPortBase; + queue = pSmi->DataPortSize; + } + memcpy(dataport, srcp, 4); + queue -= 4; + dwords--; + srcp++; + dataport++; + } + + WaitQueue(1); + /* disable clipping */ + WRITE_DPR(pSmi, 0x2C, 0); + + exaWaitSync(pDst->drawable.pScreen); + LEAVE_PROC("SMI_UploadToScreen"); + + return TRUE; } |