summaryrefslogtreecommitdiff
path: root/src/smi_exa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/smi_exa.c')
-rw-r--r--src/smi_exa.c67
1 files changed, 33 insertions, 34 deletions
diff --git a/src/smi_exa.c b/src/smi_exa.c
index da3e36b..2c902be 100644
--- a/src/smi_exa.c
+++ b/src/smi_exa.c
@@ -96,6 +96,14 @@ SMI_EXAInit(ScreenPtr pScreen)
pSmi->EXADriverPtr->maxX = 4096;
pSmi->EXADriverPtr->maxY = 4096;
+ if (pScrn->bitsPerPixel == 24) {
+ pSmi->EXADriverPtr->maxX = 4096 / 3;
+
+ if (pSmi->Chipset == SMI_LYNX) {
+ pSmi->EXADriverPtr->maxY = 4096 / 3;
+ }
+ }
+
pSmi->EXADriverPtr->pixmapPitchAlign = 16;
pSmi->EXADriverPtr->pixmapOffsetAlign = 8;
@@ -112,8 +120,8 @@ SMI_EXAInit(ScreenPtr pScreen)
pSmi->EXADriverPtr->Solid = SMI_Solid;
pSmi->EXADriverPtr->DoneSolid = SMI_DoneSolid;
- /* DFS & UTS */
#if 0
+ /* DFS & UTS */
pSmi->EXADriverPtr->UploadToScreen = SMI_UploadToScreen;
pSmi->EXADriverPtr->DownloadFromScreen = SMI_DownloadFromScreen;
#endif
@@ -460,30 +468,37 @@ 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;
+ int dst_pitch, source_pitch, align, aligned_pitch;
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));
+ if (pDst->drawable.bitsPerPixel == 24) {
+ align = 16;
+ } else {
+ align = 128 / pDst->drawable.bitsPerPixel;
+ }
+
+ aligned_pitch = (src_pitch + align - 1) & ~(align - 1);
+
/* calculate pitch in pixel unit */
dst_pitch = exaGetPixmapPitch(pDst) / (pDst->drawable.bitsPerPixel >> 3);
+ source_pitch = aligned_pitch / (pDst->drawable.bitsPerPixel >> 3);
/* calculate offset in 8 byte (64 bit) unit */
dst_offset = exaGetPixmapOffset(pDst) >> 3;
- Bpp = pDst->drawable.bitsPerPixel / 8;
- dwords = (((w * Bpp) + 3) >> 2) * h;
-
pSmi->AccelCmd = 0xCC /* GXcopy */
| SMI_HOSTBLT_WRITE
| SMI_QUICK_START;
+ /* set clipping */
+ SMI_SetClippingRectangle(pScrn, x, y, x+w, y+h);
- WaitQueue(1);
- /* Destination Window Width */
- WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16));
+ WaitQueue(7);
+ /* Destination and Source Window Widths */
+ WRITE_DPR(pSmi, 0x3C, (dst_pitch << 16) | (source_pitch & 0xFFFF));
if (pDst->drawable.bitsPerPixel == 24) {
x *= 3;
@@ -494,43 +509,27 @@ SMI_UploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
}
}
- WaitQueue(9);
- /* Destination Row Pitch */
- WRITE_DPR(pSmi, 0x10, (dst_pitch << 16));
+ /* Source and Destination Row Pitch */
+ WRITE_DPR(pSmi, 0x10, (dst_pitch << 16) | (source_pitch & 0xFFFF));
/* Drawing engine data format */
WRITE_DPR(pSmi, 0x1C, SMI_DEDataFormat(pDst));
- /* Destination Base Address (offset) */
+ /* Source and Destination Base Address (offset) */
+ WRITE_DPR(pSmi, 0x44, 0);
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, 0x0C, pSmi->AccelCmd);
WRITE_DPR(pSmi, 0x00, 0);
WRITE_DPR(pSmi, 0x04, (x << 16) | (y * 0xFFFF));
WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF));
-
- 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++;
+ while (h--) {
+ WaitQueue(aligned_pitch);
+ memcpy(pSmi->DataPortBase, src, aligned_pitch);
+ src += src_pitch;
}
- WaitQueue(1);
/* disable clipping */
- WRITE_DPR(pSmi, 0x2C, 0);
+ SMI_DisableClipping(pScrn);
exaWaitSync(pDst->drawable.pScreen);