diff options
author | Christian König <[email protected]> | 2011-03-05 15:46:56 +0100 |
---|---|---|
committer | Christian König <[email protected]> | 2011-03-05 15:46:56 +0100 |
commit | 199034a3cc46e09e7a325690ac5b2b097e90249f (patch) | |
tree | 7977b528517d926d04d7fa990b27b09c653ba087 /src/gallium/drivers/nvc0/nvc0_surface.c | |
parent | 54f11a27a1ec28fcf9734f4454dee870bc0113f8 (diff) | |
parent | 533bf171d4c926e4ab6fcd0d51396b195b9e024f (diff) |
Merge remote branch 'origin/master' into pipe-video
Diffstat (limited to 'src/gallium/drivers/nvc0/nvc0_surface.c')
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_surface.c | 100 |
1 files changed, 87 insertions, 13 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c index a4b2b948123..17fc51b8aac 100644 --- a/src/gallium/drivers/nvc0/nvc0_surface.c +++ b/src/gallium/drivers/nvc0/nvc0_surface.c @@ -30,8 +30,9 @@ #include "nvc0_context.h" #include "nvc0_resource.h" +#include "nvc0_transfer.h" -#include "nv50_defs.xml.h" +#include "nv50/nv50_defs.xml.h" #define NVC0_ENG2D_SUPPORTED_FORMATS 0xff9ccfe1cce3ccc9ULL @@ -91,14 +92,18 @@ nvc0_2d_texture_set(struct nouveau_channel *chan, int dst, width = u_minify(mt->base.base.width0, level); height = u_minify(mt->base.base.height0, level); + depth = u_minify(mt->base.base.depth0, level); + + /* layer has to be < depth, and depth > tile depth / 2 */ - offset = mt->level[level].offset; if (!mt->layout_3d) { offset += mt->layer_stride * layer; + layer = 0; depth = 1; + } else + if (!dst) { + offset += nvc0_miptree_zslice_offset(mt, level, layer); layer = 0; - } else { - depth = u_minify(mt->base.base.depth0, level); } if (!(bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK)) { @@ -182,6 +187,43 @@ nvc0_2d_texture_do_copy(struct nouveau_channel *chan, } static void +nvc0_setup_m2mf_rect(struct nvc0_m2mf_rect *rect, + struct pipe_resource *restrict res, unsigned l, + unsigned x, unsigned y, unsigned z) +{ + struct nvc0_miptree *mt = nvc0_miptree(res); + const unsigned w = u_minify(res->width0, l); + const unsigned h = u_minify(res->height0, l); + + rect->bo = mt->base.bo; + rect->domain = mt->base.domain; + rect->base = mt->level[l].offset; + rect->pitch = mt->level[l].pitch; + if (util_format_is_plain(res->format)) { + rect->width = w; + rect->height = h; + rect->x = x; + rect->y = y; + } else { + rect->width = util_format_get_nblocksx(res->format, w); + rect->height = util_format_get_nblocksy(res->format, h); + rect->x = util_format_get_nblocksx(res->format, x); + rect->y = util_format_get_nblocksy(res->format, y); + } + rect->tile_mode = mt->level[l].tile_mode; + rect->cpp = util_format_get_blocksize(res->format); + + if (mt->layout_3d) { + rect->z = z; + rect->depth = u_minify(res->depth0, l); + } else { + rect->base += z * mt->layer_stride; + rect->z = 0; + rect->depth = 1; + } +} + +static void nvc0_resource_copy_region(struct pipe_context *pipe, struct pipe_resource *dst, unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz, @@ -192,9 +234,36 @@ nvc0_resource_copy_region(struct pipe_context *pipe, int ret; unsigned dst_layer = dstz, src_layer = src_box->z; - assert((src->format == dst->format) || - (nvc0_2d_format_faithful(src->format) && - nvc0_2d_format_faithful(dst->format))); + nv04_resource(dst)->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; + + if (src->format == dst->format) { + struct nvc0_m2mf_rect drect, srect; + unsigned i; + unsigned nx = util_format_get_nblocksx(src->format, src_box->width); + unsigned ny = util_format_get_nblocksx(src->format, src_box->height); + + nvc0_setup_m2mf_rect(&drect, dst, dst_level, dstx, dsty, dstz); + nvc0_setup_m2mf_rect(&srect, src, src_level, + src_box->x, src_box->y, src_box->z); + + for (i = 0; i < src_box->depth; ++i) { + nvc0_m2mf_transfer_rect(&screen->base.base, &drect, &srect, nx, ny); + + if (nvc0_miptree(dst)->layout_3d) + drect.z++; + else + drect.base += nvc0_miptree(dst)->layer_stride; + + if (nvc0_miptree(src)->layout_3d) + srect.z++; + else + srect.base += nvc0_miptree(src)->layer_stride; + } + return; + } + + assert(nvc0_2d_format_faithful(src->format)); + assert(nvc0_2d_format_faithful(dst->format)); for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) { ret = nvc0_2d_texture_do_copy(screen->base.channel, @@ -233,15 +302,17 @@ nvc0_clear_render_target(struct pipe_context *pipe, BEGIN_RING(chan, RING_3D(RT_CONTROL), 1); OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(0)), 8); + BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(0)), 9); OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); OUT_RING (chan, sf->width); OUT_RING (chan, sf->height); OUT_RING (chan, nvc0_format_table[dst->format].rt); - OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode); - OUT_RING (chan, 1); - OUT_RING (chan, 0); + OUT_RING (chan, (mt->layout_3d << 16) | + mt->level[sf->base.u.tex.level].tile_mode); + OUT_RING (chan, dst->u.tex.first_layer + sf->depth); + OUT_RING (chan, mt->layer_stride >> 2); + OUT_RING (chan, dst->u.tex.first_layer); BEGIN_RING(chan, RING_3D(CLIP_RECT_HORIZ(0)), 2); OUT_RING (chan, ((dstx + width) << 16) | dstx); @@ -272,6 +343,7 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe, struct nvc0_surface *sf = nvc0_surface(dst); struct nouveau_bo *bo = mt->base.bo; uint32_t mode = 0; + int unk = mt->base.base.target == PIPE_TEXTURE_2D; if (clear_flags & PIPE_CLEAR_DEPTH) { BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1); @@ -293,13 +365,15 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe, OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); OUT_RING (chan, nvc0_format_table[dst->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); OUT_RING (chan, sf->width); OUT_RING (chan, sf->height); - OUT_RING (chan, (1 << 16) | 1); + OUT_RING (chan, (unk << 16) | (dst->u.tex.first_layer + sf->depth)); + BEGIN_RING(chan, RING_3D(ZETA_BASE_LAYER), 1); + OUT_RING (chan, dst->u.tex.first_layer); BEGIN_RING(chan, RING_3D(CLIP_RECT_HORIZ(0)), 2); OUT_RING (chan, ((dstx + width) << 16) | dstx); |