[Mesa-dev] [PATCH 18/37] mesa: Convert texstore.c to accessing textures using MapTextureImage.

Ian Romanick idr at freedesktop.org
Mon Aug 15 18:47:07 PDT 2011


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 08/15/2011 11:53 AM, Eric Anholt wrote:
> From: Brian Paul <brianp at vmware.com>
> 
> This continues to allocate texImage->Data as before, so
> drivers calling these functions need to use that when present.
> ---
>  src/mesa/main/texstore.c |  336 +++++++++++++++++++++++++++++++---------------
>  1 files changed, 225 insertions(+), 111 deletions(-)
> 
> diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
> index c4aeaa8..88726ad 100644
> --- a/src/mesa/main/texstore.c
> +++ b/src/mesa/main/texstore.c
> @@ -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 intsert the depth or stencil values.
                                          ^^^^^^^ insert

> + * \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,62 @@ _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");
> -      return;
> -   }
> -
> -   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 +4799,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 +4849,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 +4898,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 +4913,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 +4990,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 +5016,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 +5095,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 +5120,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);
>  }
>  

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAk5JzBsACgkQX1gOwKyEAw9vMQCfUnyDmftJWcdbter1kRrgcZdj
FtsAn3gRIbSh4ml0YRhp3pjCtfj+YBWP
=aCYC
-----END PGP SIGNATURE-----


More information about the mesa-dev mailing list