summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-06-16 13:16:28 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-06-17 14:08:11 +0100
commitc187da9a24e98cbdf86f0f0dfbdcd9025c8a4c76 (patch)
tree1d5f11c0fafdd8541e31ba1b0089fa540807545d
parent0e0101758438debf98f989d815989b45e78cf5f6 (diff)
i830: GetImage acceleration.
The presumption is that we wish to keep the target hot, so copy to a new bo and move that to the CPU in preference to causing ping-pong of the original. Also the gpu is much faster at detiling. Before (PineView): 400000 trep @ 0.1128 msec ( 8860.0/sec): GetImage 10x10 square 18000 trep @ 1.3839 msec ( 723.0/sec): GetImage 100x100 square 800 trep @ 30.0987 msec ( 33.2/sec): GetImage 500x500 square After: (PineView) 180000 trep @ 0.1478 msec ( 6770.0/sec): GetImage 10x10 square 60000 trep @ 0.4545 msec ( 2200.0/sec): GetImage 100x100 square 4000 trep @ 8.0739 msec ( 124.0/sec): GetImage 500x500 square Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/common.h1
-rw-r--r--src/i830_uxa.c91
2 files changed, 91 insertions, 1 deletions
diff --git a/src/common.h b/src/common.h
index 883aaa8f..30f1c781 100644
--- a/src/common.h
+++ b/src/common.h
@@ -421,6 +421,7 @@ intel_host_bridge (void);
enum {
INTEL_CREATE_PIXMAP_TILING_X = 0x10000000,
INTEL_CREATE_PIXMAP_TILING_Y,
+ INTEL_CREATE_PIXMAP_TILING_NONE,
};
#endif /* _INTEL_COMMON_H_ */
diff --git a/src/i830_uxa.c b/src/i830_uxa.c
index b69d45e3..8d676656 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -831,6 +831,94 @@ static Bool i830_uxa_put_image(PixmapPtr pixmap,
}
}
+static Bool i830_uxa_pixmap_get_image(PixmapPtr pixmap,
+ int x, int y, int w, int h,
+ char *dst, int dst_pitch)
+{
+ struct intel_pixmap *priv = i830_get_pixmap_intel(pixmap);
+ int stride = i830_pixmap_pitch(pixmap);
+
+ if (dst_pitch == stride && w == pixmap->drawable.width) {
+ return drm_intel_bo_get_subdata(priv->bo, y * stride, stride * h, dst) == 0;
+ } else {
+ char *src;
+ int cpp;
+
+ if (drm_intel_bo_map(priv->bo, FALSE))
+ return FALSE;
+
+ cpp = pixmap->drawable.bitsPerPixel/8;
+ src = (char *) priv->bo->virtual + y * stride + x * cpp;
+ w *= cpp;
+ do {
+ memcpy(dst, src, w);
+ src += stride;
+ dst += dst_pitch;
+ } while (--h);
+
+ drm_intel_bo_unmap(priv->bo);
+
+ return TRUE;
+ }
+}
+
+static Bool i830_uxa_get_image(PixmapPtr pixmap,
+ int x, int y,
+ int w, int h,
+ char *dst, int dst_pitch)
+{
+ struct intel_pixmap *priv;
+ PixmapPtr scratch = NULL;
+ Bool ret;
+
+ /* The presumption is that we wish to keep the target hot, so
+ * copy to a new bo and move that to the CPU in preference to
+ * causing ping-pong of the original.
+ *
+ * Also the gpu is much faster at detiling.
+ */
+
+ priv = i830_get_pixmap_intel(pixmap);
+ if (intel_pixmap_is_busy(priv) || priv->tiling != I915_TILING_NONE) {
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ GCPtr gc;
+
+ /* Copy to a linear buffer and pull. */
+ scratch = screen->CreatePixmap(screen, w, h,
+ pixmap->drawable.depth,
+ INTEL_CREATE_PIXMAP_TILING_NONE);
+ if (!scratch)
+ return FALSE;
+
+ gc = GetScratchGC(pixmap->drawable.depth, screen);
+ if (!gc) {
+ screen->DestroyPixmap(scratch);
+ return FALSE;
+ }
+
+ ValidateGC(&pixmap->drawable, gc);
+
+ gc->ops->CopyArea(&pixmap->drawable,
+ &scratch->drawable,
+ gc, x, y, w, h, 0, 0);
+
+ FreeScratchGC(gc);
+
+ intel_batch_submit(xf86Screens[screen->myNum]);
+
+ x = y = 0;
+ pixmap = scratch;
+ }
+
+ ret = i830_uxa_pixmap_get_image(pixmap, x, y, w, h, dst, dst_pitch);
+
+ if (scratch)
+ scratch->drawable.pScreen->DestroyPixmap(scratch);
+
+ return ret;
+
+}
+
void i830_uxa_block_handler(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86Screens[screen->myNum];
@@ -884,7 +972,7 @@ i830_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
tiling = I915_TILING_X;
if (usage == INTEL_CREATE_PIXMAP_TILING_Y)
tiling = I915_TILING_Y;
- if (usage == UXA_CREATE_PIXMAP_FOR_MAP)
+ if (usage == UXA_CREATE_PIXMAP_FOR_MAP || usage == INTEL_CREATE_PIXMAP_TILING_NONE)
tiling = I915_TILING_NONE;
if (tiling != I915_TILING_NONE) {
@@ -1069,6 +1157,7 @@ Bool i830_uxa_init(ScreenPtr screen)
/* PutImage */
intel->uxa_driver->put_image = i830_uxa_put_image;
+ intel->uxa_driver->get_image = i830_uxa_get_image;
intel->uxa_driver->prepare_access = i830_uxa_prepare_access;
intel->uxa_driver->finish_access = i830_uxa_finish_access;