[Mesa-dev] [PATCH 6/9] st/mesa: properly implement MapTextureImage with multiple mapped slices
Brian Paul
brianp at vmware.com
Mon Mar 17 08:42:32 PDT 2014
On 03/15/2014 11:17 AM, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> This is needed by _mesa_generate_mipmap.
>
> This adds an array of pipe_transfers to st_texture_image. Each transfer is
> for mapping a single layer. It's ugly, but at least _mesa_generate_mipmap
> works for array textures.
> ---
> src/mesa/state_tracker/st_cb_texture.c | 24 +++++++++++++-----------
> src/mesa/state_tracker/st_texture.c | 24 +++++++++++++++++-------
> src/mesa/state_tracker/st_texture.h | 11 ++++++++---
> 3 files changed, 38 insertions(+), 21 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
> index f0bf374..e783973 100644
> --- a/src/mesa/state_tracker/st_cb_texture.c
> +++ b/src/mesa/state_tracker/st_cb_texture.c
> @@ -192,6 +192,7 @@ st_MapTextureImage(struct gl_context *ctx,
> struct st_texture_image *stImage = st_texture_image(texImage);
> unsigned pipeMode;
> GLubyte *map;
> + struct pipe_transfer *transfer;
>
> pipeMode = 0x0;
> if (mode & GL_MAP_READ_BIT)
> @@ -201,10 +202,11 @@ st_MapTextureImage(struct gl_context *ctx,
> if (mode & GL_MAP_INVALIDATE_RANGE_BIT)
> pipeMode |= PIPE_TRANSFER_DISCARD_RANGE;
>
> - map = st_texture_image_map(st, stImage, pipeMode, x, y, slice, w, h, 1);
> + map = st_texture_image_map(st, stImage, pipeMode, x, y, slice, w, h, 1,
> + &transfer);
> if (map) {
> *mapOut = map;
> - *rowStrideOut = stImage->transfer->stride;
> + *rowStrideOut = transfer->stride;
> }
> else {
> *mapOut = NULL;
> @@ -221,7 +223,7 @@ st_UnmapTextureImage(struct gl_context *ctx,
> {
> struct st_context *st = st_context(ctx);
> struct st_texture_image *stImage = st_texture_image(texImage);
> - st_texture_image_unmap(st, stImage);
> + st_texture_image_unmap(st, stImage, slice);
> }
>
>
> @@ -1146,6 +1148,7 @@ fallback_copy_texsubimage(struct gl_context *ctx,
> unsigned dst_width = width;
> unsigned dst_height = height;
> unsigned dst_depth = 1;
> + struct pipe_transfer *transfer;
>
> if (ST_DEBUG & DEBUG_FALLBACK)
> debug_printf("%s: fallback processing\n", __FUNCTION__);
> @@ -1171,7 +1174,8 @@ fallback_copy_texsubimage(struct gl_context *ctx,
>
> texDest = st_texture_image_map(st, stImage, transfer_usage,
> destX, destY, slice,
> - dst_width, dst_height, dst_depth);
> + dst_width, dst_height, dst_depth,
> + &transfer);
>
> if (baseFormat == GL_DEPTH_COMPONENT ||
> baseFormat == GL_DEPTH_STENCIL) {
> @@ -1201,13 +1205,11 @@ fallback_copy_texsubimage(struct gl_context *ctx,
> }
>
> if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
> - pipe_put_tile_z(stImage->transfer,
> - texDest + row*stImage->transfer->layer_stride,
> + pipe_put_tile_z(transfer, texDest + row*transfer->layer_stride,
> 0, 0, width, 1, data);
> }
> else {
> - pipe_put_tile_z(stImage->transfer, texDest, 0, row, width, 1,
> - data);
> + pipe_put_tile_z(transfer, texDest, 0, row, width, 1, data);
> }
> }
> }
> @@ -1233,10 +1235,10 @@ fallback_copy_texsubimage(struct gl_context *ctx,
> }
>
> if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
> - dstRowStride = stImage->transfer->layer_stride;
> + dstRowStride = transfer->layer_stride;
> }
> else {
> - dstRowStride = stImage->transfer->stride;
> + dstRowStride = transfer->stride;
> }
>
> /* get float/RGBA image from framebuffer */
> @@ -1269,7 +1271,7 @@ fallback_copy_texsubimage(struct gl_context *ctx,
> free(tempSrc);
> }
>
> - st_texture_image_unmap(st, stImage);
> + st_texture_image_unmap(st, stImage, slice);
> pipe->transfer_unmap(pipe, src_trans);
> }
>
> diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
> index b5ccc76..e867b80 100644
> --- a/src/mesa/state_tracker/st_texture.c
> +++ b/src/mesa/state_tracker/st_texture.c
> @@ -240,11 +240,13 @@ GLubyte *
> st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
> enum pipe_transfer_usage usage,
> GLuint x, GLuint y, GLuint z,
> - GLuint w, GLuint h, GLuint d)
> + GLuint w, GLuint h, GLuint d,
> + struct pipe_transfer **transfer)
> {
> struct st_texture_object *stObj =
> st_texture_object(stImage->base.TexObject);
> GLuint level;
> + void *map;
>
> DBG("%s \n", __FUNCTION__);
>
> @@ -256,22 +258,30 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
> else
> level = stImage->base.Level;
>
> - return pipe_transfer_map_3d(st->pipe, stImage->pt, level, usage,
> - x, y, z + stImage->base.Face,
> - w, h, d, &stImage->transfer);
> + z += stImage->base.Face;
> +
> + map = pipe_transfer_map_3d(st->pipe, stImage->pt, level, usage,
> + x, y, z, w, h, d, transfer);
> + if (map) {
> + assert(!stImage->transfer[z]);
> + stImage->transfer[z] = *transfer;
> + }
> + return map;
> }
>
>
> void
> st_texture_image_unmap(struct st_context *st,
> - struct st_texture_image *stImage)
> + struct st_texture_image *stImage, unsigned slice)
> {
> struct pipe_context *pipe = st->pipe;
> + struct pipe_transfer **transfer =
> + &stImage->transfer[slice + stImage->base.Face];
>
> DBG("%s\n", __FUNCTION__);
>
> - pipe_transfer_unmap(pipe, stImage->transfer);
> - stImage->transfer = NULL;
> + pipe_transfer_unmap(pipe, *transfer);
> + *transfer = NULL;
> }
>
>
> diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
> index bce2a09..7356dbf 100644
> --- a/src/mesa/state_tracker/st_texture.h
> +++ b/src/mesa/state_tracker/st_texture.h
> @@ -56,7 +56,11 @@ struct st_texture_image
> */
> struct pipe_resource *pt;
>
> - struct pipe_transfer *transfer;
> + /* XXX It's silly to have 16384 transfers here. It would be better
> + * XXX if MapTextureImage supported 3D mappings, so that we don't
> + * XXX have to map each slice separately.
> + * XXX _mesa_generate_mipmap would benefit from that. */
> + struct pipe_transfer *transfer[MAX_ARRAY_TEXTURE_LAYERS];
Hmm, this is going to waste a lot of memory. On a 64-bit system this
array will be 128KB. That could quickly add up if you consider a large
number of mipmapped/cube textures.
Can't the transfer array be allocated on demand and only as large as needed?
> };
>
>
> @@ -192,11 +196,12 @@ extern GLubyte *
> st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
> enum pipe_transfer_usage usage,
> GLuint x, GLuint y, GLuint z,
> - GLuint w, GLuint h, GLuint d);
> + GLuint w, GLuint h, GLuint d,
> + struct pipe_transfer **transfer);
>
> extern void
> st_texture_image_unmap(struct st_context *st,
> - struct st_texture_image *stImage);
> + struct st_texture_image *stImage, unsigned slice);
>
>
> /* Return pointers to each 2d slice within an image. Indexed by depth
>
Patches 1-5, 7, 9: Reviewed-by: Brian Paul <brianp at vmware.com>
More information about the mesa-dev
mailing list