From ee2778b270e2636d29059219836a2c7cf3b03c0e Mon Sep 17 00:00:00 2001 From: Owen W. Taylor Date: Sun, 6 Apr 2008 17:57:52 -0400 Subject: [PATCH] Try once again on repeats for R100/R200. Upon further investigation, matching pitch is actually needed for R100 and possibly R200 as well. Add back that test and tile if pitch does not match. --- src/radeon_exa_render.c | 82 +++++++++++++++++++++++++++++++++------------- 1 files changed, 59 insertions(+), 23 deletions(-) diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c index 8d7ff9b..7d74197 100644 --- a/src/radeon_exa_render.c +++ b/src/radeon_exa_render.c @@ -53,6 +53,9 @@ #define ONLY_ONCE #endif +/* Not yet determined */ +#undef R200_NEEDS_MATCHING_PITCH + /* Only include the following (generic) bits once. */ #ifdef ONLY_ONCE static Bool is_transform[2]; @@ -235,6 +238,18 @@ static Bool RADEONCheckTexturePOT(PicturePtr pPict, Bool canTile) return TRUE; } +static Bool RADEONPitchMatches(PixmapPtr pPix) +{ + int w = pPix->drawable.width; + int h = pPix->drawable.height; + CARD32 txpitch = exaGetPixmapPitch(pPix); + + if (h > 1 && ((w * pPix->drawable.bitsPerPixel / 8 + 31) & ~31) != txpitch) + return FALSE; + + return TRUE; +} + /* We can't turn on repeats normally for a non-power-of-two dimension, * but if the source isn't transformed, we can get the same effect * by drawing the image in multiple tiles. (A common case that it's @@ -243,28 +258,35 @@ static Bool RADEONCheckTexturePOT(PicturePtr pPict, Bool canTile) * a single tile on R300 and newer, which is perfect.) */ static Bool RADEONSetupSourceTile(PicturePtr pPict, - Bool canTile1d) + PixmapPtr pPix, + Bool canTile1d, + Bool needMatchingPitch) { - if (pPict->repeat && !pPict->transform) { + need_src_tile_x = FALSE; + need_src_tile_y = FALSE; + + if (pPict->repeat) { + Bool badPitch = needMatchingPitch && !RADEONPitchMatches(pPix); + int w = pPict->pDrawable->width; int h = pPict->pDrawable->height; - - /* On R300 and newer, we can repeat a texture that is NPOT in - * one direction and POT in the other in the POT direction; on - * older chips we can only repeat at all if the texture is POT in - * both directions. - */ - if (canTile1d) { - need_src_tile_x = (w & (w - 1)) != 0; - need_src_tile_y = (h & (h - 1)) != 0; + + if (pPict->transform) { + if (badPitch) + RADEON_FALLBACK(("Width %d and pitch %u not compatible for repeat\n", + w, (unsigned)txpitch)); } else { - need_src_tile_x = need_src_tile_y = - (w & (w - 1)) != 0 || (h & (h - 1)) != 0; + need_src_tile_x = (w & (w - 1)) != 0 || badPitch; + need_src_tile_y = (h & (h - 1)) != 0; + + /* On R300 and newer, we can repeat a texture that is NPOT in + * one direction and POT in the other in the POT direction; on + * older chips we can only repeat at all if the texture is POT in + * both directions. + */ + if (!canTile1d) + need_src_tile_x = need_src_tile_y = need_src_tile_x || need_src_tile_y; } - - } else { - need_src_tile_x = FALSE; - need_src_tile_y = FALSE; } return TRUE; @@ -330,7 +352,11 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix, if (RADEONPixmapIsColortiled(pPix)) txoffset |= RADEON_TXO_MACRO_TILE; - if (pPict->repeat) { + if (pPict->repeat && !(unit == 0 && (need_src_tile_x || need_src_tile_y))) { + if (!RADEONPitchMatches(pPix)) + RADEON_FALLBACK(("Width %d and pitch %u not compatible for repeat\n", + w, (unsigned)txpitch)); + txformat |= RADEONLog2(w) << RADEON_TXFORMAT_WIDTH_SHIFT; txformat |= RADEONLog2(h) << RADEON_TXFORMAT_HEIGHT_SHIFT; } else @@ -503,7 +529,7 @@ static Bool FUNC_NAME(R100PrepareComposite)(int op, if (((dst_pitch >> pixel_shift) & 0x7) != 0) RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch)); - if (!RADEONSetupSourceTile(pSrcPicture, FALSE)) + if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE)) return FALSE; if (!FUNC_NAME(R100TextureSetup)(pSrcPicture, pSrc, 0)) @@ -632,7 +658,13 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix, if (RADEONPixmapIsColortiled(pPix)) txoffset |= R200_TXO_MACRO_TILE; - if (pPict->repeat) { + if (pPict->repeat && !(unit == 0 && (need_src_tile_x || need_src_tile_y))) { +#ifdef R200_NEEDS_MATCHING_PITCH + if (!RADEONPitchMatches(pPix)) + RADEON_FALLBACK(("Width %d and pitch %u not compatible for repeat\n", + w, (unsigned)txpitch)); +#endif + txformat |= RADEONLog2(w) << R200_TXFORMAT_WIDTH_SHIFT; txformat |= RADEONLog2(h) << R200_TXFORMAT_HEIGHT_SHIFT; } else @@ -789,7 +821,11 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture, if (((dst_pitch >> pixel_shift) & 0x7) != 0) RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch)); - if (!RADEONSetupSourceTile(pSrcPicture, FALSE)) +#ifdef R200_NEEDS_MATCHING_PITCH + if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, TRUE)) +#else + if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, FALSE)) +#endif return FALSE; if (!FUNC_NAME(R200TextureSetup)(pSrcPicture, pSrc, 0)) @@ -896,7 +932,7 @@ static Bool R300CheckCompositeTexture(PicturePtr pPict, int unit, Bool canTile, RADEON_FALLBACK(("Unsupported picture format 0x%x\n", (int)pPict->format)); - if (!RADEONCheckTexturePOT(pPict, canTile)) + if (!RADEONCheckTextureRepeat(pPict, canTile)) return FALSE; if (pPict->filter != PictFilterNearest && @@ -1138,7 +1174,7 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture, if (((dst_pitch >> pixel_shift) & 0x7) != 0) RADEON_FALLBACK(("Bad destination pitch 0x%x\n", (int)dst_pitch)); - if (!RADEONSetupSourceTile(pSrcPicture, TRUE)) + if (!RADEONSetupSourceTile(pSrcPicture, pSrc, FALSE, FALSE)) return FALSE; if (!FUNC_NAME(R300TextureSetup)(pSrcPicture, pSrc, 0)) -- 1.5.4.5