diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2015-01-09 20:15:36 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2015-01-09 20:16:40 +0000 |
commit | ebdc4d1eeb23604cf5c57c3d3a70629af041297d (patch) | |
tree | 70d7830ea859df9239296edf241ce170990b8fab /src/sna | |
parent | e143ce600af286ed9ad9d47afc22dbfbb66628dc (diff) |
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@chris-wilson.co.uk>
Diffstat (limited to 'src/sna')
-rw-r--r-- | src/sna/blt.c | 119 |
1 files changed, 118 insertions, 1 deletions
diff --git a/src/sna/blt.c b/src/sna/blt.c index 8cc97bed..d45815f4 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; } |