On 03/15/2014 11:17 AM, Marek Olšák wrote:
From: Marek Olšák <marek.ol...@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 <bri...@vmware.com>


_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to