summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2003-11-20 07:49:46 +0000
committerEric Anholt <anholt@freebsd.org>2003-11-20 07:49:46 +0000
commitb3247251fb7d9f2d50ef41d9c2089629544d534d (patch)
treed57947e53188524c0f407592b0f614a66219ef5f
parent41dde24b229f4bc4738637d9cd0a86b74b9f8457 (diff)
- 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.
-rw-r--r--hw/kdrive/ati/ati.c5
-rw-r--r--hw/kdrive/ati/ati.h1
-rw-r--r--hw/kdrive/ati/ati_draw.c138
-rw-r--r--hw/kdrive/ati/ati_reg.h4
-rw-r--r--hw/kdrive/src/kaa.c4
5 files changed, 112 insertions, 40 deletions
diff --git a/hw/kdrive/ati/ati.c b/hw/kdrive/ati/ati.c
index 6a41d0886..0374485ee 100644
--- a/hw/kdrive/ati/ati.c
+++ b/hw/kdrive/ati/ati.c
@@ -69,7 +69,10 @@ struct pci_id_list radeon_id_list[] = {
{0x1002, 0x4e53, "ATI Radeon Mobility RV350 NS"},
{0x1002, 0x4e54, "ATI Radeon Mobility RV350 NT"},
{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, 0x514c, "ATI Radeon R200 QL"},
{0x1002, 0x514d, "ATI Radeon R200 QM"},
diff --git a/hw/kdrive/ati/ati.h b/hw/kdrive/ati/ati.h
index 80ee26442..6e07fac22 100644
--- a/hw/kdrive/ati/ati.h
+++ b/hw/kdrive/ati/ati.h
@@ -58,7 +58,6 @@ typedef struct _ATIScreenInfo {
CARD8 *off_screen;
int off_screen_size;
- int pitch;
int datatype;
int dp_gui_master_cntl;
} ATIScreenInfo;
diff --git a/hw/kdrive/ati/ati_draw.c b/hw/kdrive/ati/ati_draw.c
index a8bd8794b..11c1a0194 100644
--- a/hw/kdrive/ati/ati_draw.c
+++ b/hw/kdrive/ati/ati_draw.c
@@ -69,7 +69,11 @@ CARD8 ATIBltRop[16] = {
};
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;
char *mmio;
CARD32 bltCmd;
@@ -154,25 +158,54 @@ ATIWaitIdle(void)
R128WaitIdle();
}
-static void
-ATISetup(ScreenPtr pScreen)
+static Bool
+ATISetup(ScreenPtr pScreen, PixmapPtr pDst, PixmapPtr pSrc)
{
KdScreenPriv(pScreen);
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;
- 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) {
- 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 {
- MMIO_OUT32(mmio, RADEON_REG_DEFAULT_OFFSET, 0);
- MMIO_OUT32(mmio, RADEON_REG_DEFAULT_PITCH,
- pScreenPriv->screen->width >> 3);
+ if (is_24bpp) {
+ dst_pitch *= 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,
(RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX));
+
+ return TRUE;
}
static Bool
@@ -181,12 +214,27 @@ ATIPrepareSolid(PixmapPtr pPixmap, int alu, Pixel pm, Pixel fg)
KdScreenPriv(pPixmap->drawable.pScreen);
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);
MMIO_OUT32(mmio, RADEON_REG_DP_GUI_MASTER_CNTL,
- atis->dp_gui_master_cntl | RADEON_GMC_BRUSH_SOLID_COLOR |
- RADEON_GMC_SRC_DATATYPE_COLOR | (ATISolidRop[alu] << 16));
+ atis->dp_gui_master_cntl |
+ 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_WRITE_MASK, pm);
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
ATISolid(int x1, int y1, int x2, int y2)
{
+ if (is_24bpp) {
+ x1 *= 3;
+ x2 *= 3;
+ }
ATIWaitAvail(2);
MMIO_OUT32(mmio, RADEON_REG_DST_Y_X, (y1 << 16) | x1);
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;
copydy = dy;
+ if (is_24bpp && pm != 0xffffffff)
+ return FALSE;
+
+ if (!ATISetup(pDst->drawable.pScreen, pDst, pSrc))
+ return FALSE;
+
ATIWaitAvail(3);
MMIO_OUT32(mmio, RADEON_REG_DP_GUI_MASTER_CNTL,
- atis->dp_gui_master_cntl | RADEON_GMC_BRUSH_SOLID_COLOR |
- RADEON_GMC_SRC_DATATYPE_COLOR | (ATIBltRop[alu] << 16) |
+ atis->dp_gui_master_cntl |
+ 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);
MMIO_OUT32(mmio, RADEON_REG_DP_WRITE_MASK, pm);
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
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) {
srcX += w - 1;
dstX += w - 1;
@@ -255,7 +323,7 @@ ATIDoneCopy(void)
{
}
-KaaScreenInfoRec ATIKaa = {
+static KaaScreenInfoRec ATIKaa = {
ATIPrepareSolid,
ATISolid,
ATIDoneSolid,
@@ -263,6 +331,10 @@ KaaScreenInfoRec ATIKaa = {
ATIPrepareCopy,
ATICopy,
ATIDoneCopy,
+
+ 0, /* offscreenByteAlign */
+ 0, /* offscreenPitch */
+ KAA_OFFSCREEN_PIXMAPS, /* flags */
};
Bool
@@ -270,6 +342,10 @@ ATIDrawInit(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
ATIScreenInfo(pScreenPriv);
+ ATICardInfo(pScreenPriv);
+
+ is_radeon = atic->is_radeon;
+ is_24bpp = FALSE;
switch (pScreenPriv->screen->fb[0].depth)
{
@@ -284,28 +360,28 @@ ATIDrawInit(ScreenPtr pScreen)
break;
case 24:
if (pScreenPriv->screen->fb[0].bitsPerPixel == 24) {
- atis->datatype = 5;
- ErrorF("[ati]: framebuffers at 24bpp not supported, "
- "disabling acceleration\n");
- return FALSE;
+ is_24bpp = TRUE;
+ atis->datatype = 2;
} else {
atis->datatype = 6;
}
break;
- case 32:
- atis->datatype = 6;
- break;
default:
- ErrorF("[ati]: acceleration unsupported at depth %d\n",
+ FatalError("[ati]: depth %d unsupported\n",
pScreenPriv->screen->fb[0].depth);
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))
return FALSE;
@@ -315,16 +391,6 @@ ATIDrawInit(ScreenPtr pScreen)
void
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);
}
diff --git a/hw/kdrive/ati/ati_reg.h b/hw/kdrive/ati/ati_reg.h
index 6a8d3e309..ac5221fe4 100644
--- a/hw/kdrive/ati/ati_reg.h
+++ b/hw/kdrive/ati/ati_reg.h
@@ -27,11 +27,15 @@
#define RADEON_REG_RBBM_STATUS 0x0e40
# define RADEON_RBBM_FIFOCNT_MASK 0x007f
# 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_DST_Y_X 0x1438
#define RADEON_REG_DST_HEIGHT_WIDTH 0x143c
#define RADEON_REG_DP_GUI_MASTER_CNTL 0x146c
#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_NONE (15 << 4)
# define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12)
diff --git a/hw/kdrive/src/kaa.c b/hw/kdrive/src/kaa.c
index 66e5fc874..c9a72a95d 100644
--- a/hw/kdrive/src/kaa.c
+++ b/hw/kdrive/src/kaa.c
@@ -70,7 +70,7 @@ typedef struct {
#define KaaGetPixmapPriv(p) ((KaaPixmapPrivPtr)(p)->devPrivates[kaaPixmapPrivateIndex].ptr)
#define KaaSetPixmapPriv(p,a) ((p)->devPrivates[kaaPixmapPrivateIndex].ptr = (pointer) (a))
#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)
@@ -123,7 +123,7 @@ kaaPixmapAllocArea (PixmapPtr pPixmap)
int bpp = pPixmap->drawable.bitsPerPixel;
CARD16 h = pPixmap->drawable.height;
CARD16 w = pPixmap->drawable.width;
- int pitch = KaaPixmapPitch (w);
+ int pitch = KaaPixmapPitch (w * bpp / 8);
pKaaPixmap->devKind = pPixmap->devKind;
pKaaPixmap->devPrivate = pPixmap->devPrivate;