mesa: Finally, convert RGBA glGetTexImage() to using MapTextureImage().
authorBrian Paul <brianp@vmware.com>
Mon, 1 Aug 2011 04:00:21 +0000 (21:00 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 27 Sep 2011 19:12:07 +0000 (12:12 -0700)
v2: Changes by Brian to MapTexImage in the decompression path.
v3: Changes by anholt to fix srcRowStride for decompression of NPOT.

Tested-by: Brian Paul <brianp@vmware.com> (v2)
src/mesa/main/texgetimage.c
src/mesa/state_tracker/st_cb_texture.c

index 11494e53ad59ab9d4a034b8d5ae65e0be9e8962a..d2f25b9f802300f3a993f3b096694c6008d8d504 100644 (file)
@@ -241,8 +241,32 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
          return;
       }
 
-      _mesa_decompress_image(texFormat, texImage->Width, texImage->Height,
-                             texImage->Data, texImage->RowStride, tempImage);
+      /* Decompress the texture image - results in 'tempImage' */
+      {
+         GLubyte *srcMap;
+         GLint srcRowStride;
+         GLuint bytes, bw, bh;
+
+         bytes = _mesa_get_format_bytes(texImage->TexFormat);
+         _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
+
+         ctx->Driver.MapTextureImage(ctx, texImage, 0,
+                                     0, 0, width, height,
+                                     GL_MAP_READ_BIT,
+                                     &srcMap, &srcRowStride);
+
+         /* XXX This line is a bit of a hack to work around the
+          * mismatch of compressed row strides as returned by
+          * MapTextureImage() vs. what the texture decompression code
+          * uses.  This will be fixed in the future.
+          */
+         srcRowStride = srcRowStride * bh / bytes;
+
+         _mesa_decompress_image(texFormat, width, height,
+                                srcMap, srcRowStride, tempImage);
+
+         ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
+      }
 
       if (baseFormat == GL_LUMINANCE ||
           baseFormat == GL_LUMINANCE_ALPHA) {
@@ -270,7 +294,6 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
    }
    else {
       /* No decompression needed */
-      const GLint texelSize = _mesa_get_format_bytes(texFormat);
       GLuint img, row;
       GLfloat (*rgba)[4];
 
@@ -281,13 +304,19 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
       }
 
       for (img = 0; img < depth; img++) {
+        GLubyte *srcMap;
+        GLint rowstride;
+
+         /* map src texture buffer */
+         ctx->Driver.MapTextureImage(ctx, texImage, img,
+                                     0, 0, width, height, GL_MAP_READ_BIT,
+                                     &srcMap, &rowstride);
+
          for (row = 0; row < height; row++) {
+           const GLubyte *src = srcMap + row * rowstride;
             void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
                                              width, height, format, type,
                                              img, row, 0);
-            const GLubyte *src = (const GLubyte *) texImage->Data +
-               (texImage->ImageOffsets[img] +
-                texImage->RowStride * row) * texelSize;
 
             _mesa_unpack_rgba_row(texFormat, width, src, rgba);
 
@@ -327,6 +356,9 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
                                        format, type, dest,
                                        &ctx->Pack, transferOps);
          }
+
+         /* Unmap the src texture buffer */
+         ctx->Driver.UnmapTextureImage(ctx, texImage, img);
       }
 
       free(rgba);
index 560b6b561725d9ecc0f34615037f0996a3be1b87..354e58de91dbf358fc8b4998e10ea7e77693e519 100644 (file)
@@ -938,7 +938,6 @@ st_GetTexImage(struct gl_context * ctx, GLenum target, GLint level,
                                format, type);
    GLuint depth, i;
    GLubyte *dest;
-   GLboolean do_map = GL_TRUE;
 
    if (stImage->pt && util_format_is_s3tc(stImage->pt->format)) {
       /* Need to decompress the texture.
@@ -950,37 +949,6 @@ st_GetTexImage(struct gl_context * ctx, GLenum target, GLint level,
       return;
    }
 
-   if (format == GL_DEPTH_STENCIL ||
-       format == GL_DEPTH_COMPONENT) {
-      do_map = GL_FALSE;
-   }
-
-   /* Map */
-   if (do_map && stImage->pt) {
-      /* Image is stored in hardware format in a buffer managed by the
-       * kernel.  Need to explicitly map and unmap it.
-       */
-      texImage->Data = st_texture_image_map(st, stImage, 0,
-                                            PIPE_TRANSFER_READ, 0, 0,
-                                            stImage->base.Width,
-                                            stImage->base.Height);
-      /* compute stride in texels from stride in bytes */
-      texImage->RowStride = stImage->transfer->stride
-         * util_format_get_blockwidth(stImage->pt->format)
-         / util_format_get_blocksize(stImage->pt->format);
-   }
-   else if (do_map) {
-      /* Otherwise, the image should actually be stored in
-       * texImage->Data.  This is pretty confusing for
-       * everybody, I'd much prefer to separate the two functions of
-       * texImage->Data - storage for texture images in main memory
-       * and access (ie mappings) of images.  In other words, we'd
-       * create a new texImage->Map field and leave Data simply for
-       * storage.
-       */
-      assert(texImage->Data);
-   }
-
    depth = texImage->Depth;
    texImage->Depth = 1;
 
@@ -1003,12 +971,6 @@ st_GetTexImage(struct gl_context * ctx, GLenum target, GLint level,
    }
 
    texImage->Depth = depth;
-
-   /* Unmap */
-   if (do_map && stImage->pt) {
-      st_texture_image_unmap(st, stImage);
-      texImage->Data = NULL;
-   }
 }