- Fix a bug in pitch alignment for offscren pixmaps.

- Add 24-bit acceleration for Xati using the 8-bit trick from mach64.
- Add offscreen pixmap support to Xati.
This commit is contained in:
Eric Anholt 2003-11-20 07:49:46 +00:00
parent 41dde24b22
commit b3247251fb
5 changed files with 112 additions and 40 deletions

View File

@ -69,7 +69,10 @@ struct pci_id_list radeon_id_list[] = {
{0x1002, 0x4e53, "ATI Radeon Mobility RV350 NS"}, {0x1002, 0x4e53, "ATI Radeon Mobility RV350 NS"},
{0x1002, 0x4e54, "ATI Radeon Mobility RV350 NT"}, {0x1002, 0x4e54, "ATI Radeon Mobility RV350 NT"},
{0x1002, 0x4e56, "ATI Radeon Mobility RV350 NV"}, {0x1002, 0x4e56, "ATI Radeon Mobility RV350 NV"},
{0x1002, 0x5144, "ATI Radeon QD"}, {0x1002, 0x5144, "ATI Radeon R100 QD"},
{0x1002, 0x5145, "ATI Radeon R100 QE"},
{0x1002, 0x5146, "ATI Radeon R100 QF"},
{0x1002, 0x5147, "ATI Radeon R100 QG"},
{0x1002, 0x5148, "ATI Radeon R200 QH"}, {0x1002, 0x5148, "ATI Radeon R200 QH"},
{0x1002, 0x514c, "ATI Radeon R200 QL"}, {0x1002, 0x514c, "ATI Radeon R200 QL"},
{0x1002, 0x514d, "ATI Radeon R200 QM"}, {0x1002, 0x514d, "ATI Radeon R200 QM"},

View File

@ -58,7 +58,6 @@ typedef struct _ATIScreenInfo {
CARD8 *off_screen; CARD8 *off_screen;
int off_screen_size; int off_screen_size;
int pitch;
int datatype; int datatype;
int dp_gui_master_cntl; int dp_gui_master_cntl;
} ATIScreenInfo; } ATIScreenInfo;

View File

