lvl->image_offset = CALLOC(mt->image_nr, sizeof(int));
lvl->pitch = align(pt->width[l] * pt->block.size, 64);
+ lvl->tile_mode = tile_mode;
width = MAX2(1, width >> 1);
height = MAX2(1, height >> 1);
depth = MAX2(1, depth >> 1);
+
+ if (tile_mode && height <= (tile_h >> 1)) {
+ tile_mode--;
+ tile_h >>= 1;
+ }
}
for (i = 0; i < mt->image_nr; i++) {
for (l = 0; l <= pt->last_level; l++) {
struct nv50_miptree_level *lvl = &mt->level[l];
int size;
+ tile_h = 1 << (lvl->tile_mode + 2);
size = align(pt->width[l], 8) * pt->block.size;
size = align(size, 64);
- size *= align(pt->height[l], tile_h) * pt->block.size;
+ size *= align(pt->height[l], tile_h);
lvl->image_offset[i] = mt->total_size;
}
ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 256, mt->total_size,
- tile_mode, tile_flags, &mt->bo);
+ mt->level[0].tile_mode, tile_flags, &mt->bo);
if (ret) {
FREE(mt);
return NULL;
struct pipe_transfer base;
struct nouveau_bo *bo;
unsigned level_offset;
+ unsigned level_tiling;
int level_pitch;
int level_width;
int level_height;
};
static void
-nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo,
- unsigned src_offset, int src_pitch, int sx, int sy,
- int sw, int sh, struct nouveau_bo *dst_bo,
- unsigned dst_offset, int dst_pitch, int dx, int dy,
- int dw, int dh, int cpp, int width, int height,
+nv50_transfer_rect_m2mf(struct pipe_screen *pscreen,
+ struct nouveau_bo *src_bo, unsigned src_offset,
+ int src_pitch, unsigned src_tile_mode,
+ int sx, int sy, int sw, int sh,
+ struct nouveau_bo *dst_bo, unsigned dst_offset,
+ int dst_pitch, unsigned dst_tile_mode,
+ int dx, int dy, int dw, int dh,
+ int cpp, int width, int height,
unsigned src_reloc, unsigned dst_reloc)
{
struct nv50_screen *screen = nv50_screen(pscreen);
} else {
BEGIN_RING(chan, m2mf, 0x0200, 6);
OUT_RING (chan, 0);
- OUT_RING (chan, src_bo->tile_mode << 4);
+ OUT_RING (chan, src_tile_mode << 4);
OUT_RING (chan, sw * cpp);
OUT_RING (chan, sh);
OUT_RING (chan, 1);
} else {
BEGIN_RING(chan, m2mf, 0x021c, 6);
OUT_RING (chan, 0);
- OUT_RING (chan, dst_bo->tile_mode << 4);
+ OUT_RING (chan, dst_tile_mode << 4);
OUT_RING (chan, dw * cpp);
OUT_RING (chan, dh);
OUT_RING (chan, 1);
tx->level_width = mt->base.width[level];
tx->level_height = mt->base.height[level];
tx->level_offset = lvl->image_offset[image];
+ tx->level_tiling = lvl->tile_mode;
tx->level_x = x;
tx->level_y = y;
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
if (usage != PIPE_TRANSFER_WRITE) {
nv50_transfer_rect_m2mf(pscreen, mt->bo, tx->level_offset,
- tx->level_pitch, x, y, tx->level_width,
- tx->level_height, tx->bo, 0,
- tx->base.stride, 0, 0,
+ tx->level_pitch, tx->level_tiling,
+ x, y,
+ tx->level_width, tx->level_height,
+ tx->bo, 0, tx->base.stride,
+ tx->bo->tile_mode, 0, 0,
tx->base.width, tx->base.height,
tx->base.block.size, w, h,
NOUVEAU_BO_VRAM | NOUVEAU_BO_GART,
if (ptx->usage != PIPE_TRANSFER_READ) {
struct pipe_screen *pscreen = ptx->texture->screen;
nv50_transfer_rect_m2mf(pscreen, tx->bo, 0, tx->base.stride,
- 0, 0, tx->base.width, tx->base.height,
- mt->bo, tx->level_offset,
- tx->level_pitch, tx->level_x,
- tx->level_y, tx->level_width,
- tx->level_height, tx->base.block.size,
+ tx->bo->tile_mode, 0, 0,
tx->base.width, tx->base.height,
+ mt->bo, tx->level_offset,
+ tx->level_pitch, tx->level_tiling,
+ tx->level_x, tx->level_y,
+ tx->level_width, tx->level_height,
+ tx->base.block.size, tx->base.width,
+ tx->base.height,
NOUVEAU_BO_GART, NOUVEAU_BO_VRAM |
NOUVEAU_BO_GART);
}