summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/i830_uxa.c88
-rw-r--r--uxa/uxa-accel.c13
-rw-r--r--uxa/uxa-render.c15
-rw-r--r--uxa/uxa.h17
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, &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.
- *