@ -69,7 +69,11 @@ CARD8 ATIBltRop[16] = {
}; };
int copydx, copydy; int copydx, copydy;
int is_radeon; Bool is_radeon;
/* If is_24bpp is set, then we are using the accelerator in 8-bit mode due
* to it being broken for 24bpp, so coordinates have to be multiplied by 3.
*/
Bool is_24bpp;
int fifo_size; int fifo_size;
char *mmio; char *mmio;
CARD32 bltCmd; CARD32 bltCmd;
@ -154,25 +158,54 @@ ATIWaitIdle(void)
R128WaitIdle(); R128WaitIdle();
} }
static void static Bool
ATISetup(ScreenPtr pScreen) ATISetup(ScreenPtr pScreen, PixmapPtr pDst, PixmapPtr pSrc)
{ {
KdScreenPriv(pScreen); KdScreenPriv(pScreen);
ATICardInfo(pScreenPriv); ATICardInfo(pScreenPriv);
ATIScreenInfo(pScreenPriv); int dst_offset, dst_pitch, src_offset = 0, src_pitch = 0;
int bpp = pScreenPriv->screen->fb[0].bitsPerPixel;
mmio = atic->reg_base; mmio = atic->reg_base;
ATIWaitAvail(5); /* No acceleration for other formats (yet) */
if (pDst->drawable.bitsPerPixel != bpp)
return FALSE;
dst_pitch = pDst->devKind;
dst_offset = ((CARD8 *)pDst->devPrivate.ptr -
pScreenPriv->screen->memory_base);
if (pSrc != NULL) {
src_pitch = pSrc->devKind;
src_offset = ((CARD8 *)pSrc->devPrivate.ptr -
pScreenPriv->screen->memory_base);
}
ATIWaitAvail(3);
if (is_radeon) { if (is_radeon) {
MMIO_OUT32(mmio, RADEON_REG_DEFAULT_OFFSET, atis->pitch << 16); MMIO_OUT32(mmio, RADEON_REG_DST_PITCH_OFFSET,
((dst_pitch >> 6) << 22) | (dst_offset >> 10));
if (pSrc != NULL) {
MMIO_OUT32(mmio, RADEON_REG_SRC_PITCH_OFFSET,
((src_pitch >> 6) << 22) | (src_offset >> 10));
}
} else { } else {
MMIO_OUT32(mmio, RADEON_REG_DEFAULT_OFFSET, 0); if (is_24bpp) {
MMIO_OUT32(mmio, RADEON_REG_DEFAULT_PITCH, dst_pitch *= 3;
pScreenPriv->screen->width >> 3); src_pitch *= 3;
}
/* R128 pitch is in units of 8 pixels, offset in 32 bytes */
MMIO_OUT32(mmio, RADEON_REG_DST_PITCH_OFFSET,
((dst_pitch/bpp) << 21) | (dst_offset >> 5));
if (pSrc != NULL) {
MMIO_OUT32(mmio, RADEON_REG_SRC_PITCH_OFFSET,
((src_pitch/bpp) << 21) | (src_offset >> 5));
}
} }
MMIO_OUT32(mmio, RADEON_REG_DEFAULT_SC_BOTTOM_RIGHT, MMIO_OUT32(mmio, RADEON_REG_DEFAULT_SC_BOTTOM_RIGHT,
(RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX)); (RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX));
return TRUE;
} }
static Bool static Bool
@ -181,12 +214,27 @@ ATIPrepareSolid(PixmapPtr pPixmap, int alu, Pixel pm, Pixel fg)
KdScreenPriv(pPixmap->drawable.pScreen); KdScreenPriv(pPixmap->drawable.pScreen);
ATIScreenInfo(pScreenPriv); ATIScreenInfo(pScreenPriv);
ATISetup(pPixmap->drawable.pScreen); if (is_24bpp) {
if (pm != 0xffffffff)
return FALSE;
/* Solid fills in fake-24bpp mode only work if the pixel color
* is all the same byte.
*/
if ((fg & 0xffffff) != (((fg & 0xff) << 16) | ((fg >> 8) &
0xffff)))
return FALSE;
}
if (!ATISetup(pPixmap->drawable.pScreen, pPixmap, NULL))
return FALSE;
ATIWaitAvail(4); ATIWaitAvail(4);
MMIO_OUT32(mmio, RADEON_REG_DP_GUI_MASTER_CNTL, MMIO_OUT32(mmio, RADEON_REG_DP_GUI_MASTER_CNTL,
atis->dp_gui_master_cntl | RADEON_GMC_BRUSH_SOLID_COLOR | atis->dp_gui_master_cntl |
RADEON_GMC_SRC_DATATYPE_COLOR | (ATISolidRop[alu] << 16)); RADEON_GMC_BRUSH_SOLID_COLOR |
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
RADEON_GMC_SRC_DATATYPE_COLOR |
(ATISolidRop[alu] << 16));
MMIO_OUT32(mmio, RADEON_REG_DP_BRUSH_FRGD_CLR, fg); MMIO_OUT32(mmio, RADEON_REG_DP_BRUSH_FRGD_CLR, fg);
MMIO_OUT32(mmio, RADEON_REG_DP_WRITE_MASK, pm); MMIO_OUT32(mmio, RADEON_REG_DP_WRITE_MASK, pm);
MMIO_OUT32(mmio, RADEON_REG_DP_CNTL, RADEON_DST_X_LEFT_TO_RIGHT | MMIO_OUT32(mmio, RADEON_REG_DP_CNTL, RADEON_DST_X_LEFT_TO_RIGHT |
@ -198,6 +246,10 @@ ATIPrepareSolid(PixmapPtr pPixmap, int alu, Pixel pm, Pixel fg)
static void static void
ATISolid(int x1, int y1, int x2, int y2) ATISolid(int x1, int y1, int x2, int y2)
{ {
if (is_24bpp) {
x1 *= 3;
x2 *= 3;
}
ATIWaitAvail(2); ATIWaitAvail(2);
MMIO_OUT32(mmio, RADEON_REG_DST_Y_X, (y1 << 16) | x1); MMIO_OUT32(mmio, RADEON_REG_DST_Y_X, (y1 << 16) | x1);
MMIO_OUT32(mmio, RADEON_REG_DST_WIDTH_HEIGHT, ((x2 - x1) << 16) | MMIO_OUT32(mmio, RADEON_REG_DST_WIDTH_HEIGHT, ((x2 - x1) << 16) |
@ -218,10 +270,20 @@ ATIPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, Pixel pm
copydx = dx; copydx = dx;
copydy = dy; copydy = dy;
if (is_24bpp && pm != 0xffffffff)
return FALSE;
if (!ATISetup(pDst->drawable.pScreen, pDst, pSrc))
return FALSE;
ATIWaitAvail(3); ATIWaitAvail(3);
MMIO_OUT32(mmio, RADEON_REG_DP_GUI_MASTER_CNTL, MMIO_OUT32(mmio, RADEON_REG_DP_GUI_MASTER_CNTL,
atis->dp_gui_master_cntl | RADEON_GMC_BRUSH_SOLID_COLOR | atis->dp_gui_master_cntl |
RADEON_GMC_SRC_DATATYPE_COLOR | (ATIBltRop[alu] << 16) | RADEON_GMC_BRUSH_SOLID_COLOR |
RADEON_GMC_SRC_DATATYPE_COLOR |
(ATIBltRop[alu] << 16) |
RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
RADEON_DP_SRC_SOURCE_MEMORY); RADEON_DP_SRC_SOURCE_MEMORY);
MMIO_OUT32(mmio, RADEON_REG_DP_WRITE_MASK, pm); MMIO_OUT32(mmio, RADEON_REG_DP_WRITE_MASK, pm);
MMIO_OUT32(mmio, RADEON_REG_DP_CNTL, MMIO_OUT32(mmio, RADEON_REG_DP_CNTL,
@ -234,6 +296,12 @@ ATIPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, Pixel pm
static void static void
ATICopy(int srcX, int srcY, int dstX, int dstY, int w, int h) ATICopy(int srcX, int srcY, int dstX, int dstY, int w, int h)
{ {
if (is_24bpp) {
srcX *= 3;
dstX *= 3;
w *= 3;
}
if (copydx < 0) { if (copydx < 0) {
srcX += w - 1; srcX += w - 1;
dstX += w - 1; dstX += w - 1;
@ -255,7 +323,7 @@ ATIDoneCopy(void)
{ {
} }
KaaScreenInfoRec ATIKaa = { static KaaScreenInfoRec ATIKaa = {
ATIPrepareSolid, ATIPrepareSolid,
ATISolid, ATISolid,
ATIDoneSolid, ATIDoneSolid,
@ -263,6 +331,10 @@ KaaScreenInfoRec ATIKaa = {
ATIPrepareCopy, ATIPrepareCopy,
ATICopy, ATICopy,
ATIDoneCopy, ATIDoneCopy,
0, /* offscreenByteAlign */
0, /* offscreenPitch */
KAA_OFFSCREEN_PIXMAPS, /* flags */
}; };
Bool Bool
@ -270,6 +342,10 @@ ATIDrawInit(ScreenPtr pScreen)
{ {
KdScreenPriv(pScreen); KdScreenPriv(pScreen);
ATIScreenInfo(pScreenPriv); ATIScreenInfo(pScreenPriv);
ATICardInfo(pScreenPriv);
is_radeon = atic->is_radeon;
is_24bpp = FALSE;
switch (pScreenPriv->screen->fb[0].depth) switch (pScreenPriv->screen->fb[0].depth)
{ {
@ -284,28 +360,28 @@ ATIDrawInit(ScreenPtr pScreen)
break; break;
case 24: case 24:
if (pScreenPriv->screen->fb[0].bitsPerPixel == 24) { if (pScreenPriv->screen->fb[0].bitsPerPixel == 24) {
atis->datatype = 5; is_24bpp = TRUE;
ErrorF("[ati]: framebuffers at 24bpp not supported, " atis->datatype = 2;
"disabling acceleration\n");
return FALSE;
} else { } else {
atis->datatype = 6; atis->datatype = 6;
} }
break; break;
case 32:
atis->datatype = 6;
break;
default: default:
ErrorF("[ati]: acceleration unsupported at depth %d\n", FatalError("[ati]: depth %d unsupported\n",
pScreenPriv->screen->fb[0].depth); pScreenPriv->screen->fb[0].depth);
return FALSE; return FALSE;
} }
atis->dp_gui_master_cntl = (atis->datatype << 8) |
RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_AUX_CLIP_DIS;
if (pScreenPriv->screen->fb[0].bitsPerPixel == 24) { if (is_radeon) {
ATIKaa.offscreenByteAlign = 1024;
ATIKaa.offscreenPitch = 64;
} else {
ATIKaa.offscreenByteAlign = 8;
ATIKaa.offscreenPitch = pScreenPriv->screen->fb[0].bitsPerPixel;
} }
if (!kaaDrawInit(pScreen, &ATIKaa)) if (!kaaDrawInit(pScreen, &ATIKaa))
return FALSE; return FALSE;
@ -315,16 +391,6 @@ ATIDrawInit(ScreenPtr pScreen)
void void
ATIDrawEnable(ScreenPtr pScreen) ATIDrawEnable(ScreenPtr pScreen)
{ {
KdScreenPriv(pScreen);
ATIScreenInfo(pScreenPriv);
ATICardInfo(pScreenPriv);
is_radeon = atic->is_radeon;
atis->pitch = (pScreenPriv->screen->fb[0].byteStride + 0x3f) & ~0x3f;
atis->dp_gui_master_cntl = (atis->datatype << 8) |
RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_AUX_CLIP_DIS;
KdMarkSync(pScreen); KdMarkSync(pScreen);
} }

View File

@ -27,11 +27,15 @@
#define RADEON_REG_RBBM_STATUS 0x0e40 #define RADEON_REG_RBBM_STATUS 0x0e40
# define RADEON_RBBM_FIFOCNT_MASK 0x007f # define RADEON_RBBM_FIFOCNT_MASK 0x007f
# define RADEON_RBBM_ACTIVE (1 << 31) # define RADEON_RBBM_ACTIVE (1 << 31)
#define RADEON_REG_SRC_PITCH_OFFSET 0x1428
#define RADEON_REG_DST_PITCH_OFFSET 0x142c
#define RADEON_REG_SRC_Y_X 0x1434 #define RADEON_REG_SRC_Y_X 0x1434
#define RADEON_REG_DST_Y_X 0x1438 #define RADEON_REG_DST_Y_X 0x1438
#define RADEON_REG_DST_HEIGHT_WIDTH 0x143c #define RADEON_REG_DST_HEIGHT_WIDTH 0x143c
#define RADEON_REG_DP_GUI_MASTER_CNTL 0x146c #define RADEON_REG_DP_GUI_MASTER_CNTL 0x146c
#define RADEON_REG_DP_BRUSH_FRGD_CLR 0x147c #define RADEON_REG_DP_BRUSH_FRGD_CLR 0x147c
# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1)
# define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4) # define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4)
# define RADEON_GMC_BRUSH_NONE (15 << 4) # define RADEON_GMC_BRUSH_NONE (15 << 4)
# define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12) # define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12)

View File

@ -70,7 +70,7 @@ typedef struct {
#define KaaGetPixmapPriv(p) ((KaaPixmapPrivPtr)(p)->devPrivates[kaaPixmapPrivateIndex].ptr) #define KaaGetPixmapPriv(p) ((KaaPixmapPrivPtr)(p)->devPrivates[kaaPixmapPrivateIndex].ptr)
#define KaaSetPixmapPriv(p,a) ((p)->devPrivates[kaaPixmapPrivateIndex].ptr = (pointer) (a)) #define KaaSetPixmapPriv(p,a) ((p)->devPrivates[kaaPixmapPrivateIndex].ptr = (pointer) (a))
#define KaaPixmapPriv(p) KaaPixmapPrivPtr pKaaPixmap = KaaGetPixmapPriv(p) #define KaaPixmapPriv(p) KaaPixmapPrivPtr pKaaPixmap = KaaGetPixmapPriv(p)
#define KaaPixmapPitch(w) (((w) + (pKaaScr->info->offscreenPitch - 1)) & ~(pKaaScr->info->offscreenPitch - 1)) #define KaaPixmapPitch(pitch) (((pitch) + (pKaaScr->info->offscreenPitch - 1)) & ~(pKaaScr->info->offscreenPitch - 1))
#define MIN_OFFPIX_SIZE (4096) #define MIN_OFFPIX_SIZE (4096)
@ -123,7 +123,7 @@ kaaPixmapAllocArea (PixmapPtr pPixmap)
int bpp = pPixmap->drawable.bitsPerPixel; int bpp = pPixmap->drawable.bitsPerPixel;
CARD16 h = pPixmap->drawable.height; CARD16 h = pPixmap->drawable.height;
CARD16 w = pPixmap->drawable.width; CARD16 w = pPixmap->drawable.width;
int pitch = KaaPixmapPitch (w); int pitch = KaaPixmapPitch (w * bpp / 8);
pKaaPixmap->devKind = pPixmap->devKind; pKaaPixmap->devKind = pPixmap->devKind;
pKaaPixmap->devPrivate = pPixmap->devPrivate; pKaaPixmap->devPrivate = pPixmap->devPrivate;