From 85cb4f299d8a0a0ebc8fe14d0ccd327375eda99e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Thu, 20 Dec 2012 03:54:33 +0100 Subject: [PATCH] st/mesa: fix GetTexImage for compressed 2D array textures This uses a 3D blit to decompress the texture and then a 3D transfer to read it. Reviewed-by: Brian Paul --- src/gallium/auxiliary/util/u_inlines.h | 18 +++++++++ src/mesa/state_tracker/st_cb_texture.c | 55 +++++++++++++++----------- 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index 582aacdca1e..2ff90c982d8 100644 --- a/src/gallium/auxiliary/util/u_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -421,6 +421,24 @@ pipe_transfer_map(struct pipe_context *context, &box, transfer); } +static INLINE void * +pipe_transfer_map_3d(struct pipe_context *context, + struct pipe_resource *resource, + unsigned level, + enum pipe_transfer_usage usage, + unsigned x, unsigned y, unsigned z, + unsigned w, unsigned h, unsigned d, + struct pipe_transfer **transfer) +{ + struct pipe_box box; + u_box_3d(x, y, z, w, h, d, &box); + return context->transfer_map(context, + resource, + level, + usage, + &box, transfer); +} + static INLINE void pipe_transfer_unmap( struct pipe_context *context, struct pipe_transfer *transfer ) diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 28fdaa573f9..c49ca493804 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -633,7 +633,7 @@ decompress_with_blit(struct gl_context * ctx, blit.dst.box.z = 0; blit.src.box.width = blit.dst.box.width = width; blit.src.box.height = blit.dst.box.height = height; - blit.src.box.depth = blit.dst.box.depth = 1; + blit.src.box.depth = blit.dst.box.depth = depth; blit.mask = PIPE_MASK_RGBA; blit.filter = PIPE_TEX_FILTER_NEAREST; blit.scissor_enable = FALSE; @@ -643,9 +643,8 @@ decompress_with_blit(struct gl_context * ctx, pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels); - map = pipe_transfer_map(pipe, dst, 0, 0, - PIPE_TRANSFER_READ, - 0, 0, width, height, &tex_xfer); + map = pipe_transfer_map_3d(pipe, dst, 0, PIPE_TRANSFER_READ, + 0, 0, 0, width, height, depth, &tex_xfer); if (!map) { goto end; } @@ -657,18 +656,24 @@ decompress_with_blit(struct gl_context * ctx, ctx->Pack.SwapBytes)) { /* memcpy */ const uint bytesPerRow = width * util_format_get_blocksize(pipe_format); - /* map the dst_surface so we can read from it */ - GLuint row; - for (row = 0; row < height; row++) { - GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, - height, format, type, row, 0); - memcpy(dest, map, bytesPerRow); - map += tex_xfer->stride; + GLuint row, slice; + + for (slice = 0; slice < depth; slice++) { + ubyte *slice_map = map; + + for (row = 0; row < height; row++) { + GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels, + width, height, format, + type, slice, row, 0); + memcpy(dest, slice_map, bytesPerRow); + slice_map += tex_xfer->stride; + } + map += tex_xfer->layer_stride; } } else { /* format translation via floats */ - GLuint row; + GLuint row, slice; enum pipe_format pformat = util_format_linear(dst->format); GLfloat *rgba; @@ -678,20 +683,24 @@ decompress_with_blit(struct gl_context * ctx, goto end; } - for (row = 0; row < height; row++) { - const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */ - GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, - height, format, type, row, 0); + for (slice = 0; slice < depth; slice++) { + for (row = 0; row < height; row++) { + const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */ + GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels, + width, height, format, + type, slice, row, 0); - if (ST_DEBUG & DEBUG_FALLBACK) - debug_printf("%s: fallback format translation\n", __FUNCTION__); + if (ST_DEBUG & DEBUG_FALLBACK) + debug_printf("%s: fallback format translation\n", __FUNCTION__); - /* get float[4] rgba row from surface */ - pipe_get_tile_rgba_format(tex_xfer, map, 0, row, width, 1, - pformat, rgba); + /* get float[4] rgba row from surface */ + pipe_get_tile_rgba_format(tex_xfer, map, 0, row, width, 1, + pformat, rgba); - _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, - type, dest, &ctx->Pack, transferOps); + _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, + type, dest, &ctx->Pack, transferOps); + } + map += tex_xfer->layer_stride; } free(rgba); -- 2.30.2