mesa: Convert texstore.c to accessing textures using MapTextureImage.
authorBrian Paul <brianp@vmware.com>
Fri, 29 Jul 2011 23:25:23 +0000 (16:25 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 29 Aug 2011 17:14:19 +0000 (10:14 -0700)
This continues to allocate texImage->Data as before, so
drivers calling these functions need to use that when present.

Reviewed-by: Brian Paul <brianp@vmware.com>
src/mesa/main/texstore.c

index c4aeaa8f16d3a2f1e54c877e9fd450b37b966813..aac600e40dee5f206ff562032fdfad1efa8ac365 100644 (file)
@@ -4565,17 +4565,24 @@ texture_size(const struct gl_texture_image *texImage)
 }
 
 
-/** Return row stride in bytes */
-static GLuint
-texture_row_stride(const struct gl_texture_image *texImage)
+/**
+ * Normally, we'll only _write_ texel data to a texture when we map it.
+ * But if the user is providing depth or stencil values and the texture
+ * image is a combined depth/stencil format, we'll actually read from
+ * the texture buffer too (in order to insert the depth or stencil values.
+ * \param userFormat  the user-provided image format
+ * \param texFormat  the destination texture format
+ */
+static GLbitfield
+get_read_write_mode(GLenum userFormat, gl_format texFormat)
 {
-   GLuint stride = _mesa_format_row_stride(texImage->TexFormat,
-                                           texImage->Width);
-   return stride;
+   if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT)
+       && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL)
+      return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
+   else
+      return GL_MAP_WRITE_BIT;
 }
 
-
-
 /**
  * This is the software fallback for Driver.TexImage1D().
  * \sa _mesa_store_teximage2d()
@@ -4590,6 +4597,12 @@ _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
                        struct gl_texture_image *texImage)
 {
    GLuint sizeInBytes;
+   const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
+   const GLuint zeroImageOffset = 0;
+   GLubyte *dstMap;
+   GLint dstRowStride;
+   GLboolean success;
+
    (void) border;
 
    /* allocate memory */
@@ -4608,20 +4621,26 @@ _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
        */
       return;
    }
-   else {
-      const GLint dstRowStride = 0;
-      GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
-                                         texImage->TexFormat,
-                                         texImage->Data,
-                                         0, 0, 0,  /* dstX/Y/Zoffset */
-                                         dstRowStride,
-                                         texImage->ImageOffsets,
-                                         width, 1, 1,
-                                         format, type, pixels, packing);
-      if (!success) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
-      }
-   }
+
+   /* Map dest texture buffer (write to whole region) */
+   ctx->Driver.MapTextureImage(ctx, texImage, 0,
+                               0, 0, width, 1,
+                               rwMode,
+                               &dstMap, &dstRowStride);
+
+   success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
+                            texImage->TexFormat,
+                            dstMap,
+                            0, 0, 0,  /* dstX/Y/Zoffset */
+                            0, /* dstRowStride */
+                            &zeroImageOffset,
+                            width, 1, 1,
+                            format, type, pixels, packing);
+
+   ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
+
+   if (!success)
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
 
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
@@ -4643,6 +4662,12 @@ _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
                        struct gl_texture_image *texImage)
 {
    GLuint sizeInBytes;
+   const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
+   const GLuint zeroImageOffset = 0;
+   GLubyte *dstMap;
+   GLint dstRowStride;
+   GLboolean success;
+
    (void) border;
 
    /* allocate memory */
@@ -4661,20 +4686,26 @@ _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
        */
       return;
    }
