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>
This commit is contained in:
Chris Wilson 2015-01-09 20:15:36 +00:00
parent e143ce600a
commit ebdc4d1eeb
1 changed files with 118 additions and 1 deletions

View File

@ -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;
}