diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-05-14 23:29:13 +0100 |
---|---|---|
committer | Owain G. Ainsworth <oga@openbsd.org> | 2010-05-17 20:33:21 +0100 |
commit | d9361a801789050b3f931b53362c8c35f4dc60a5 (patch) | |
tree | e70a15fb3401c50ddb34bbb6a3cff34e7dbf512d | |
parent | 9a6151abde1018bd4ddf9d346c9c94e16f92bf8e (diff) |
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 <chris@chris-wilson.co.uk>
Signed-off-by: Owain G. Ainsworth <oga@openbsd.org>
-rw-r--r-- | src/i830_uxa.c | 88 | ||||
-rw-r--r-- | uxa/uxa-accel.c | 13 | ||||
-rw-r--r-- | uxa/uxa-render.c | 15 | ||||
-rw-r--r-- | uxa/uxa.h | 17 |
4 files changed, 91 insertions, 42 deletions
diff --git a/src/i830_uxa.c b/src/i830_uxa.c index 0d673fd8..5e8cc116 100644 --- a/src/i830_uxa.c +++ b/src/i830_uxa.c @@ -195,6 +195,28 @@ 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]; + + 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. */ @@ -203,32 +225,14 @@ i830_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg) { ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum]; intel_screen_private *intel = intel_get_screen_private(scrn); - unsigned long pitch; drm_intel_bo *bo_table[] = { NULL, /* batch_bo */ i830_get_pixmap_bo(pixmap), }; - 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; - pitch = i830_pixmap_pitch(pixmap); - if (!i830_pixmap_pitch_is_aligned(pixmap)) { intel_debug_fallback(scrn, "pixmap pitch not aligned"); return FALSE; @@ -248,11 +252,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; } @@ -313,6 +316,33 @@ static void i830_uxa_done_solid(PixmapPtr pixmap) * - 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]; + + 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) { @@ -324,28 +354,17 @@ i830_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir, i830_get_pixmap_bo(dest), }; - if (!UXA_PM_IS_SOLID(&source->drawable, planemask)) { - intel_debug_fallback(scrn, "planemask is not solid"); + if (!intel_check_pitch_2d(source)) return FALSE; - } - - if (dest->drawable.bitsPerPixel < 8) { - intel_debug_fallback(scrn, "under 8bpp pixmaps unsupported\n"); + if (!intel_check_pitch_2d(dest)) 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; - intel->render_source = source; intel->BR[13] = I830CopyROP[alu] << 16; - switch (source->drawable.bitsPerPixel) { case 8: break; @@ -356,6 +375,7 @@ i830_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir, intel->BR[13] |= ((1 << 25) | (1 << 24)); break; } + return TRUE; } @@ -1060,11 +1080,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 bede1f41..bf81b482 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); @@ -74,6 +74,17 @@ typedef struct _UxaDriver { * @{ */ /** + * 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 * @param alu raster operation @@ -138,6 +149,12 @@ typedef struct _UxaDriver { * @{ */ /** + * 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. - * |