-   else {
-      GLint dstRowStride = texture_row_stride(texImage);
-      GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
-                                         texImage->TexFormat,
-                                         texImage->Data,
-                                         0, 0, 0,  /* dstX/Y/Zoffset */
-                                         dstRowStride,
-                                         texImage->ImageOffsets,
-                                         width, height, 1,
-                                         format, type, pixels, packing);
-      if (!success) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
-      }
-   }
+
+   /* Map dest texture buffer (write to whole region) */
+   ctx->Driver.MapTextureImage(ctx, texImage, 0,
+                               0, 0, width, height,
+                               rwMode,
+                               &dstMap, &dstRowStride);
+   assert(dstMap);
+   success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
+                            texImage->TexFormat,
+                            dstMap,
+                            0, 0, 0,  /* dstX/Y/Zoffset */
+                            dstRowStride,
+                            &zeroImageOffset,
+                            width, height, 1,
+                            format, type, pixels, packing);
+
+   ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
+
+   if (!success)
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
 
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
@@ -4695,40 +4726,72 @@ _mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level,
                        struct gl_texture_image *texImage)
 {
    GLuint sizeInBytes;
+   const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
+   GLboolean success;
+   GLint slice;
+   GLubyte **sliceMaps;
+   GLuint *dstImageOffsets;
+   GLint dstRowStride;
+   GLuint texelSize = _mesa_get_format_bytes(texImage->TexFormat);
+
    (void) border;
 
    /* allocate memory */
    sizeInBytes = texture_size(texImage);
    texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
    if (!texImage->Data) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
+      /* Note: we check for a NULL image pointer here, _after_ we allocated
+       * memory for the texture.  That's what the GL spec calls for.
+       */
       return;
    }
 
-   pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
-                                        type, pixels, packing, "glTexImage3D");
+   pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth,
+                                        format, type,
+                                        pixels, packing, "glTexImage3D");
    if (!pixels) {
       /* Note: we check for a NULL image pointer here, _after_ we allocated
        * memory for the texture.  That's what the GL spec calls for.
        */
       return;
    }
-   else {
-      GLint dstRowStride = texture_row_stride(texImage);
-      GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
-                                         texImage->TexFormat,
-                                         texImage->Data,
-                                         0, 0, 0,  /* dstX/Y/Zoffset */
-                                         dstRowStride,
-                                         texImage->ImageOffsets,
-                                         width, height, depth,
-                                         format, type, pixels, packing);
-      if (!success) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
-      }
+
+   sliceMaps = (GLubyte **) malloc(depth * sizeof(GLubyte *));
+   dstImageOffsets = (GLuint *) malloc(depth * sizeof(GLuint));
+
+   /* Map dest texture buffer slices */
+   for (slice = 0; slice < depth; slice++) {
+      ctx->Driver.MapTextureImage(ctx, texImage, slice,
+                                  0, 0, width, height,
+                                  rwMode,
+                                  &sliceMaps[slice], &dstRowStride);
+   }
+   /* Compute image slice offsets */
+   for (slice = 0; slice < depth; slice++) {
+      dstImageOffsets[slice] = (sliceMaps[slice] - sliceMaps[0]) / texelSize;
+   }
+
+   success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
+                            texImage->TexFormat,
+                            sliceMaps[0],
+                            0, 0, 0,  /* dstX/Y/Zoffset */
+                            dstRowStride,
+                            dstImageOffsets,
+                            width, height, depth,
+                            format, type, pixels, packing);
+
+   /* Unmap dest texture buffer slices */
+   for (slice = 0; slice < depth; slice++) {
+      ctx->Driver.UnmapTextureImage(ctx, texImage, slice);
    }
 
+   if (!success)
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
+
    _mesa_unmap_teximage_pbo(ctx, packing);
+
+   free(sliceMaps);
+   free(dstImageOffsets);
 }
 
 
@@ -4746,26 +4809,37 @@ _mesa_store_texsubimage1d(struct gl_context *ctx, GLenum target, GLint level,
                           struct gl_texture_object *texObj,
                           struct gl_texture_image *texImage)
 {
+   const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
+   const GLuint zeroImageOffset = 0;
+   GLubyte *dstMap;
+   GLint dstRowStride;
+   GLboolean success;
+
    /* get pointer to src pixels (may be in a pbo which we'll map here) */
    pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
                                         pixels, packing, "glTexSubImage1D");
    if (!pixels)
       return;
 
