summaryrefslogtreecommitdiff
path: root/src/smi_shadow.c
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-25 19:28:39 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-25 19:28:39 +0000
commit14cd4af100e1deb1c7b63e9f19587e38ce1f08f2 (patch)
treee8af016d0a4e5289a95542db236ec18f86925171 /src/smi_shadow.c
parent1684aa7a21a194b6e7dd518f3895c9b2dfce229a (diff)
XFree86 4.3.99.16 Bring the tree up to date for the Cygwin folksxf86-4_3_99_901xf86-4_3_99_16
Diffstat (limited to 'src/smi_shadow.c')
-rw-r--r--src/smi_shadow.c158
1 files changed, 157 insertions, 1 deletions
diff --git a/src/smi_shadow.c b/src/smi_shadow.c
index 5ef9ba5..ed7372b 100644
--- a/src/smi_shadow.c
+++ b/src/smi_shadow.c
@@ -26,7 +26,7 @@ Silicon Motion shall not be used in advertising or otherwise to promote the
sale, use or other dealings in this Software without prior written
authorization from the XFree86 Project and Silicon Motion.
*/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_shadow.c,v 1.2 2000/12/05 21:18:37 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_shadow.c,v 1.3 2003/10/08 11:13:01 eich Exp $ */
#include "xf86.h"
#include "xf86_OSproc.h"
@@ -181,6 +181,162 @@ void SMI_RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
LEAVE_PROC("SMI_RefreshArea");
}
+/* Custom version for the 730 series (Cougar3DR).
+ This chipset has problems with large rotate-blts. */
+
+void SMI_RefreshArea730(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ SMIPtr pSmi = SMIPTR(pScrn);
+ int width, height, srcX, srcY, destX, destY;
+ int maxPixels, tempWidth;
+
+ ENTER_PROC("SMI_RefreshArea730");
+
+ /* #671 */
+ if (pSmi->polyLines)
+ {
+ pSmi->polyLines = FALSE;
+ return;
+ }
+
+ if (pSmi->rotate)
+ {
+ /* IF we need to do rotation, setup the hardware here. */
+ WaitIdleEmpty();
+ WRITE_DPR(pSmi, 0x10, pSmi->ShadowPitch);
+ WRITE_DPR(pSmi, 0x3C, pSmi->ShadowPitch);
+ WRITE_DPR(pSmi, 0x44, pSmi->FBOffset >> 3);
+ }
+
+ /* #672 */
+ if (pSmi->ClipTurnedOn)
+ {
+ WaitQueue(1);
+ WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
+ pSmi->ClipTurnedOn = FALSE;
+ }
+
+ /* SM731 cannot rotate-blt more than a certain number of pixels
+ (based on a calculation from the Windows driver source */
+ maxPixels = 1280 / pScrn->bitsPerPixel;
+
+ while (num--)
+ {
+ /* Get coordinates of the box to refresh. */
+ srcX = pbox->x1;
+ srcY = pbox->y1;
+ width = pbox->x2 - srcX;
+ height = pbox->y2 - srcY;
+
+ DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d\n", srcX, srcY, width, height));
+
+ if ((width > 0) && (height > 0))
+ {
+ switch (pSmi->rotate)
+ {
+ case SMI_ROTATE_CW:
+ /* 90 degrees CW rotation. Calculate destination
+ coordinates:
+
+ *---+
+ | | +-----*
+ | | | | destX = shadowHeight - srcY - 1
+ | | --> | | destY = srcX
+ | | | |
+ | | +-----+
+ +---+
+ */
+ destX = pSmi->ShadowHeight - srcY - 1;
+ destY = srcX;
+
+ for (tempWidth=width; tempWidth>0;)
+ {
+ if (width>maxPixels)
+ width = maxPixels;
+ WaitQueue(4);
+ WRITE_DPR(pSmi, 0x00, (srcX << 16) + srcY);
+ WRITE_DPR(pSmi, 0x04, (destX << 16) + destY);
+ WRITE_DPR(pSmi, 0x08, (width << 16) + height);
+ WRITE_DPR(pSmi, 0x0C, 0xCC | SMI_ROTATE_BLT |
+ SMI_ROTATE_CW | SMI_START_ENGINE);
+ destY += maxPixels;
+ srcX += maxPixels;
+ tempWidth -= maxPixels;
+ width = tempWidth;
+ }
+
+ break;
+
+ case SMI_ROTATE_CCW:
+ /* 90 degrees CCW rotatation. Calculate destination
+ coordinates:
+
+ *---+
+ | | +-----+
+ | | | | destX = srcY
+ | | --> | | destY = shadowWidth - srcX - 1
+ | | | |
+ | | *-----+
+ +---+
+ */
+ destX = srcY;
+ destY = pSmi->ShadowWidth - srcX - 1;
+
+ for (tempWidth=width; tempWidth>0;)
+ {
+ if (width>maxPixels)
+ width = maxPixels;
+ WaitQueue(4);
+ WRITE_DPR(pSmi, 0x00, (srcX << 16) + srcY);
+ WRITE_DPR(pSmi, 0x04, (destX << 16) + destY);
+ WRITE_DPR(pSmi, 0x08, (width << 16) + height);
+ WRITE_DPR(pSmi, 0x0C, 0xCC | SMI_ROTATE_BLT |
+ SMI_ROTATE_CCW | SMI_START_ENGINE);
+ destY -= maxPixels;
+ srcX += maxPixels;
+ tempWidth -= maxPixels;
+ width = tempWidth;
+ }
+
+ break;
+
+ default:
+ /* No rotation, perform a normal copy. */
+ if (pScrn->bitsPerPixel == 24)
+ {
+ srcX *= 3;
+ width *= 3;
+
+ if (pSmi->Chipset == SMI_LYNX)
+ {
+ srcY *= 3;
+ }
+ }
+
+ WaitQueue(4);
+ WRITE_DPR(pSmi, 0x00, (srcX << 16) + srcY);
+ WRITE_DPR(pSmi, 0x04, (srcX << 16) + srcY);
+ WRITE_DPR(pSmi, 0x08, (width << 16) + height);
+ WRITE_DPR(pSmi, 0x0C, SMI_BITBLT + SMI_START_ENGINE + 0xCC);
+ break;
+ }
+ }
+
+ pbox++;
+ }
+
+ if (pSmi->rotate)
+ {
+ /* If we did a rotation, we need to restore the hardware state here. */
+ WaitIdleEmpty();
+ WRITE_DPR(pSmi, 0x10, (pSmi->Stride << 16) | pSmi->Stride);
+ WRITE_DPR(pSmi, 0x3C, (pSmi->Stride << 16) | pSmi->Stride);
+ WRITE_DPR(pSmi, 0x44, 0);
+ }
+
+ LEAVE_PROC("SMI_RefreshArea730");
+}
+
/******************************************************************************\
|* SMI_PointerMoved
|*=============================================================================