diff options
author | Eric Anholt <anholt@freebsd.org> | 2003-12-28 09:16:52 +0000 |
---|---|---|
committer | Eric Anholt <anholt@freebsd.org> | 2003-12-28 09:16:52 +0000 |
commit | 4b846df995820fbe22054d6e8f991ca21d295e75 (patch) | |
tree | ff02adec0da0938a1d5242e0d285bb197c7a0c04 | |
parent | afd080a9cc746f297aa8b97aedf0d230367e6719 (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.h | 7 | ||||
-rw-r--r-- | hw/kdrive/ati/ati_draw.c | 78 | ||||
-rw-r--r-- | hw/kdrive/ati/ati_draw.h | 10 | ||||
-rw-r--r-- | hw/kdrive/ati/ati_drawtmp.h | 59 | ||||
-rw-r--r-- | hw/kdrive/ati/ati_dri.c | 2 | ||||
-rw-r--r-- | hw/kdrive/ati/r128_blendtmp.h | 18 |
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, |