diff options
author | Christoph Bumiller <[email protected]> | 2010-12-23 15:21:36 +0100 |
---|---|---|
committer | Christoph Bumiller <[email protected]> | 2010-12-23 15:21:36 +0100 |
commit | 96def0c3147ac7b9449de00bf1306dfd1ca436fb (patch) | |
tree | 3121d715d5b5e7c9f42d4ae851151737ccbd8b77 /src/gallium/drivers/nvc0/nvc0_miptree.c | |
parent | 2c20aae23393a3f6899f1775df47697ce65fc6ca (diff) |
nvc0: fix layer stride state
Diffstat (limited to 'src/gallium/drivers/nvc0/nvc0_miptree.c')
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_miptree.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_miptree.c b/src/gallium/drivers/nvc0/nvc0_miptree.c index 70b10a0fc39..7c7e134146e 100644 --- a/src/gallium/drivers/nvc0/nvc0_miptree.c +++ b/src/gallium/drivers/nvc0/nvc0_miptree.c @@ -58,17 +58,18 @@ get_tile_dims(unsigned nx, unsigned ny, unsigned nz) } static INLINE unsigned -get_zslice_offset(uint32_t tile_mode, unsigned z, unsigned pitch, unsigned nbh) +calc_zslice_offset(uint32_t tile_mode, unsigned z, unsigned pitch, unsigned nbh) { unsigned tile_h = NVC0_TILE_HEIGHT(tile_mode); - unsigned tile_d = NVC0_TILE_DEPTH(tile_mode); + unsigned tile_d_shift = NVC0_TILE_DIM_SHIFT(tile_mode, 2); + unsigned tile_d = 1 << tile_d_shift; - /* pitch_2d == to next slice within this volume tile */ - /* pitch_3d == size (in bytes) of a volume tile */ - unsigned pitch_2d = tile_h * NVC0_TILE_PITCH(tile_mode); - unsigned pitch_3d = tile_d * align(nbh, tile_h) * pitch; + /* stride_2d == to next slice within this volume tile */ + /* stride_3d == size (in bytes) of a volume tile */ + unsigned stride_2d = tile_h * NVC0_TILE_PITCH(tile_mode); + unsigned stride_3d = tile_d * align(nbh, tile_h) * pitch; - return (z % tile_d) * pitch_2d + (z / tile_d) * pitch_3d; + return (z & (tile_d - 1)) * stride_2d + (z >> tile_d_shift) * stride_3d; } static void @@ -298,10 +299,16 @@ nvc0_miptree_surface_new(struct pipe_context *pipe, ps->height = ns->height; if (mt->layout_3d) { - ns->offset += get_zslice_offset(lvl->tile_mode, ps->u.tex.first_layer, - lvl->pitch, - util_format_get_nblocksy(pt->format, - ns->height)); + unsigned zslice = ps->u.tex.first_layer; + + /* TODO: re-layout the texture to use only depth 1 tiles in this case: */ + if (ns->depth > 1 && (zslice & (NVC0_TILE_DEPTH(lvl->tile_mode) - 1))) + NOUVEAU_ERR("Creating unsupported 3D surface of slices [%u:%u].\n", + zslice, ps->u.tex.last_layer); + + ns->offset += calc_zslice_offset(lvl->tile_mode, zslice, lvl->pitch, + util_format_get_nblocksy(pt->format, + ns->height)); } else { ns->offset += mt->layer_stride * ps->u.tex.first_layer; } |