From f7bbcc492a05f0801c64ee884798cf1a7ebb71c2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 14 May 2010 23:29:13 +0100 Subject: [PATCH] Split the prepare blitter functions into check + prepare. Allow us to check whether we can handle the operation using the blitter prior to doing any work. Signed-off-by: Chris Wilson --- src/i830_uxa.c | 113 +++++++++++++++++++++++++++++------------------ uxa/uxa-accel.c | 13 ++++++ uxa/uxa-render.c | 15 +++---- uxa/uxa.h | 17 +++++++ 4 files changed, 106 insertions(+), 52 deletions(-) diff --git a/src/i830_uxa.c b/src/i830_uxa.c index 6a454ac0..b2370fe7 100644 --- a/src/i830_uxa.c +++ b/src/i830_uxa.c @@ -195,6 +195,35 @@ i830_uxa_pixmap_compute_size(PixmapPtr pixmap, return size; } +static Bool +i830_uxa_check_solid(DrawablePtr drawable, int alu, Pixel planemask) +{ + ScrnInfoPtr scrn = xf86Screens[drawable->pScreen->myNum]; + intel_screen_private *intel = intel_get_screen_private(scrn); + + if (IS_GEN6(intel)) { + intel_debug_fallback(scrn, + "Sandybridge BLT engine not supported\n"); + return FALSE; + } + + if (!UXA_PM_IS_SOLID(drawable, planemask)) { + intel_debug_fallback(scrn, "planemask is not solid\n"); + return FALSE; + } + + switch (drawable->bitsPerPixel) { + case 8: + case 16: + case 32: + break; + default: + return FALSE; + } + + return TRUE; +} + /** * Sets up hardware state for a series of solid fills. */ @@ -208,27 +237,6 @@ i830_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg) i830_get_pixmap_bo(pixmap), }; - if (IS_GEN6(intel)) { - intel_debug_fallback(scrn, - "Sandybridge BLT engine not supported\n"); - return FALSE; - } - - if (!UXA_PM_IS_SOLID(&pixmap->drawable, planemask)) { - intel_debug_fallback(scrn, "planemask is not solid\n"); - return FALSE; - } - - if (pixmap->drawable.bitsPerPixel == 24) { - intel_debug_fallback(scrn, "solid 24bpp unsupported!\n"); - return FALSE; - } - - if (pixmap->drawable.bitsPerPixel < 8) { - intel_debug_fallback(scrn, "under 8bpp pixmaps unsupported\n"); - return FALSE; - } - if (!intel_check_pitch_2d(pixmap)) return FALSE; @@ -251,11 +259,10 @@ i830_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg) case 32: /* RGB8888 */ intel->BR[13] |= ((1 << 24) | (1 << 25)); - if (pixmap->drawable.depth == 24) - fg |= 0xff000000; break; } intel->BR[16] = fg; + return TRUE; } @@ -315,6 +322,40 @@ static void i830_uxa_done_solid(PixmapPtr pixmap) * TODO: * - support planemask using FULL_BLT_CMD? */ +static Bool +i830_uxa_check_copy(DrawablePtr source, DrawablePtr dest, + int alu, Pixel planemask) +{ + ScrnInfoPtr scrn = xf86Screens[dest->pScreen->myNum]; + intel_screen_private *intel = intel_get_screen_private(scrn); + + if (IS_GEN6(intel)) { + intel_debug_fallback(scrn, + "Sandybridge BLT engine not supported\n"); + return FALSE; + } + + if (!UXA_PM_IS_SOLID(source, planemask)) { + intel_debug_fallback(scrn, "planemask is not solid"); + return FALSE; + } + + if (source->bitsPerPixel != dest->bitsPerPixel) { + intel_debug_fallback(scrn, "mixed bpp copies unsupported\n"); + return FALSE; + } + switch (source->bitsPerPixel) { + case 8: + case 16: + case 32: + break; + default: + return FALSE; + } + + return TRUE; +} + static Bool i830_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir, int ydir, int alu, Pixel planemask) @@ -327,34 +368,17 @@ i830_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir, i830_get_pixmap_bo(dest), }; - if (IS_GEN6(intel)) { - intel_debug_fallback(scrn, - "Sandybridge BLT engine not supported\n"); - return FALSE; - } - - if (!UXA_PM_IS_SOLID(&source->drawable, planemask)) { - intel_debug_fallback(scrn, "planemask is not solid"); - return FALSE; - } - - if (dest->drawable.bitsPerPixel < 8) { - intel_debug_fallback(scrn, "under 8bpp pixmaps unsupported\n"); - return FALSE; - } - - if (!i830_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table))) - return FALSE; - if (!intel_check_pitch_2d(source)) return FALSE; if (!intel_check_pitch_2d(dest)) return FALSE; + if (!i830_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table))) + return FALSE; + intel->render_source = source; intel->BR[13] = I830CopyROP[alu] << 16; - switch (source->drawable.bitsPerPixel) { case 8: break; @@ -365,6 +389,7 @@ i830_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir, intel->BR[13] |= ((1 << 25) | (1 << 24)); break; } + return TRUE; } @@ -1056,11 +1081,13 @@ Bool i830_uxa_init(ScreenPtr screen) intel->uxa_driver->uxa_minor = 0; /* Solid fill */ + intel->uxa_driver->check_solid = i830_uxa_check_solid; intel->uxa_driver->prepare_solid = i830_uxa_prepare_solid; intel->uxa_driver->solid = i830_uxa_solid; intel->uxa_driver->done_solid = i830_uxa_done_solid; /* Copy */ + intel->uxa_driver->check_copy = i830_uxa_check_copy; intel->uxa_driver->prepare_copy = i830_uxa_prepare_copy; intel->uxa_driver->copy = i830_uxa_copy; intel->uxa_driver->done_copy = i830_uxa_done_copy; diff --git a/uxa/uxa-accel.c b/uxa/uxa-accel.c index 4f7fd41c..9f4a89a6 100644 --- a/uxa/uxa-accel.c +++ b/uxa/uxa-accel.c @@ -433,8 +433,16 @@ uxa_copy_n_to_n(DrawablePtr pSrcDrawable, int dst_off_x, dst_off_y; PixmapPtr pSrcPixmap, pDstPixmap; + if (uxa_screen->info->check_copy && + !uxa_screen->info->check_copy(pSrcDrawable, pDstDrawable, + pGC ? pGC->alu : GXcopy, + pGC ? pGC->planemask : FB_ALLONES)) + goto fallback; + pSrcPixmap = uxa_get_drawable_pixmap(pSrcDrawable); pDstPixmap = uxa_get_drawable_pixmap(pDstDrawable); + if (!pSrcPixmap || !pDstPixmap) + goto fallback; uxa_get_drawable_deltas(pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y); @@ -956,6 +964,11 @@ uxa_fill_region_tiled(DrawablePtr pDrawable, uxa_get_pixmap_first_pixel(pTile), planemask, alu); + if (uxa_screen->info->check_copy && + !uxa_screen->info->check_copy(&pTile->drawable, pDrawable, alu, planemask)) + return FALSE; + + pPixmap = uxa_get_drawable_pixmap(pDrawable); uxa_get_drawable_deltas(pDrawable, pPixmap, &xoff, &yoff); REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c index cf643e3b..883145f2 100644 --- a/uxa/uxa-render.c +++ b/uxa/uxa-render.c @@ -349,7 +349,12 @@ uxa_try_driver_solid_fill(PicturePtr pSrc, PixmapPtr pSrcPix = NULL, pDstPix; CARD32 pixel; - pDstPix = uxa_get_drawable_pixmap(pDst->pDrawable); + if (uxa_screen->info->check_solid && !uxa_screen->info->check_solid(pDst->pDrawable, GXcopy, 0xffffffff)) + return -1; + + pDstPix = uxa_get_offscreen_pixmap(pDst->pDrawable, &dst_off_x, &dst_off_y); + if (!pDstPix) + return -1; xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; @@ -365,16 +370,8 @@ uxa_try_driver_solid_fill(PicturePtr pSrc, width, height)) return 1; - uxa_get_drawable_deltas(pDst->pDrawable, pDstPix, &dst_off_x, - &dst_off_y); - REGION_TRANSLATE(pScreen, ®ion, dst_off_x, dst_off_y); - if (!uxa_pixmap_is_offscreen(pDstPix)) { - REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); - return 0; - } - if (pSrcPix) { if (! uxa_get_color_for_pixmap (pSrcPix, pSrc->format, pDst->format, &pixel)) { REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); diff --git a/uxa/uxa.h b/uxa/uxa.h index 32a86a96..bf7ec0b5 100644 --- a/uxa/uxa.h +++ b/uxa/uxa.h @@ -73,6 +73,17 @@ typedef struct _UxaDriver { /** @name solid * @{ */ + /** + * check_solid() checks whether the driver can do a solid fill to this drawable. + * @param pDrawable Destination drawable + * @param alu raster operation + * @param planemask write mask for the fill + * + * The check_solid() call is recommended if prepare_solid() is + * implemented, but is not required. + */ + Bool(*check_solid) (DrawablePtr pDrawable, int alu, Pixel planemask); + /** * prepare_solid() sets up the driver for doing a solid fill. * @param pPixmap Destination pixmap @@ -137,6 +148,12 @@ typedef struct _UxaDriver { /** @name copy * @{ */ + /** + * check_copy() checks whether the driver can blit between the two Pictures + */ + Bool(*check_copy) (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + int alu, Pixel planemask); /** * prepare_copy() sets up the driver for doing a copy within video * memory.