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

Marek Olšák maraeo at gmail.com
Thu Mar 20 12:26:44 PDT 2014


On Mon, Mar 17, 2014 at 6:24 PM, Roland Scheidegger <sroland at vmware.com> wrote:
> 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.

It wouldn't be difficult, but updating all the classic drivers would
be annoying. I'm not interested in doing the rework at the moment.

Marek


More information about the mesa-dev mailing list