-   {
-      const GLint dstRowStride = 0;
-      GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
-                                         texImage->TexFormat,
-                                         texImage->Data,
-                                         xoffset, 0, 0,  /* offsets */
-                                         dstRowStride,
-                                         texImage->ImageOffsets,
-                                         width, 1, 1,
-                                         format, type, pixels, packing);
-      if (!success) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
-      }
-   }
+   /* Map dest texture buffer (write to whole region) */
+   ctx->Driver.MapTextureImage(ctx, texImage, 0,
+                               xoffset, 0, width, 1,
+                               rwMode,
+                               &dstMap, &dstRowStride);
+
+   success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
+                            texImage->TexFormat,
+                            dstMap,
+                            0, 0, 0,  /* dstX/Y/Zoffset */
+                            dstRowStride,
+                            &zeroImageOffset,
+                            width, 1, 1,
+                            format, type, pixels, packing);
+
+   ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
+
+   if (!success)
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
 
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
@@ -4785,26 +4859,37 @@ _mesa_store_texsubimage2d(struct gl_context *ctx, GLenum target, GLint level,
                           struct gl_texture_object *texObj,
                           struct gl_texture_image *texImage)
 {
+   const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
+   const GLuint zeroImageOffset = 0;
+   GLubyte *dstMap;
+   GLint dstRowStride;
+   GLboolean success;
+
    /* get pointer to src pixels (may be in a pbo which we'll map here) */
    pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
                                         pixels, packing, "glTexSubImage2D");
    if (!pixels)
       return;
 
-   {
-      GLint dstRowStride = texture_row_stride(texImage);
-      GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
-                                         texImage->TexFormat,
-                                         texImage->Data,
-                                         xoffset, yoffset, 0,
-                                         dstRowStride,
-                                         texImage->ImageOffsets,
-                                         width, height, 1,
-                                         format, type, pixels, packing);
-      if (!success) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
-      }
-   }
+   /* Map dest texture buffer (write to whole region) */
+   ctx->Driver.MapTextureImage(ctx, texImage, 0,
+                               xoffset, yoffset, width, height,
+                               rwMode,
+                               &dstMap, &dstRowStride);
+
+   success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
+                            texImage->TexFormat,
+                            dstMap,
+                            0, 0, 0,  /* dstX/Y/Zoffset */
+                            dstRowStride,
+                            &zeroImageOffset,
+                            width, height, 1,
+                            format, type, pixels, packing);
+
+   ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
+
+   if (!success)
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
 
    _mesa_unmap_teximage_pbo(ctx, packing);
 }
@@ -4823,6 +4908,14 @@ _mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level,
                           struct gl_texture_object *texObj,
                           struct gl_texture_image *texImage)
 {
+   const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
+   GLboolean success;
+   GLint slice;
+   GLubyte **sliceMaps;
+   GLuint *dstImageOffsets;
+   GLint dstRowStride;
+   GLuint texelSize = _mesa_get_format_bytes(texImage->TexFormat);
+
    /* get pointer to src pixels (may be in a pbo which we'll map here) */
    pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
                                         type, pixels, packing,
@@ -4830,22 +4923,44 @@ _mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level,
    if (!pixels)
       return;
 
-   {
-      GLint dstRowStride = texture_row_stride(texImage);
-      GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
-                                         texImage->TexFormat,
-                                         texImage->Data,
-                                         xoffset, yoffset, zoffset,
-                                         dstRowStride,
-                                         texImage->ImageOffsets,
-                                         width, height, depth,
-                                         format, type, pixels, packing);
-      if (!success) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
-      }
+   sliceMaps = (GLubyte **) malloc((zoffset + depth) * sizeof(GLubyte *));
+   dstImageOffsets = (GLuint *) malloc((zoffset + depth) * sizeof(GLuint));
+
+   /* Map dest texture buffer slices */
+   for (slice = 0; slice < depth; slice++) {
+      ctx->Driver.MapTextureImage(ctx, texImage, zoffset + slice,
+                                  xoffset, yoffset, width, height,
+                                  rwMode,
+                                  &sliceMaps[zoffset + slice], &dstRowStride);
+   }
+
+   /* Compute image slice offsets */
+   for (slice = 0; slice < depth; slice++) {
+      dstImageOffsets[slice] =
+         (sliceMaps[zoffset + slice] - sliceMaps[zoffset]) / texelSize;
+   }
+
+   success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
+                            texImage->TexFormat,
+                            sliceMaps[zoffset],
+                            0, 0, 0,  /* dstX/Y/Zoffset */
+                            dstRowStride,
+                            dstImageOffsets,
+                            width, height, depth,
+                            format, type, pixels, packing);
+
+   /* Unmap dest texture buffer slices */
+   for (slice = 0; slice < depth; slice++) {
+      ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + slice);
    }
 
