summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-05-14 23:29:13 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-05-14 23:31:57 +0100
commitf7bbcc492a05f0801c64ee884798cf1a7ebb71c2 (patch)
tree9f3dd8208ff88f30be516242c7840721efda7f63
parent4be8d7eb89e61ffb2ceb19f1f84260e581187692 (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>
-rw-r--r--src/i830_uxa.c91
-rw-r--r--uxa/uxa-accel.c13
-rw-r--r--uxa/uxa-render.c15
-rw-r--r--uxa/uxa.h17
4 files changed, 95 insertions, 41 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,18 +195,11 @@ i830_uxa_pixmap_compute_size(PixmapPtr pixmap,
return size;
}
-/**
- * Sets up hardware state for a series of solid fills.
- */
static Bool
-i830_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg)
+i830_uxa_check_solid(DrawablePtr drawable, int alu, Pixel planemask)
{
- ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum];
+ ScrnInfoPtr scrn = xf86Screens[drawable->pScreen->myNum];
intel_screen_private *intel = intel_get_screen_private(scrn);
- drm_intel_bo *bo_table[] = {
- NULL, /* batch_bo */
- i830_get_pixmap_bo(pixmap),
- };
if (IS_GEN6(intel)) {
intel_debug_fallback(scrn,
@@ -214,20 +207,35 @@ i830_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg)
return FALSE;
}
- if (!UXA_PM_IS_SOLID(&pixmap->drawable, planemask)) {
+ if (!UXA_PM_IS_SOLID(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");
+ switch (drawable->bitsPerPixel) {
+ case 8:
+ case 16:
+ case 32:
+ break;
+ default:
return FALSE;
}
- if (pixmap->drawable.bitsPerPixel < 8) {
- intel_debug_fallback(scrn, "under 8bpp pixmaps unsupported\n");
- return FALSE;
- }
+ return TRUE;
+}
+
+/**
+ * Sets up hardware state for a series of solid fills.
+ */
+static Bool
+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);
+ drm_intel_bo *bo_table[] = {
+ NULL, /* batch_bo */
+ i830_get_pixmap_bo(pixmap),
+ };
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;
}
@@ -316,16 +323,11 @@ static void i830_uxa_done_solid(PixmapPtr pixmap)
* - support planemask using FULL_BLT_CMD?
*/
static Bool
-i830_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir,
- int ydir, int alu, Pixel planemask)
+i830_uxa_check_copy(DrawablePtr source, DrawablePtr dest,
+ int alu, Pixel planemask)
{
- ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
+ ScrnInfoPtr scrn = xf86Screens[dest->pScreen->myNum];
intel_screen_private *intel = intel_get_screen_private(scrn);
- drm_intel_bo *bo_table[] = {
- NULL, /* batch_bo */
- i830_get_pixmap_bo(source),
- i830_get_pixmap_bo(dest),
- };
if (IS_GEN6(intel)) {
intel_debug_fallback(scrn,
@@ -333,28 +335,50 @@ i830_uxa_prepare_copy(PixmapPtr source, PixmapPtr dest, int xdir,
return FALSE;
}
- if (!UXA_PM_IS_SOLID(&source->drawable, planemask)) {
+ if (!UXA_PM_IS_SOLID(source, 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");
+ if (source->bitsPerPixel != dest->bitsPerPixel) {
+ intel_debug_fallback(scrn, "mixed bpp copies unsupported\n");
return FALSE;
}
-
- if (!i830_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table)))
+ 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)
+{
+ ScrnInfoPtr scrn = xf86Screens[dest->drawable.pScreen->myNum];
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ drm_intel_bo *bo_table[] = {
+ NULL, /* batch_bo */
+ i830_get_pixmap_bo(source),
+ i830_get_pixmap_bo(dest),
+ };
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, &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);
diff --git a/uxa/uxa.h b/uxa/uxa.h
index 32a86a96..bf7ec0b5 100644
--- a/uxa/uxa.h
+++ b/uxa/uxa.h
@@ -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.
- *