xf86-video-intel: src/sna/sna_io.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Jun 27 09:17:15 PDT 2013


 src/sna/sna_io.c |   69 +++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 60 insertions(+), 9 deletions(-)

New commits:
commit caf43fcadb0fcb3d342543f1e7dd78ee2314a627
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 27 16:52:21 2013 +0100

    sna: Enable memcpy_from_tiled for the IO paths
    
    Should you ever need to read back from a tiled surface and for whatever
    reason do not have a CPU bo to accelerate the operation, maybe we could
    use the manual tiling instead (as it is useful elsewhere).
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index e51c033..6ab907f 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -53,6 +53,55 @@ static inline bool must_tile(struct sna *sna, int width, int height)
 		upload_too_large(sna, width, height));
 }
 
+static bool bo_inplace_tiled(struct kgem *kgem, struct kgem_bo *bo)
+{
+	if (bo->tiling != I915_TILING_X)
+		return false;
+
+	if (bo->scanout)
+		return false;
+
+	return bo->domain == DOMAIN_CPU || kgem->has_llc;
+}
+
+static bool download_inplace__tiled(struct kgem *kgem, struct kgem_bo *bo)
+{
+	if (!kgem->memcpy_from_tiled_x)
+		return false;
+
+	return bo_inplace_tiled(kgem, bo);
+}
+
+static bool
+read_boxes_inplace__tiled(struct kgem *kgem,
+			  struct kgem_bo *bo, int16_t src_dx, int16_t src_dy,
+			  PixmapPtr pixmap, int16_t dst_dx, int16_t dst_dy,
+			  const BoxRec *box, int n)
+{
+	int bpp = pixmap->drawable.bitsPerPixel;
+	void *src, *dst = pixmap->devPrivate.ptr;
+	int src_pitch = bo->pitch;
+	int dst_pitch = pixmap->devKind;
+
+	assert(bo->tiling == I915_TILING_X);
+
+	src = __kgem_bo_map__cpu(kgem, bo);
+	if (src == NULL)
+		return false;
+
+	kgem_bo_sync__cpu_full(kgem, bo, 0);
+	do {
+		memcpy_from_tiled_x(kgem, src, dst, bpp, src_pitch, dst_pitch,
+				  box->x1 + src_dx, box->y1 + src_dy,
+				  box->x1 + dst_dx, box->y1 + dst_dy,
+				  box->x2 - box->x1, box->y2 - box->y1);
+		box++;
+	} while (--n);
+	__kgem_bo_unmap__cpu(kgem, bo, src);
+
+	return true;
+}
+
 static void read_boxes_inplace(struct kgem *kgem,
 			       struct kgem_bo *bo, int16_t src_dx, int16_t src_dy,
 			       PixmapPtr pixmap, int16_t dst_dx, int16_t dst_dy,
@@ -63,6 +112,12 @@ static void read_boxes_inplace(struct kgem *kgem,
 	int src_pitch = bo->pitch;
 	int dst_pitch = pixmap->devKind;
 
+	if (download_inplace__tiled(kgem, bo) &&
+	    read_boxes_inplace__tiled(kgem, bo, src_dx, src_dy,
+				      pixmap, dst_dx, dst_dy,
+				      box, n))
+		return;
+
 	DBG(("%s x %d, tiling=%d\n", __FUNCTION__, n, bo->tiling));
 
 	if (!kgem_bo_can_map(kgem, bo))
@@ -106,7 +161,7 @@ static bool download_inplace(struct kgem *kgem, struct kgem_bo *bo)
 	if (unlikely(kgem->wedged))
 		return true;
 
-	if (!kgem_bo_can_map(kgem, bo))
+	if (!kgem_bo_can_map(kgem, bo) && !download_inplace__tiled(kgem, bo))
 		return false;
 
 	if (FORCE_INPLACE)
@@ -115,7 +170,9 @@ static bool download_inplace(struct kgem *kgem, struct kgem_bo *bo)
 	if (kgem->can_blt_cpu && kgem->max_cpu_size)
 		return false;
 
-	return !__kgem_bo_is_busy(kgem, bo) || bo->tiling == I915_TILING_NONE;
+	return !__kgem_bo_is_busy(kgem, bo) ||
+		bo->tiling == I915_TILING_NONE ||
+		download_inplace__tiled(kgem, bo);
 }
 
 void sna_read_boxes(struct sna *sna,
@@ -480,13 +537,7 @@ static bool upload_inplace__tiled(struct kgem *kgem, struct kgem_bo *bo)
 	if (!kgem->memcpy_to_tiled_x)
 		return false;
 
-	if (bo->tiling != I915_TILING_X)
-		return false;
-
-	if (bo->scanout)
-		return false;
-
-	return bo->domain == DOMAIN_CPU || kgem->has_llc;
+	return bo_inplace_tiled(kgem, bo);
 }
 
 static bool


More information about the xorg-commit mailing list