[Mesa-dev] [PATCH 6/9] st/mesa: properly implement MapTextureImage with multiple mapped slices

Roland Scheidegger sroland at vmware.com
Mon Mar 17 10:24:30 PDT 2014


Am 15.03.2014 18:17, schrieb Marek Olšák:
> 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];
>
That indeed looks silly. Would it be difficult (and maybe even useful
for other places) to extend MapTextureImage() to deal with 3d mappings?
1-5 looks good to me.

Roland


>  
>  
> @@ -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
> 


More information about the mesa-dev mailing list