summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2003-12-28 09:16:52 +0000
committerEric Anholt <anholt@freebsd.org>2003-12-28 09:16:52 +0000
commit4b846df995820fbe22054d6e8f991ca21d295e75 (patch)
treeff02adec0da0938a1d5242e0d285bb197c7a0c04
parentafd080a9cc746f297aa8b97aedf0d230367e6719 (diff)
- Allow acceleration between same-depth pixmaps, rather than between
anything and a dst that matched the screen depth (fixes corruption for non-screen-depth src and makes more acceleration possible). - Add ATI_FALLBACK macro and use it to allow verbose descriptions of why hardware acceleration fails. - Check that src and dst alignment meet requirements of the card before accelerating. The BIOS may set up screens that don't meet the requirements. - Fix the R128 offset alignment (32 bytes, not 8). - Enable Blend operation even if screen is 24bpp (it will fail if the dest is 24bpp anyway).
-rw-r--r--hw/kdrive/ati/ati.h7
-rw-r--r--hw/kdrive/ati/ati_draw.c78
-rw-r--r--hw/kdrive/ati/ati_draw.h10
-rw-r--r--hw/kdrive/ati/ati_drawtmp.h59
-rw-r--r--hw/kdrive/ati/ati_dri.c2
-rw-r--r--hw/kdrive/ati/r128_blendtmp.h18
6 files changed, 103 insertions, 71 deletions
diff --git a/hw/kdrive/ati/ati.h b/hw/kdrive/ati/ati.h
index 44e83a5ac..cacc264dd 100644
--- a/hw/kdrive/ati/ati.h
+++ b/hw/kdrive/ati/ati.h
@@ -146,13 +146,6 @@ typedef struct _ATIScreenInfo {
Bool using_dri;
Bool using_dma;
- /* 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 datatype;
- int dp_gui_master_cntl;
#ifdef USE_DRI
drmSize registerSize;
diff --git a/hw/kdrive/ati/ati_draw.c b/hw/kdrive/ati/ati_draw.c
index 6e8575ef7..5dab41ede 100644
--- a/hw/kdrive/ati/ati_draw.c
+++ b/hw/kdrive/ati/ati_draw.c
@@ -108,6 +108,10 @@ ATIScreenInfo *accel_atis;
int src_pitch;
int src_offset;
int src_bpp;
+/* 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.
+ */
+int is_24bpp;
static void
ATIWaitAvailMMIO(int n)
@@ -348,7 +352,7 @@ drmBufPtr ATIDMAGetBuffer()
#endif /* USE_DRI */
static Bool
-R128GetDatatype(CARD32 format, CARD32 *type)
+R128GetDatatypePict(CARD32 format, CARD32 *type)
{
switch (format) {
case PICT_a8r8g8b8:
@@ -364,6 +368,34 @@ R128GetDatatype(CARD32 format, CARD32 *type)
return FALSE;
}
+/* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we
+ * require src and dest datatypes to be equal.
+ */
+static Bool
+ATIGetDatatypeBpp(int bpp, CARD32 *type)
+{
+ is_24bpp = FALSE;
+
+ switch (bpp) {
+ case 8:
+ *type = R128_DATATYPE_C8;
+ return TRUE;
+ case 16:
+ *type = R128_DATATYPE_RGB_565;
+ return TRUE;
+ case 24:
+ *type = R128_DATATYPE_C8;
+ is_24bpp = TRUE;
+ return TRUE;
+ case 32:
+ *type = R128_DATATYPE_ARGB_8888;
+ return TRUE;
+ default:
+ ErrorF("Unsupported bpp: %x\n", bpp);
+ return FALSE;
+ }
+}
+
#ifdef USE_DRI
#define USE_DMA
#include "ati_drawtmp.h"
@@ -391,31 +423,6 @@ ATIDrawInit(ScreenPtr pScreen)
ATIScreenInfo(pScreenPriv);
ATICardInfo(pScreenPriv);
- switch (pScreenPriv->screen->fb[0].depth)
- {
- case 8:
- atis->datatype = 2;
- break;
- case 15:
- atis->datatype = 3;
- break;
- case 16:
- atis->datatype = 4;
- break;
- case 24:
- if (pScreenPriv->screen->fb[0].bitsPerPixel == 24) {
- atis->is_24bpp = TRUE;
- atis->datatype = 2;
- } else {
- atis->datatype = 6;
- }
- break;
- default:
- FatalError("[ati]: depth %d unsupported\n",
- pScreenPriv->screen->fb[0].depth);
- return FALSE;
- }
-
ErrorF("Screen: %d/%d depth/bpp\n", pScreenPriv->screen->fb[0].depth,
pScreenPriv->screen->fb[0].bitsPerPixel);
#ifdef USE_DRI
@@ -427,9 +434,6 @@ ATIDrawInit(ScreenPtr pScreen)
}
#endif /* USE_DRI */
- atis->dp_gui_master_cntl = (atis->datatype << 8) |
- RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_AUX_CLIP_DIS;
-
memset(&atis->kaa, 0, sizeof(KaaScreenInfoRec));
#ifdef USE_DRI
if (atis->using_dma) {
@@ -437,7 +441,7 @@ ATIDrawInit(ScreenPtr pScreen)
atis->kaa.Solid = ATISolidDMA;
atis->kaa.PrepareCopy = ATIPrepareCopyDMA;
atis->kaa.Copy = ATICopyDMA;
- if (!atic->is_radeon && !atis->is_24bpp) {
+ if (!atic->is_radeon) {
atis->kaa.PrepareBlend = R128PrepareBlendDMA;
atis->kaa.Blend = R128BlendDMA;
atis->kaa.DoneBlend = R128DoneBlendDMA;
@@ -450,7 +454,7 @@ ATIDrawInit(ScreenPtr pScreen)
atis->kaa.Solid = ATISolidMMIO;
atis->kaa.PrepareCopy = ATIPrepareCopyMMIO;
atis->kaa.Copy = ATICopyMMIO;
- if (!atic->is_radeon && !atis->is_24bpp) {
+ if (!atic->is_radeon) {
atis->kaa.PrepareBlend = R128PrepareBlendMMIO;
atis->kaa.Blend = R128BlendMMIO;
atis->kaa.DoneBlend = R128DoneBlendMMIO;
@@ -463,13 +467,11 @@ ATIDrawInit(ScreenPtr pScreen)
atis->kaa.offscreenByteAlign = 1024;
atis->kaa.offscreenPitch = 1024;
} else {
- atis->kaa.offscreenByteAlign = 8;
- /* Workaround for corrupation at 8 and 24bpp. Why? */
- if (atis->datatype == 2)
- atis->kaa.offscreenPitch = 16;
- else
- atis->kaa.offscreenPitch =
- pScreenPriv->screen->fb[0].bitsPerPixel;
+ atis->kaa.offscreenByteAlign = 32;
+ /* Pitch alignment is in sets of 8 pixels, and we need to cover
+ * 32bpp, so 32 bytes.
+ */
+ atis->kaa.offscreenPitch = 32;
}
if (!kaaDrawInit(pScreen, &atis->kaa))
return FALSE;
diff --git a/hw/kdrive/ati/ati_draw.h b/hw/kdrive/ati/ati_draw.h
index 95b3b875c..eddc8721e 100644
--- a/hw/kdrive/ati/ati_draw.h
+++ b/hw/kdrive/ati/ati_draw.h
@@ -69,4 +69,14 @@ void ATIDMAStop(ScreenPtr pScreen);
#endif /* USE_DRI */
+#if 0
+#define ATI_FALLBACK(x) \
+do { \
+ ErrorF x; \
+ return FALSE; \
+} while (0)
+#else
+#define ATI_FALLBACK(x) return FALSE
+#endif
+
#endif /* _ATI_DRAW_H_ */
diff --git a/hw/kdrive/ati/ati_drawtmp.h b/hw/kdrive/ati/ati_drawtmp.h
index 6573aef68..a8a0a7dac 100644
--- a/hw/kdrive/ati/ati_drawtmp.h
+++ b/hw/kdrive/ati/ati_drawtmp.h
@@ -32,7 +32,8 @@
#define END() ADVANCE_RING()
#else
#define TAG(x) x##MMIO
-#define LOCALS char *mmio = atic->reg_base
+#define LOCALS (void)atis; \
+ char *mmio = atic->reg_base
#define BEGIN(x) ATIWaitAvailMMIO(x)
#define OUT_REG(reg, val) MMIO_OUT32((mmio), (reg), (val))
#define END()
@@ -45,22 +46,27 @@ TAG(ATISetup)(PixmapPtr pDst, PixmapPtr pSrc)
ATIScreenInfo(pScreenPriv);
ATICardInfo(pScreenPriv);
int dst_offset, dst_pitch;
- int bpp = pScreenPriv->screen->fb[0].bitsPerPixel;
+ int bpp = pDst->drawable.bitsPerPixel;
LOCALS;
accel_atis = atis;
- /* 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 ((dst_pitch & (atis->kaa.offscreenPitch - 1)) != 0)
+ ATI_FALLBACK(("Bad dst pitch 0x%x\n", dst_pitch));
+ if ((dst_offset & (atis->kaa.offscreenByteAlign - 1)) != 0)
+ ATI_FALLBACK(("Bad dst offset 0x%x\n", dst_offset));
+
if (pSrc != NULL) {
src_pitch = pSrc->devKind;
src_offset = ((CARD8 *)pSrc->devPrivate.ptr -
pScreenPriv->screen->memory_base);
+ if ((src_pitch & (atis->kaa.offscreenPitch - 1)) != 0)
+ ATI_FALLBACK(("Bad src pitch 0x%x\n", src_pitch));
+ if ((src_offset & (atis->kaa.offscreenByteAlign - 1)) != 0)
+ ATI_FALLBACK(("Bad src offset 0x%x\n", src_offset));
}
BEGIN((pSrc != NULL) ? 3 : 2);
@@ -72,7 +78,7 @@ TAG(ATISetup)(PixmapPtr pDst, PixmapPtr pSrc)
((src_pitch >> 6) << 22) | (src_offset >> 10));
}
} else {
- if (atis->is_24bpp) {
+ if (is_24bpp) {
dst_pitch *= 3;
src_pitch *= 3;
}
@@ -97,25 +103,31 @@ TAG(ATIPrepareSolid)(PixmapPtr pPixmap, int alu, Pixel pm, Pixel fg)
KdScreenPriv(pPixmap->drawable.pScreen);
ATIScreenInfo(pScreenPriv);
ATICardInfo(pScreenPriv);
+ CARD32 datatype;
LOCALS;
- if (atis->is_24bpp) {
- if (pm != 0xffffffff)
- return FALSE;
+ if (is_24bpp) {
/* Solid fills in fake-24bpp mode only work if the pixel color
- * is all the same byte.
+ * and planemask are all the same byte.
*/
if ((fg & 0xffffff) != (((fg & 0xff) << 16) | ((fg >> 8) &
0xffff)))
- return FALSE;
+ ATI_FALLBACK(("Can't do solid color %d in 24bpp\n"));
+ if ((pm & 0xffffff) != (((pm & 0xff) << 16) | ((pm >> 8) &
+ 0xffff)))
+ ATI_FALLBACK(("Can't do planemask %d in 24bpp\n"));
}
+ if (!ATIGetDatatypeBpp(pPixmap->drawable.bitsPerPixel, &datatype))
+ return FALSE;
if (!TAG(ATISetup)(pPixmap, NULL))
return FALSE;
BEGIN(4);
OUT_REG(RADEON_REG_DP_GUI_MASTER_CNTL,
- atis->dp_gui_master_cntl |
+ (datatype << 8) |
+ RADEON_GMC_CLR_CMP_CNTL_DIS |
+ RADEON_GMC_AUX_CLIP_DIS |
RADEON_GMC_BRUSH_SOLID_COLOR |
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
RADEON_GMC_SRC_DATATYPE_COLOR |
@@ -136,7 +148,7 @@ TAG(ATISolid)(int x1, int y1, int x2, int y2)
ATICardInfo *atic = atis->atic;
LOCALS;
- if (atis->is_24bpp) {
+ if (is_24bpp) {
x1 *= 3;
x2 *= 3;
}
@@ -152,20 +164,31 @@ TAG(ATIPrepareCopy)(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, Pix
KdScreenPriv(pDst->drawable.pScreen);
ATIScreenInfo(pScreenPriv);
ATICardInfo(pScreenPriv);
+ CARD32 datatype;
LOCALS;
+ /* No acceleration between different formats */
+ if (pSrc->drawable.bitsPerPixel != pDst->drawable.bitsPerPixel)
+ ATI_FALLBACK(("src bpp != dst bpp (%d vs %d)\n",
+ pSrc->drawable.bitsPerPixel, pDst->drawable.bitsPerPixel));
+
copydx = dx;
copydy = dy;
- if (atis->is_24bpp && pm != 0xffffffff)
- return FALSE;
+ if (is_24bpp && ((pm & 0xffffff) != (((pm & 0xff) << 16) | ((pm >> 8) &
+ 0xffff))))
+ ATI_FALLBACK(("Can't do planemask %d in 24bpp\n"));
+ if (!ATIGetDatatypeBpp(pDst->drawable.bitsPerPixel, &datatype))
+ return FALSE;
if (!TAG(ATISetup)(pDst, pSrc))
return FALSE;
BEGIN(3);
OUT_REG(RADEON_REG_DP_GUI_MASTER_CNTL,
- atis->dp_gui_master_cntl |
+ (datatype << 8) |
+ RADEON_GMC_CLR_CMP_CNTL_DIS |
+ RADEON_GMC_AUX_CLIP_DIS |
RADEON_GMC_BRUSH_SOLID_COLOR |
RADEON_GMC_SRC_DATATYPE_COLOR |
(ATIBltRop[alu] << 16) |
@@ -188,7 +211,7 @@ TAG(ATICopy)(int srcX, int srcY, int dstX, int dstY, int w, int h)
ATICardInfo *atic = atis->atic;
LOCALS;
- if (atis->is_24bpp) {
+ if (is_24bpp) {
srcX *= 3;
dstX *= 3;
w *= 3;
diff --git a/hw/kdrive/ati/ati_dri.c b/hw/kdrive/ati/ati_dri.c
index e289573f8..65ca0f72e 100644
--- a/hw/kdrive/ati/ati_dri.c
+++ b/hw/kdrive/ati/ati_dri.c
@@ -449,7 +449,7 @@ static void ATIDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
{
KdScreenPriv(pScreen);
ATIScreenInfo(pScreenPriv);
- ATICardInfo(pScreenPriv);
+
if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) &&
(newContextType==DRI_2D_CONTEXT)) {
/* Entering from Wakeup */
diff --git a/hw/kdrive/ati/r128_blendtmp.h b/hw/kdrive/ati/r128_blendtmp.h
index e40aaf4c0..ede48fe4c 100644
--- a/hw/kdrive/ati/r128_blendtmp.h
+++ b/hw/kdrive/ati/r128_blendtmp.h
@@ -56,13 +56,17 @@ TAG(R128PrepareBlend)(int op, PicturePtr pSrcPicture, PicturePtr pDstPicture,
src_bpp = pSrc->drawable.bitsPerPixel;
if (op >= sizeof(R128BlendOp)/sizeof(R128BlendOp[0]))
- return FALSE;
- if (pSrcPicture->repeat || pSrcPicture->transform != NULL)
- return FALSE;
-
- if (!R128GetDatatype(pDstPicture->format, &dstDatatype) ||
- !R128GetDatatype(pSrcPicture->format, &srcDatatype))
- return FALSE;
+ ATI_FALLBACK(("Unsupported op 0x%x\n", op));
+ if (pSrcPicture->repeat)
+ ATI_FALLBACK(("repeat unsupported\n"));
+ if (pSrcPicture->transform != NULL)
+ ATI_FALLBACK(("transform unsupported\n"));
+ if (!R128GetDatatypePict(pDstPicture->format, &dstDatatype))
+ ATI_FALLBACK(("Unsupported dest format 0x%x\n",
+ pDstPicture->format));
+ if (!R128GetDatatypePict(pSrcPicture->format, &srcDatatype))
+ ATI_FALLBACK(("Unsupported src format 0x%x\n",
+ pSrcPicture->format));
BEGIN(11);
OUT_REG(RADEON_REG_DP_GUI_MASTER_CNTL,