From 5b75aae2cf1ad38556e9a55da72ad65419aa7f84 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 26 Jun 2004 04:13:03 +0000 Subject: [PATCH] Add ARGB cursor support for Radeon cards. --- hw/kdrive/ati/ati.c | 12 ++- hw/kdrive/ati/ati_cursor.c | 171 +++++++++++++++++++++++++++++++++---- hw/kdrive/ati/ati_draw.c | 3 +- hw/kdrive/ati/ati_reg.h | 1 + 4 files changed, 166 insertions(+), 21 deletions(-) diff --git a/hw/kdrive/ati/ati.c b/hw/kdrive/ati/ati.c index 06c3d7ded..1aa2e520b 100644 --- a/hw/kdrive/ati/ati.c +++ b/hw/kdrive/ati/ati.c @@ -284,6 +284,7 @@ ATIScreenInit(KdScreenInfo *screen) ATICardInfo(screen); Bool success = FALSE; int screen_size = 0; + int cursor_size; #if defined(USE_DRI) && defined(GLXEXT) int l; #endif @@ -323,11 +324,14 @@ ATIScreenInit(KdScreenInfo *screen) screen->off_screen_base = screen_size; - /* Reserve the area for the monochrome cursor. */ - if (screen->off_screen_base + - ATI_CURSOR_HEIGHT * ATI_CURSOR_PITCH * 3 <= screen->memory_size) { + if (atic->is_radeon) + cursor_size = ATI_CURSOR_HEIGHT * ATI_CURSOR_WIDTH * 4; + else + cursor_size = ATI_CURSOR_HEIGHT * ATI_CURSOR_PITCH * 2; + /* Reserve the area for the cursor. */ + if (screen->off_screen_base + cursor_size <= screen->memory_size) { atis->cursor.offset = screen->off_screen_base; - screen->off_screen_base += ATI_CURSOR_HEIGHT * ATI_CURSOR_PITCH * 2; + screen->off_screen_base += cursor_size; } #if defined(USE_DRI) && defined(GLXEXT) diff --git a/hw/kdrive/ati/ati_cursor.c b/hw/kdrive/ati/ati_cursor.c index e62e926ed..f59b4639f 100644 --- a/hw/kdrive/ati/ati_cursor.c +++ b/hw/kdrive/ati/ati_cursor.c @@ -38,6 +38,7 @@ ATIMoveCursor(ScreenPtr pScreen, int x, int y) ATICursor *pCurPriv = &atis->cursor; CARD16 xoff, yoff; CARD8 *mmio = atic->reg_base; + int stride = atic->is_radeon ? 256 : 16; if (!pCurPriv->has_cursor) return; @@ -62,11 +63,11 @@ ATIMoveCursor(ScreenPtr pScreen, int x, int y) (xoff << 16) | yoff); MMIO_OUT32(mmio, ATI_REG_CUR_HORZ_VERT_POSN, ATI_CUR_LOCK | (x << 16) | y); - MMIO_OUT32(mmio, ATI_REG_CUR_OFFSET, (pCurPriv->offset + yoff * 16)); + MMIO_OUT32(mmio, ATI_REG_CUR_OFFSET, (pCurPriv->offset + yoff * stride)); } static void -ATIAllocCursorColors(ScreenPtr pScreen) +ClassicAllocCursorColors(ScreenPtr pScreen) { KdScreenPriv(pScreen); ATIScreenInfo(pScreenPriv); @@ -91,7 +92,7 @@ ATIAllocCursorColors(ScreenPtr pScreen) } static void -ATISetCursorColors(ScreenPtr pScreen) +ClassicSetCursorColors(ScreenPtr pScreen) { KdScreenPriv(pScreen); ATICardInfo(pScreenPriv); @@ -103,8 +104,8 @@ ATISetCursorColors(ScreenPtr pScreen) MMIO_OUT32(mmio, ATI_REG_CUR_CLR1, pCurPriv->source); } -void -ATIRecolorCursor(ScreenPtr pScreen, int ndef, xColorItem *pdef) +static void +ClassicRecolorCursor(ScreenPtr pScreen, int ndef, xColorItem *pdef) { KdScreenPriv(pScreen); ATIScreenInfo(pScreenPriv); @@ -128,8 +129,8 @@ ATIRecolorCursor(ScreenPtr pScreen, int ndef, xColorItem *pdef) if (ndef == 0) return; } - ATIAllocCursorColors(pScreen); - ATISetCursorColors(pScreen); + ClassicAllocCursorColors(pScreen); + ClassicSetCursorColors(pScreen); } #define InvertBits32(v) do { \ @@ -139,7 +140,7 @@ ATIRecolorCursor(ScreenPtr pScreen, int ndef, xColorItem *pdef) } while (0) static void -ATILoadCursor(ScreenPtr pScreen, int x, int y) +ClassicLoadCursor(ScreenPtr pScreen) { KdScreenPriv(pScreen); ATICardInfo(pScreenPriv); @@ -154,7 +155,7 @@ ATILoadCursor(ScreenPtr pScreen, int x, int y) CARD32 tmp; CARD8 *mmio = atic->reg_base; - ATIAllocCursorColors(pScreen); + ClassicAllocCursorColors(pScreen); pCurPriv->pCursor = pCursor; pCurPriv->xhot = pCursor->bits->xhot; @@ -223,10 +224,120 @@ ATILoadCursor(ScreenPtr pScreen, int x, int y) MMIO_OUT32(mmio, ATI_REG_GEN_CNTL, tmp | ATI_CRTC_CUR_EN); /* Set new color */ - ATISetCursorColors(pScreen); + ClassicSetCursorColors(pScreen); - /* Move to new position */ - ATIMoveCursor(pScreen, x, y); +} + +static void +RadeonLoadCursor(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + ATICardInfo(pScreenPriv); + ATIScreenInfo(pScreenPriv); + ATICursor *pCurPriv = &atis->cursor; + CursorPtr pCursor = pCurPriv->pCursor; + CursorBitsPtr bits = pCursor->bits; + int h, w; + int x, y; + CARD32 *ram, *msk, *mskLine, *src, *srcLine; + int lwsrc; + CARD32 tmp; + CARD8 *mmio = atic->reg_base; + + pCurPriv->pCursor = pCursor; + pCurPriv->xhot = pCursor->bits->xhot; + pCurPriv->yhot = pCursor->bits->yhot; + + w = bits->width; + if (w > ATI_CURSOR_WIDTH) + w = ATI_CURSOR_WIDTH; + + h = bits->height; + if (h > ATI_CURSOR_HEIGHT) + h = ATI_CURSOR_HEIGHT; + + tmp = MMIO_IN32(mmio, ATI_REG_GEN_CNTL); + MMIO_OUT32(mmio, ATI_REG_GEN_CNTL, tmp & ~ATI_CRTC_CUR_EN); + + /* Stick new image into cursor memory */ + ram = (CARD32 *)(pScreenPriv->screen->memory_base + + pCurPriv->offset); + if (pCursor->bits->argb) + { + srcLine = pCursor->bits->argb; + for (y = 0; y < h; y++) + { + src = srcLine; + srcLine += pCursor->bits->width; + for (x = 0; x < w; x++) + *ram++ = *src++; + for (; x < ATI_CURSOR_WIDTH; x++) + *ram++ = 0; + } + for (; y < ATI_CURSOR_HEIGHT; y++) + for (x = 0; x < ATI_CURSOR_WIDTH; x++) + *ram++ = 0; + } + else + { + CARD32 colors[4]; + + colors[0] = 0; + colors[1] = 0; + colors[2] = (((pCursor->backRed >> 8) << 16) | + ((pCursor->backGreen >> 8) << 8) | + ((pCursor->backBlue >> 8) << 0) | + 0xff000000); + colors[3] = (((pCursor->foreRed >> 8) << 16) | + ((pCursor->foreGreen >> 8) << 8) | + ((pCursor->foreBlue >> 8) << 0) | + 0xff000000); + + mskLine = (CARD32 *)bits->mask; + srcLine = (CARD32 *)bits->source; + + /* words per line */ + lwsrc = BitmapBytePad(bits->width) / 4; + + for (y = 0; y < ATI_CURSOR_HEIGHT; y++) + { + CARD32 m, s; + + msk = mskLine; + src = srcLine; + mskLine += lwsrc; + srcLine += lwsrc; + + for (x = 0; x < ATI_CURSOR_WIDTH / 32; x++) + { + int k; + if (y < h && x < lwsrc) + { + m = *msk++; + s = *src++; + } + else + { + m = 0x0; + s = 0x0; + } + + for (k = 0; k < 32; k++) + { + CARD32 bits = (s & 1) | ((m & 1) << 1); + *ram++ = colors[bits]; + s >>= 1; + m >>= 1; + } + } + } + } + + /* Enable the cursor */ + tmp &= ~(ATI_CRTC_ICON_EN); + tmp |= (ATI_CRTC_ARGB_EN); + tmp |= ATI_CRTC_CUR_EN; + MMIO_OUT32(mmio, ATI_REG_GEN_CNTL, tmp); } static void @@ -245,6 +356,7 @@ static Bool ATIRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) { KdScreenPriv(pScreen); + ATICardInfo(pScreenPriv); ATIScreenInfo(pScreenPriv); ATICursor *pCurPriv = &atis->cursor; @@ -257,7 +369,12 @@ ATIRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) int x, y; miPointerPosition(&x, &y); - ATILoadCursor(pScreen, x, y); + if (atic->is_radeon) + RadeonLoadCursor (pScreen); + else + ClassicLoadCursor(pScreen); + /* Move to new position */ + ATIMoveCursor(pScreen, x, y); } return TRUE; @@ -273,6 +390,7 @@ static void ATISetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y) { KdScreenPriv(pScreen); + ATICardInfo(pScreenPriv); ATIScreenInfo(pScreenPriv); ATICursor *pCurPriv = &atis->cursor; @@ -282,7 +400,14 @@ ATISetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y) return; if (pCursor) - ATILoadCursor(pScreen, x, y); + { + if (atic->is_radeon) + RadeonLoadCursor (pScreen); + else + ClassicLoadCursor(pScreen); + /* Move to new position */ + ATIMoveCursor(pScreen, x, y); + } else ATIUnloadCursor(pScreen); } @@ -324,6 +449,7 @@ void ATICursorEnable(ScreenPtr pScreen) { KdScreenPriv(pScreen); + ATICardInfo(pScreenPriv); ATIScreenInfo(pScreenPriv); ATICursor *pCurPriv = &atis->cursor; @@ -334,7 +460,12 @@ ATICursorEnable(ScreenPtr pScreen) int x, y; miPointerPosition(&x, &y); - ATILoadCursor(pScreen, x, y); + if (atic->is_radeon) + RadeonLoadCursor(pScreen); + else + ClassicLoadCursor(pScreen); + /* Move to new position */ + ATIMoveCursor(pScreen, x, y); } else ATIUnloadCursor(pScreen); @@ -380,6 +511,16 @@ ATICursorInit(ScreenPtr pScreen) return TRUE; } +void +ATIRecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef) +{ + KdScreenPriv(pScreen); + ATICardInfo(pScreenPriv); + + if (!atic->is_radeon) + ClassicRecolorCursor (pScreen, ndef, pdef); +} + void ATICursorFini(ScreenPtr pScreen) { diff --git a/hw/kdrive/ati/ati_draw.c b/hw/kdrive/ati/ati_draw.c index d22b8685a..1f378b9e3 100644 --- a/hw/kdrive/ati/ati_draw.c +++ b/hw/kdrive/ati/ati_draw.c @@ -795,9 +795,8 @@ void ATIDrawFini(ScreenPtr pScreen) { KdScreenPriv(pScreen); - ATIScreenInfo(pScreenPriv); - #ifdef USE_DRI + ATIScreenInfo(pScreenPriv); if (atis->using_dri) { ATIDRICloseScreen(pScreen); atis->using_dri = FALSE; diff --git a/hw/kdrive/ati/ati_reg.h b/hw/kdrive/ati/ati_reg.h index 36eba9a0e..5b5279596 100644 --- a/hw/kdrive/ati/ati_reg.h +++ b/hw/kdrive/ati/ati_reg.h @@ -49,6 +49,7 @@ # define ATI_CRTC_CUR_EN (1 << 16) # define ATI_CRTC_CUR_MODE_MASK (7 << 17) # define ATI_CRTC_ICON_EN (1 << 20) +# define ATI_CRTC_ARGB_EN (2 << 20) # define ATI_CRTC_EXT_DISP_EN (1 << 24) # define ATI_CRTC_EN (1 << 25) # define ATI_CRTC_DISP_REQ_EN_B (1 << 26)