diff options
Diffstat (limited to 'src/gallium/drivers/nvc0/nvc0_surface.c')
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_surface.c | 84 |
1 files changed, 28 insertions, 56 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c index e1e4c303b12..4484a9f8b76 100644 --- a/src/gallium/drivers/nvc0/nvc0_surface.c +++ b/src/gallium/drivers/nvc0/nvc0_surface.c @@ -31,7 +31,6 @@ #include "nvc0_context.h" #include "nvc0_resource.h" -#include "nvc0_transfer.h" #include "nv50/nv50_defs.xml.h" @@ -91,8 +90,8 @@ nvc0_2d_texture_set(struct nouveau_channel *chan, int dst, return 1; } - width = u_minify(mt->base.base.width0, level); - height = u_minify(mt->base.base.height0, level); + width = u_minify(mt->base.base.width0, level) << mt->ms_x; + height = u_minify(mt->base.base.height0, level) << mt->ms_y; depth = u_minify(mt->base.base.depth0, level); /* layer has to be < depth, and depth > tile depth / 2 */ @@ -151,7 +150,13 @@ nvc0_2d_texture_do_copy(struct nouveau_channel *chan, unsigned sx, unsigned sy, unsigned sz, unsigned w, unsigned h) { + static const uint32_t duvdxy[5] = + { + 0x40000000, 0x80000000, 0x00000001, 0x00000002, 0x00000004 + }; + int ret; + uint32_t ctrl = 0x00; ret = MARK_RING(chan, 2 * 16 + 32, 4); if (ret) @@ -165,66 +170,33 @@ nvc0_2d_texture_do_copy(struct nouveau_channel *chan, if (ret) return ret; - /* 0/1 = CENTER/CORNER, 10/00 = POINT/BILINEAR */ + /* NOTE: 2D engine doesn't work for MS8 */ + if (src->ms_x) + ctrl = 0x11; + + /* 0/1 = CENTER/CORNER, 00/10 = POINT/BILINEAR */ BEGIN_RING(chan, RING_2D(BLIT_CONTROL), 1); - OUT_RING (chan, 0); + OUT_RING (chan, ctrl); BEGIN_RING(chan, RING_2D(BLIT_DST_X), 4); - OUT_RING (chan, dx); - OUT_RING (chan, dy); - OUT_RING (chan, w); - OUT_RING (chan, h); + OUT_RING (chan, dx << dst->ms_x); + OUT_RING (chan, dy << dst->ms_y); + OUT_RING (chan, w << dst->ms_x); + OUT_RING (chan, h << dst->ms_y); BEGIN_RING(chan, RING_2D(BLIT_DU_DX_FRACT), 4); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 1); + OUT_RING (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000); + OUT_RING (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f); + OUT_RING (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000); + OUT_RING (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f); BEGIN_RING(chan, RING_2D(BLIT_SRC_X_FRACT), 4); OUT_RING (chan, 0); - OUT_RING (chan, sx); + OUT_RING (chan, sx << src->ms_x); OUT_RING (chan, 0); - OUT_RING (chan, sy); + OUT_RING (chan, sy << src->ms_x); return 0; } 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 nv50_miptree *mt = nv50_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, @@ -244,14 +216,14 @@ nvc0_resource_copy_region(struct pipe_context *pipe, nv04_resource(dst)->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; - if (src->format == dst->format) { - struct nvc0_m2mf_rect drect, srect; + if (src->format == dst->format && src->nr_samples == dst->nr_samples) { + struct nv50_m2mf_rect drect, srect; unsigned i; unsigned nx = util_format_get_nblocksx(src->format, src_box->width); unsigned ny = util_format_get_nblocksy(src->format, src_box->height); - nvc0_setup_m2mf_rect(&drect, dst, dst_level, dstx, dsty, dstz); - nvc0_setup_m2mf_rect(&srect, src, src_level, + nv50_m2mf_rect_setup(&drect, dst, dst_level, dstx, dsty, dstz); + nv50_m2mf_rect_setup(&srect, src, src_level, src_box->x, src_box->y, src_box->z); for (i = 0; i < src_box->depth; ++i) { |