diff options
Diffstat (limited to 'src/gallium/drivers/nv04')
-rw-r--r-- | src/gallium/drivers/nv04/nv04_surface_2d.c | 93 |
1 files changed, 43 insertions, 50 deletions
diff --git a/src/gallium/drivers/nv04/nv04_surface_2d.c b/src/gallium/drivers/nv04/nv04_surface_2d.c index ad11b2fd45a..538f8233197 100644 --- a/src/gallium/drivers/nv04/nv04_surface_2d.c +++ b/src/gallium/drivers/nv04/nv04_surface_2d.c @@ -104,7 +104,10 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx, struct nouveau_bo *dst_bo = ctx->nvws->get_bo(ctx->buf(dst)); const unsigned max_w = 1024; const unsigned max_h = 1024; - int i, src_offset = src->offset, dst_offset = dst->offset, src_stride = src->stride; + const unsigned sub_w = w > max_w ? max_w : w; + const unsigned sub_h = h > max_h ? max_h : h; + unsigned cx, cy; + int i, src_offset = src->offset, dst_offset = dst->offset; /* POT or GTFO */ assert(!(w & (w - 1)) && !(h & (h - 1))); @@ -113,62 +116,52 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx, OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_FORMAT, 1); + OUT_RING (chan, nv04_surface_format(dst->format) | + log2i(w) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT | + log2i(h) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT); + BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); OUT_RELOCo(chan, src_bo, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); OUT_RING (chan, swzsurf->handle); - /* Upload, then swizzle each mipmap level in turn */ - for (i=0; i<src->texture->last_level; i++) { - unsigned sub_w, sub_h; - unsigned cx, cy; - - BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_FORMAT, 1); - OUT_RING (chan, nv04_surface_format(dst->format) | - log2i(w) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT | - log2i(h) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT); - - sub_w = w > max_w ? max_w : w; - sub_h = h > max_h ? max_h : h; - - for (cy = 0; cy < h; cy += sub_h) { - for (cx = 0; cx < w; cx += sub_w) { - - BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET, 1); - OUT_RELOCl(chan, dst_bo, dst_offset + nv04_swizzle_bits(cx, cy) * - dst->block.size, NOUVEAU_BO_GART | - NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9); - OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); - OUT_RING (chan, nv04_scaled_image_format(src->format)); - OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); - OUT_RING (chan, 0); - OUT_RING (chan, sub_h << 16 | sub_w); - OUT_RING (chan, 0); - OUT_RING (chan, sub_h << 16 | sub_w); - OUT_RING (chan, 1 << 20); - OUT_RING (chan, 1 << 20); - - BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); - OUT_RING (chan, sub_h << 16 | sub_w); - OUT_RING (chan, src_stride | - NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | - NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); - OUT_RELOCl(chan, src_bo, src_offset + cy * src_stride + - cx * src->block.size, NOUVEAU_BO_GART | - NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (chan, 0); - } - } - - /* FIXME: need to find next offset for source */ - /*src_offset += w * h * src->block.size;*/ + /* FIXME: Find right src and dst offset, given mipmap level */ + for (i=0; i<src->level; i++) { + src_offset += w * h * src->block.size; dst_offset += w * h * dst->block.size; - src_stride >>= 1; - w >>= 1; - h >>= 1; + } + + for (cy = 0; cy < h; cy += sub_h) { + for (cx = 0; cx < w; cx += sub_w) { + + BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET, 1); + OUT_RELOCl(chan, dst_bo, dst_offset + nv04_swizzle_bits(cx, cy) * + dst->block.size, NOUVEAU_BO_GART | + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); + OUT_RING (chan, nv04_scaled_image_format(src->format)); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); + OUT_RING (chan, 0); + OUT_RING (chan, sub_h << 16 | sub_w); + OUT_RING (chan, 0); + OUT_RING (chan, sub_h << 16 | sub_w); + OUT_RING (chan, 1 << 20); + OUT_RING (chan, 1 << 20); + + BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); + OUT_RING (chan, sub_h << 16 | sub_w); + OUT_RING (chan, src->stride | + NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | + NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); + OUT_RELOCl(chan, src_bo, src_offset + cy * src->stride + + cx * src->block.size, NOUVEAU_BO_GART | + NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RING (chan, 0); + } } return 0; |