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