Add ARGB cursor support for Radeon cards.

This commit is contained in:
Keith Packard 2004-06-26 04:13:03 +00:00
parent 8bc0bc6d36
commit 5b75aae2cf
4 changed files with 166 additions and 21 deletions

View File

@ -284,6 +284,7 @@ ATIScreenInit(KdScreenInfo *screen)
ATICardInfo(screen); ATICardInfo(screen);
Bool success = FALSE; Bool success = FALSE;
int screen_size = 0; int screen_size = 0;
int cursor_size;
#if defined(USE_DRI) && defined(GLXEXT) #if defined(USE_DRI) && defined(GLXEXT)
int l; int l;
#endif #endif
@ -323,11 +324,14 @@ ATIScreenInit(KdScreenInfo *screen)
screen->off_screen_base = screen_size; screen->off_screen_base = screen_size;
/* Reserve the area for the monochrome cursor. */ if (atic->is_radeon)
if (screen->off_screen_base + cursor_size = ATI_CURSOR_HEIGHT * ATI_CURSOR_WIDTH * 4;
ATI_CURSOR_HEIGHT * ATI_CURSOR_PITCH * 3 <= screen->memory_size) { 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; 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) #if defined(USE_DRI) && defined(GLXEXT)

View File

@ -38,6 +38,7 @@ ATIMoveCursor(ScreenPtr pScreen, int x, int y)
ATICursor *pCurPriv = &atis->cursor; ATICursor *pCurPriv = &atis->cursor;
CARD16 xoff, yoff; CARD16 xoff, yoff;
CARD8 *mmio = atic->reg_base; CARD8 *mmio = atic->reg_base;
int stride = atic->is_radeon ? 256 : 16;
if (!pCurPriv->has_cursor) if (!pCurPriv->has_cursor)
return; return;
@ -62,11 +63,11 @@ ATIMoveCursor(ScreenPtr pScreen, int x, int y)
(xoff << 16) | yoff); (xoff << 16) | yoff);
MMIO_OUT32(mmio, ATI_REG_CUR_HORZ_VERT_POSN, ATI_CUR_LOCK | MMIO_OUT32(mmio, ATI_REG_CUR_HORZ_VERT_POSN, ATI_CUR_LOCK |
(x << 16) | y); (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 static void
ATIAllocCursorColors(ScreenPtr pScreen) ClassicAllocCursorColors(ScreenPtr pScreen)
{ {
KdScreenPriv(pScreen); KdScreenPriv(pScreen);
ATIScreenInfo(pScreenPriv); ATIScreenInfo(pScreenPriv);
@ -91,7 +92,7 @@ ATIAllocCursorColors(ScreenPtr pScreen)
} }
static void static void
ATISetCursorColors(ScreenPtr pScreen) ClassicSetCursorColors(ScreenPtr pScreen)
{ {
KdScreenPriv(pScreen); KdScreenPriv(pScreen);
ATICardInfo(pScreenPriv); ATICardInfo(pScreenPriv);
@ -103,8 +104,8 @@ ATISetCursorColors(ScreenPtr pScreen)
MMIO_OUT32(mmio, ATI_REG_CUR_CLR1, pCurPriv->source); MMIO_OUT32(mmio, ATI_REG_CUR_CLR1, pCurPriv->source);
} }
void static void
ATIRecolorCursor(ScreenPtr pScreen, int ndef, xColorItem *pdef) ClassicRecolorCursor(ScreenPtr pScreen, int ndef, xColorItem *pdef)
{ {
KdScreenPriv(pScreen); KdScreenPriv(pScreen);
ATIScreenInfo(pScreenPriv); ATIScreenInfo(pScreenPriv);
@ -128,8 +129,8 @@ ATIRecolorCursor(ScreenPtr pScreen, int ndef, xColorItem *pdef)
if (ndef == 0) if (ndef == 0)
return; return;
} }
ATIAllocCursorColors(pScreen); ClassicAllocCursorColors(pScreen);
ATISetCursorColors(pScreen); ClassicSetCursorColors(pScreen);
} }
#define InvertBits32(v) do { \ #define InvertBits32(v) do { \
@ -139,7 +140,7 @@ ATIRecolorCursor(ScreenPtr pScreen, int ndef, xColorItem *pdef)
} while (0) } while (0)
static void static void
ATILoadCursor(ScreenPtr pScreen, int x, int y) ClassicLoadCursor(ScreenPtr pScreen)
{ {
KdScreenPriv(pScreen); KdScreenPriv(pScreen);
ATICardInfo(pScreenPriv); ATICardInfo(pScreenPriv);
@ -154,7 +155,7 @@ ATILoadCursor(ScreenPtr pScreen, int x, int y)
CARD32 tmp; CARD32 tmp;
CARD8 *mmio = atic->reg_base; CARD8 *mmio = atic->reg_base;
ATIAllocCursorColors(pScreen); ClassicAllocCursorColors(pScreen);
pCurPriv->pCursor = pCursor; pCurPriv->pCursor = pCursor;
pCurPriv->xhot = pCursor->bits->xhot; 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); MMIO_OUT32(mmio, ATI_REG_GEN_CNTL, tmp | ATI_CRTC_CUR_EN);
/* Set new color */ /* 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 static void
@ -245,6 +356,7 @@ static Bool
ATIRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) ATIRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
{ {
KdScreenPriv(pScreen); KdScreenPriv(pScreen);
ATICardInfo(pScreenPriv);
ATIScreenInfo(pScreenPriv); ATIScreenInfo(pScreenPriv);
ATICursor *pCurPriv = &atis->cursor; ATICursor *pCurPriv = &atis->cursor;
@ -257,7 +369,12 @@ ATIRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
int x, y; int x, y;
miPointerPosition(&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; return TRUE;
@ -273,6 +390,7 @@ static void
ATISetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y) ATISetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
{ {
KdScreenPriv(pScreen); KdScreenPriv(pScreen);
ATICardInfo(pScreenPriv);
ATIScreenInfo(pScreenPriv); ATIScreenInfo(pScreenPriv);
ATICursor *pCurPriv = &atis->cursor; ATICursor *pCurPriv = &atis->cursor;
@ -282,7 +400,14 @@ ATISetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
return; return;
if (pCursor) if (pCursor)
ATILoadCursor(pScreen, x, y); {
if (atic->is_radeon)
RadeonLoadCursor (pScreen);
else
ClassicLoadCursor(pScreen);
/* Move to new position */
ATIMoveCursor(pScreen, x, y);
}
else else
ATIUnloadCursor(pScreen); ATIUnloadCursor(pScreen);
} }
@ -324,6 +449,7 @@ void
ATICursorEnable(ScreenPtr pScreen) ATICursorEnable(ScreenPtr pScreen)
{ {
KdScreenPriv(pScreen); KdScreenPriv(pScreen);
ATICardInfo(pScreenPriv);
ATIScreenInfo(pScreenPriv); ATIScreenInfo(pScreenPriv);
ATICursor *pCurPriv = &atis->cursor; ATICursor *pCurPriv = &atis->cursor;
@ -334,7 +460,12 @@ ATICursorEnable(ScreenPtr pScreen)
int x, y; int x, y;
miPointerPosition(&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 else
ATIUnloadCursor(pScreen); ATIUnloadCursor(pScreen);
@ -380,6 +511,16 @@ ATICursorInit(ScreenPtr pScreen)
return TRUE; return TRUE;
} }
void
ATIRecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef)
{
KdScreenPriv(pScreen);
ATICardInfo(pScreenPriv);
if (!atic->is_radeon)
ClassicRecolorCursor (pScreen, ndef, pdef);
}
void void
ATICursorFini(ScreenPtr pScreen) ATICursorFini(ScreenPtr pScreen)
{ {

View File

@ -795,9 +795,8 @@ void
ATIDrawFini(ScreenPtr pScreen) ATIDrawFini(ScreenPtr pScreen)
{ {
KdScreenPriv(pScreen); KdScreenPriv(pScreen);
ATIScreenInfo(pScreenPriv);
#ifdef USE_DRI #ifdef USE_DRI
ATIScreenInfo(pScreenPriv);
if (atis->using_dri) { if (atis->using_dri) {
ATIDRICloseScreen(pScreen); ATIDRICloseScreen(pScreen);
atis->using_dri = FALSE; atis->using_dri = FALSE;

View File

@ -49,6 +49,7 @@
# define ATI_CRTC_CUR_EN (1 << 16) # define ATI_CRTC_CUR_EN (1 << 16)
# define ATI_CRTC_CUR_MODE_MASK (7 << 17) # define ATI_CRTC_CUR_MODE_MASK (7 << 17)
# define ATI_CRTC_ICON_EN (1 << 20) # 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_EXT_DISP_EN (1 << 24)
# define ATI_CRTC_EN (1 << 25) # define ATI_CRTC_EN (1 << 25)
# define ATI_CRTC_DISP_REQ_EN_B (1 << 26) # define ATI_CRTC_DISP_REQ_EN_B (1 << 26)