nv50: fix mipmap offsets and tiling

The hardware expects a texture's tile mode to change with
the mipmap level.
Also, only multiply by block size once to obtain size.
This commit is contained in:
Christoph Bumiller
2009-08-14 18:23:55 +02:00
parent 3506d7d3e2
commit 442a5e4343
3 changed files with 34 additions and 17 deletions
+1
View File
@@ -71,6 +71,7 @@ struct nv50_sampler_stateobj {
struct nv50_miptree_level {
int *image_offset;
unsigned pitch;
unsigned tile_mode;
};
struct nv50_miptree {
+9 -2
View File
@@ -87,20 +87,27 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
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;
@@ -109,7 +116,7 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
}
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;
+24 -15
View File
@@ -8,6 +8,7 @@ struct nv50_transfer {
struct pipe_transfer base;
struct nouveau_bo *bo;
unsigned level_offset;
unsigned level_tiling;
int level_pitch;
int level_width;
int level_height;
@@ -16,11 +17,14 @@ struct nv50_transfer {
};
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);
@@ -41,7 +45,7 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo,
} 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);
@@ -57,7 +61,7 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo,
} 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);
@@ -136,6 +140,7 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
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,
@@ -147,9 +152,11 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
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,
@@ -168,12 +175,14 @@ nv50_transfer_del(struct pipe_transfer *ptx)
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);
}