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>
This commit is contained in:
Chris Wilson 2010-05-14 23:29:13 +01:00
parent 4be8d7eb89
commit f7bbcc492a
4 changed files with 106 additions and 52 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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, &region, dst_off_x, dst_off_y);
if (!uxa_pixmap_is_offscreen(pDstPix)) {
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return 0;
}
if (pSrcPix) {
if (! uxa_get_color_for_pixmap (pSrcPix, pSrc->format, pDst->format, &pixel)) {
REGION_UNINIT(pDst->pDrawable->pScreen, &region);

View File

@ -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.