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

Marek Olšák maraeo at gmail.com
Sat Mar 15 10:17:56 PDT 2014


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];
 };
 
 
@@ -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
-- 
1.8.3.2



More information about the mesa-dev mailing list