[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