diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_miptree.c | 29 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_resource.h | 15 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_state_validate.c | 4 |
3 files changed, 30 insertions, 18 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_miptree.c b/src/gallium/drivers/nvc0/nvc0_miptree.c index 70b10a0fc3..7c7e134146 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; } diff --git a/src/gallium/drivers/nvc0/nvc0_resource.h b/src/gallium/drivers/nvc0/nvc0_resource.h index 0ff7a03198..9384f1905d 100644 --- a/src/gallium/drivers/nvc0/nvc0_resource.h +++ b/src/gallium/drivers/nvc0/nvc0_resource.h @@ -66,12 +66,17 @@ nvc0_resource_unmap(struct nvc0_resource *res) nouveau_bo_unmap(res->bo); } -#define NVC0_TILE_PITCH(m) (64 << ((m) & 0xf)) -#define NVC0_TILE_HEIGHT(m) (8 << (((m) >> 4) & 0xf)) -#define NVC0_TILE_DEPTH(m) (1 << ((m) >> 8)) +#define NVC0_TILE_DIM_SHIFT(m, d) (((m) >> (d * 4)) & 0xf) -#define NVC0_TILE_SIZE(m) \ - (NVC0_TILE_PITCH(m) * NVC0_TILE_HEIGHT(m) * NVC0_TILE_DEPTH(m)) +#define NVC0_TILE_PITCH(m) (64 << NVC0_TILE_DIM_SHIFT(m, 0)) +#define NVC0_TILE_HEIGHT(m) ( 8 << NVC0_TILE_DIM_SHIFT(m, 1)) +#define NVC0_TILE_DEPTH(m) ( 1 << NVC0_TILE_DIM_SHIFT(m, 2)) + +#define NVC0_TILE_SIZE_2D(m) (((64 * 8) << \ + NVC0_TILE_DIM_SHIFT(m, 0)) << \ + NVC0_TILE_DIM_SHIFT(m, 1)) + +#define NVC0_TILE_SIZE(m) (NVC0_TILE_SIZE_2D(m) << NVC0_TILE_DIM_SHIFT(m, 2)) struct nvc0_miptree_level { uint32_t offset; diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c index f20e7e962c..25aec0244d 100644 --- a/src/gallium/drivers/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c @@ -81,7 +81,7 @@ nvc0_validate_fb(struct nvc0_context *nvc0) OUT_RING (chan, (mt->layout_3d << 16) | mt->level[sf->base.u.tex.level].tile_mode); OUT_RING (chan, sf->depth); - OUT_RING (chan, mt->layer_stride); + OUT_RING (chan, mt->layer_stride >> 2); nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); @@ -99,7 +99,7 @@ nvc0_validate_fb(struct nvc0_context *nvc0) OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); OUT_RING (chan, nvc0_format_table[fb->zsbuf->format].rt); OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode); - OUT_RING (chan, 0); + OUT_RING (chan, mt->layer_stride >> 2); BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1); OUT_RING (chan, 1); BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3); |