+   if (!success)
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
+
    _mesa_unmap_teximage_pbo(ctx, packing);
+
+   free(sliceMaps);
+   free(dstImageOffsets);
 }
 
 
@@ -4885,7 +5000,8 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx,
                                   struct gl_texture_object *texObj,
                                   struct gl_texture_image *texImage)
 {
-   (void) width; (void) height; (void) border;
+   GLubyte *dstMap;
+   GLint dstRowStride;
 
    /* This is pretty simple, basically just do a memcpy without worrying
     * about the usual image unpacking or image transfer operations.
@@ -4910,8 +5026,17 @@ _mesa_store_compressed_teximage2d(struct gl_context *ctx,
    if (!data)
       return;
 
+
+   /* Map dest texture buffer (write to whole region) */
+   ctx->Driver.MapTextureImage(ctx, texImage, 0,
+                               0, 0, width, height,
+                               GL_MAP_WRITE_BIT,
+                               &dstMap, &dstRowStride);
+
    /* copy the data */
-   memcpy(texImage->Data, data, imageSize);
+   memcpy(dstMap, data, imageSize);
+
+   ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
 
    _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
 }
@@ -4980,19 +5105,15 @@ _mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target,
                                      struct gl_texture_object *texObj,
                                      struct gl_texture_image *texImage)
 {
-   GLint bytesPerRow, destRowStride, srcRowStride;
+   GLint bytesPerRow, dstRowStride, srcRowStride;
    GLint i, rows;
-   GLubyte *dest;
+   GLubyte *dstMap;
    const GLubyte *src;
    const gl_format texFormat = texImage->TexFormat;
-   const GLint destWidth = texImage->Width;
    GLuint bw, bh;
 
    _mesa_get_format_block_size(texFormat, &bw, &bh);
 
-   (void) level;
-   (void) format;
-
    /* these should have been caught sooner */
    ASSERT((width % bw) == 0 || width == 2 || width == 1);
    ASSERT((height % bh) == 0 || height == 2 || height == 1);
@@ -5009,21 +5130,24 @@ _mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target,
    srcRowStride = _mesa_format_row_stride(texFormat, width);
    src = (const GLubyte *) data;
 
-   destRowStride = _mesa_format_row_stride(texFormat, destWidth);
-   dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
-                                         texFormat, destWidth,
-                                         (GLubyte *) texImage->Data);
+   /* Map dest texture buffer (write to whole region) */
+   ctx->Driver.MapTextureImage(ctx, texImage, 0,
+                               xoffset, yoffset, width, height,
+                               GL_MAP_WRITE_BIT,
+                               &dstMap, &dstRowStride);
 
    bytesPerRow = srcRowStride;  /* bytes per row of blocks */
    rows = height / bh;  /* rows in blocks */
 
    /* copy rows of blocks */
    for (i = 0; i < rows; i++) {
-      memcpy(dest, src, bytesPerRow);
-      dest += destRowStride;
+      memcpy(dstMap, src, bytesPerRow);
+      dstMap += dstRowStride;
       src += srcRowStride;
    }
 
+   ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
+
    _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
 }