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

Chris Wilson ickle at kemper.freedesktop.org
Fri Jan 9 12:17:10 PST 2015


 src/sna/blt.c |  119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 118 insertions(+), 1 deletion(-)

New commits:
commit ebdc4d1eeb23604cf5c57c3d3a70629af041297d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jan 9 20:15:36 2015 +0000

    sna: Add basic unswizzled manual detilers for gen2
    
    gen2 uses a unique tile setup, and as far as we known, no swizzling.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/blt.c b/src/sna/blt.c
index 8cc97be..d45815f 100644
--- a/src/sna/blt.c
+++ b/src/sna/blt.c
@@ -745,10 +745,127 @@ memcpy_from_tiled_x__swizzle_9_11(const void *src, void *dst, int bpp,
 	}
 }
 
+static fast_memcpy void
+memcpy_to_tiled_x__gen2(const void *src, void *dst, int bpp,
+			int32_t src_stride, int32_t dst_stride,
+			int16_t src_x, int16_t src_y,
+			int16_t dst_x, int16_t dst_y,
+			uint16_t width, uint16_t height)
+{
+	const unsigned tile_width = 128;
+	const unsigned tile_height = 16;
+	const unsigned tile_size = 2048;
+
+	const unsigned cpp = bpp / 8;
+	const unsigned tile_pixels = tile_width / cpp;
+	const unsigned tile_shift = ffs(tile_pixels) - 1;
+	const unsigned tile_mask = tile_pixels - 1;
+
+	DBG(("%s(bpp=%d): src=(%d, %d), dst=(%d, %d), size=%dx%d, pitch=%d/%d\n",
+	     __FUNCTION__, bpp, src_x, src_y, dst_x, dst_y, width, height, src_stride, dst_stride));
+	assert(src != dst);
+
+	if (src_x | src_y)
+		src = (const uint8_t *)src + src_y * src_stride + src_x * cpp;
+	assert(src_stride >= width * cpp);
+	src_stride -= width * cpp;
+
+	while (height--) {
+		unsigned w = width * cpp;
+		uint8_t *tile_row = dst;
+
+		tile_row += dst_y / tile_height * dst_stride * tile_height;
+		tile_row += (dst_y & (tile_height-1)) * tile_width;
+		if (dst_x) {
+			tile_row += (dst_x >> tile_shift) * tile_size;
+			if (dst_x & tile_mask) {
+				const unsigned x = (dst_x & tile_mask) * cpp;
+				const unsigned len = min(tile_width - x, w);
+				memcpy(tile_row + x, src, len);
+
+				tile_row += tile_size;
+				src = (const uint8_t *)src + len;
+				w -= len;
+			}
+		}
+		while (w >= tile_width) {
+			memcpy(tile_row, src, tile_width);
+
+			tile_row += tile_size;
+			src = (const uint8_t *)src + tile_width;
+			w -= tile_width;
+		}
+		memcpy(tile_row, src, w);
+		src = (const uint8_t *)src + src_stride + w;
+		dst_y++;
+	}
+}
+
+static fast_memcpy void
+memcpy_from_tiled_x__gen2(const void *src, void *dst, int bpp,
+			  int32_t src_stride, int32_t dst_stride,
+			  int16_t src_x, int16_t src_y,
+			  int16_t dst_x, int16_t dst_y,
+			  uint16_t width, uint16_t height)
+{
+	const unsigned tile_width = 128;
+	const unsigned tile_height = 16;
+	const unsigned tile_size = 2048;
+
+	const unsigned cpp = bpp / 8;
+	const unsigned tile_pixels = tile_width / cpp;
+	const unsigned tile_shift = ffs(tile_pixels) - 1;
+	const unsigned tile_mask = tile_pixels - 1;
+
+	DBG(("%s(bpp=%d): src=(%d, %d), dst=(%d, %d), size=%dx%d, pitch=%d/%d\n",
+	     __FUNCTION__, bpp, src_x, src_y, dst_x, dst_y, width, height, src_stride, dst_stride));
+	assert(src != dst);
+
+	if (dst_x | dst_y)
+		dst = (uint8_t *)dst + dst_y * dst_stride + dst_x * cpp;
+	assert(dst_stride >= width * cpp);
+	dst_stride -= width * cpp;
+
+	while (height--) {
+		unsigned w = width * cpp;
+		const uint8_t *tile_row = src;
+
+		tile_row += src_y / tile_height * src_stride * tile_height;
+		tile_row += (src_y & (tile_height-1)) * tile_width;
+		if (src_x) {
+			tile_row += (src_x >> tile_shift) * tile_size;
+			if (src_x & tile_mask) {
+				const unsigned x = (src_x & tile_mask) * cpp;
+				const unsigned len = min(tile_width - x, w);
+				memcpy(dst, tile_row + x, len);
+
+				tile_row += tile_size;
+				dst = (uint8_t *)dst + len;
+				w -= len;
+			}
+		}
+		while (w >= tile_width) {
+			memcpy(dst, tile_row, tile_width);
+
+			tile_row += tile_size;
+			dst = (uint8_t *)dst + tile_width;
+			w -= tile_width;
+		}
+		memcpy(dst, tile_row, w);
+		dst = (uint8_t *)dst + dst_stride + w;
+		src_y++;
+	}
+}
+
 void choose_memcpy_tiled_x(struct kgem *kgem, int swizzling)
 {
 	if (kgem->gen < 30) {
-		DBG(("%s: no detiling functions for gen2\n", __FUNCTION__));
+		if (swizzling == I915_BIT_6_SWIZZLE_NONE) {
+			DBG(("%s: gen2, no swizzling\n", __FUNCTION__));
+			kgem->memcpy_to_tiled_x = memcpy_to_tiled_x__gen2;
+			kgem->memcpy_from_tiled_x = memcpy_from_tiled_x__gen2;
+		} else
+			DBG(("%s: no detiling with swizzle functions for gen2\n", __FUNCTION__));
 		return;
 	}
 


More information about the xorg-commit mailing list