[Mesa-dev] [PATCH] mesa: consolidate texstore functions

Jose Fonseca jfonseca at vmware.com
Thu Dec 22 08:15:47 PST 2011


Looks good to me.

Jose

----- Original Message -----
> From: Brian Paul <brianp at vmware.com>
> 
> The code for storing 1D, 2D and 3D tex images (whole or sub-images)
> was
> all pretty similar.  This consolidates those six paths.
> 
> v2: rework switch statement to catch unexpected targets
> ---
>  src/mesa/main/texstore.c |  484
>  +++++++++++++++-------------------------------
>  1 files changed, 153 insertions(+), 331 deletions(-)
> 
> diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
> index fb1ad04..86c35d3 100644
> --- a/src/mesa/main/texstore.c
> +++ b/src/mesa/main/texstore.c
> @@ -4565,9 +4565,137 @@ get_read_write_mode(GLenum userFormat,
> gl_format texFormat)
>        return GL_MAP_WRITE_BIT;
>  }
>  
> +
> +/**
> + * Helper function for storing 1D, 2D, 3D whole and subimages into
> texture
> + * memory.
> + * The source of the image data may be user memory or a PBO.  In the
> later
> + * case, we'll map the PBO, copy from it, then unmap it.
> + */
> +static void
> +store_texsubimage(struct gl_context *ctx,
> +                  struct gl_texture_image *texImage,
> +                  GLint xoffset, GLint yoffset, GLint zoffset,
> +                  GLint width, GLint height, GLint depth,
> +                  GLenum format, GLenum type, const GLvoid *pixels,
> +                  const struct gl_pixelstore_attrib *packing,
> +                  const char *caller)
> +
> +{
> +   const GLbitfield mapMode = get_read_write_mode(format,
> texImage->TexFormat);
> +   const GLenum target = texImage->TexObject->Target;
> +   GLboolean success = GL_FALSE;
> +   GLuint dims, slice, numSlices = 1, sliceOffset = 0;
> +   GLint srcImageStride = 0;
> +   const GLubyte *src;
> +
> +   assert(xoffset + width <= texImage->Width);
> +   assert(yoffset + height <= texImage->Height);
> +   assert(zoffset + depth <= texImage->Depth);
> +
> +   switch (target) {
> +   case GL_TEXTURE_1D:
> +      dims = 1;
> +      break;
> +   case GL_TEXTURE_2D_ARRAY:
> +   case GL_TEXTURE_3D:
> +      dims = 3;
> +      break;
> +   default:
> +      dims = 2;
> +   }
> +
> +   /* get pointer to src pixels (may be in a pbo which we'll map
> here) */
> +   src = (const GLubyte *)
> +      _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
> +                                  format, type, pixels, packing,
> caller);
> +   if (!src)
> +      return;
> +
> +   /* compute slice info (and do some sanity checks) */
> +   switch (target) {
> +   case GL_TEXTURE_2D:
> +   case GL_TEXTURE_RECTANGLE:
> +   case GL_TEXTURE_CUBE_MAP:
> +      /* one image slice, nothing special needs to be done */
> +      break;
> +   case GL_TEXTURE_1D:
> +      assert(height == 1);
> +      assert(depth == 1);
> +      assert(yoffset == 0);
> +      assert(zoffset == 0);
> +      break;
> +   case GL_TEXTURE_1D_ARRAY:
> +      assert(depth == 1);
> +      assert(zoffset == 0);
> +      numSlices = height;
> +      sliceOffset = yoffset;
> +      height = 1;
> +      yoffset = 0;
> +      srcImageStride = _mesa_image_row_stride(packing, width,
> format, type);
> +      break;
> +   case GL_TEXTURE_2D_ARRAY:
> +      numSlices = depth;
> +      sliceOffset = zoffset;
> +      depth = 1;
> +      zoffset = 0;
> +      srcImageStride = _mesa_image_image_stride(packing, width,
> height,
> +                                                format, type);
> +      break;
> +   case GL_TEXTURE_3D:
> +      /* we'll store 3D images as a series of slices */
> +      numSlices = depth;
> +      sliceOffset = zoffset;
> +      srcImageStride = _mesa_image_image_stride(packing, width,
> height,
> +                                                format, type);
> +      break;
> +   default:
> +      _mesa_warning(ctx, "Unexpected target 0x%x in
> store_texsubimage()", target);
> +      return;
> +   }
> +
> +   assert(numSlices == 1 || srcImageStride != 0);
> +
> +   for (slice = 0; slice < numSlices; slice++) {
> +      GLubyte *dstMap;
> +      GLint dstRowStride;
> +
> +      ctx->Driver.MapTextureImage(ctx, texImage,
> +                                  slice + sliceOffset,
> +                                  xoffset, yoffset, width, height,
> +                                  mapMode, &dstMap, &dstRowStride);
> +      if (dstMap) {
> +         /* Note: we're only storing a 2D (or 1D) slice at a time
> but we need
> +          * to pass the right 'dims' value so that
> GL_UNPACK_SKIP_IMAGES is
> +          * used for 3D images.
> +          */
> +         success = _mesa_texstore(ctx, dims, texImage->_BaseFormat,
> +                                  texImage->TexFormat,
> +                                  0, 0, 0,  /* dstX/Y/Zoffset */
> +                                  dstRowStride,
> +                                  &dstMap,
> +                                  width, height, 1,  /* w, h, d */
> +                                  format, type, src, packing);
> +
> +         ctx->Driver.UnmapTextureImage(ctx, texImage, slice +
> sliceOffset);
> +      }
> +
> +      src += srcImageStride;
> +
> +      if (!success)
> +         break;
> +   }
> +
> +   if (!success)
> +      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
> +
> +   _mesa_unmap_teximage_pbo(ctx, packing);
> +}
> +
> +
> +
>  /**
> - * This is the software fallback for Driver.TexImage1D().
> - * \sa _mesa_store_teximage2d()
> + * This is the fallback for Driver.TexImage1D().
>   */
>  void
>  _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint
>  level,
> @@ -4578,13 +4706,6 @@ _mesa_store_teximage1d(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);
> -   GLubyte *dstMap;
> -   GLint dstRowStride;
> -   GLboolean success;
> -
> -   (void) border;
> -
>     if (width == 0)
>        return;
>  
> @@ -4595,47 +4716,14 @@ _mesa_store_teximage1d(struct gl_context
> *ctx, GLenum target, GLint level,
>        return;
>     }
>  
> -   pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format,
> type,
> -                                        pixels, packing,
> "glTexImage1D");
> -   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;
> -   }
> -
> -   /* Map dest texture buffer (write to whole region) */
> -   ctx->Driver.MapTextureImage(ctx, texImage, 0,
> -                               0, 0, width, 1,
> -                               rwMode,
> -                               &dstMap, &dstRowStride);
> -   if (dstMap) {
> -      success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
> -                               texImage->TexFormat,
> -                               0, 0, 0,  /* dstX/Y/Zoffset */
> -                               0, /* dstRowStride */
> -                               &dstMap,
> -                               width, 1, 1,
> -                               format, type, pixels, packing);
> -
> -      ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
> -   }
> -   else {
> -      success = GL_FALSE;
> -   }
> -
> -   if (!success)
> -      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
> -
> -   _mesa_unmap_teximage_pbo(ctx, packing);
> +   store_texsubimage(ctx, texImage,
> +                     0, 0, 0, width, 1, 1,
> +                     format, type, pixels, packing, "glTexImage1D");
>  }
>  
>  
>  /**
> - * This is the software fallback for Driver.TexImage2D().
> - *
> - * This function is oriented toward storing images in main memory,
> rather
> - * than VRAM.  Device driver's can easily plug in their own
> replacement.
> + * This is the fallback for Driver.TexImage2D().
>   */
>  void
>  _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint
>  level,
> @@ -4646,13 +4734,6 @@ _mesa_store_teximage2d(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);
> -   GLubyte *dstMap;
> -   GLint dstRowStride;
> -   GLboolean success;
> -
> -   (void) border;
> -
>     if (width == 0 || height == 0)
>        return;
>  
> @@ -4663,80 +4744,15 @@ _mesa_store_teximage2d(struct gl_context
> *ctx, GLenum target, GLint level,
>        return;
>     }
>  
> -   pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1,
> format, type,
> -                                        pixels, packing,
> "glTexImage2D");
> -   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;
> -   }
> -
> -   if (target == GL_TEXTURE_1D_ARRAY) {
> -      const GLint srcStride =
> -         _mesa_image_row_stride(packing, width, format, type);
> -      int y;
> -
> -      success = GL_TRUE;
> -
> -      for (y = 0; y < height; y++) {
> -         /* Map dest texture buffer (write to whole region) */
> -         ctx->Driver.MapTextureImage(ctx, texImage, y,
> -                                     0, 0, width, 1,
> -                                     rwMode,
> -                                     &dstMap, &dstRowStride);
> -         if (dstMap) {
> -            success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
> -                                     texImage->TexFormat,
> -                                     0, 0, 0,  /* dstX/Y/Zoffset */
> -                                     dstRowStride,
> -                                     &dstMap,
> -                                     width, 1, 1,
> -                                     format, type, pixels, packing);
> -            ctx->Driver.UnmapTextureImage(ctx, texImage, y);
> -         }
> -         else {
> -            success = GL_FALSE;
> -         }
> -
> -         if (!success)
> -            break;
> -
> -         pixels = (const GLubyte *) pixels + srcStride;
> -      }
> -   } else {
> -      /* Map dest texture buffer (write to whole region) */
> -      ctx->Driver.MapTextureImage(ctx, texImage, 0,
> -                                  0, 0, width, height,
> -                                  rwMode,
> -                                  &dstMap, &dstRowStride);
> -      if (dstMap) {
> -         success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
> -                                  texImage->TexFormat,
> -                                  0, 0, 0,  /* dstX/Y/Zoffset */
> -                                  dstRowStride,
> -                                  &dstMap,
> -                                  width, height, 1,
> -                                  format, type, pixels, packing);
> -
> -         ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
> -      }
> -      else {
> -         success = GL_FALSE;
> -      }
> -   }
> -
> -   if (!success)
> -      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
> -
> -   _mesa_unmap_teximage_pbo(ctx, packing);
> +   store_texsubimage(ctx, texImage,
> +                     0, 0, 0, width, height, 1,
> +                     format, type, pixels, packing, "glTexImage2D");
>  }
>  
>  
>  
>  /**
> - * This is the software fallback for Driver.TexImage3D().
> - * \sa _mesa_store_teximage2d()
> + * This is the fallback for Driver.TexImage3D().
>   */
>  void
>  _mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint
>  level,
> @@ -4747,14 +4763,6 @@ _mesa_store_teximage3d(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 = GL_TRUE;
> -   GLint slice;
> -   GLubyte **sliceMaps;
> -   GLint dstRowStride;
> -
> -   (void) border;
> -
>     if (width == 0 || height == 0 || depth == 0)
>        return;
>  
> @@ -4765,66 +4773,16 @@ _mesa_store_teximage3d(struct gl_context
> *ctx, GLenum target, GLint level,
>        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;
> -   }
> -
> -   if (target == GL_TEXTURE_1D_ARRAY) {
> -      depth = height;
> -      height = 1;
> -   }
> -
> -   sliceMaps = (GLubyte **) calloc(depth, sizeof(GLubyte *));
> -
> -   /* 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);
> -      if (!sliceMaps[slice]) {
> -         success = GL_FALSE;
> -         break;
> -      }
> -   }
> -
> -   if (success) {
> -      success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
> -                               texImage->TexFormat,
> -                               0, 0, 0,  /* dstX/Y/Zoffset */
> -                               dstRowStride,
> -                               sliceMaps,
> -                               width, height, depth,
> -                               format, type, pixels, packing);
> -   }
> -
> -   /* Unmap dest texture buffer slices */
> -   for (slice = 0; slice < depth; slice++) {
> -      if (sliceMaps[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);
> +   store_texsubimage(ctx, texImage,
> +                     0, 0, 0, width, height, depth,
> +                     format, type, pixels, packing, "glTexImage3D");
>  }
>  
>  
>  
>  
>  /*
> - * This is the software fallback for Driver.TexSubImage1D()
> - * and Driver.CopyTexSubImage1D().
> + * This is the fallback for Driver.TexSubImage1D().
>   */
>  void
>  _mesa_store_texsubimage1d(struct gl_context *ctx, GLenum target,
>  GLint level,
> @@ -4834,49 +4792,15 @@ _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);
> -   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;
> -
> -   /* Map dest texture buffer */
> -   ctx->Driver.MapTextureImage(ctx, texImage, 0,
> -                               xoffset, 0, width, 1,
> -                               rwMode,
> -                               &dstMap, &dstRowStride);
> -
> -   if (dstMap) {
> -      success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
> -                               texImage->TexFormat,
> -                               0, 0, 0,  /* dstX/Y/Zoffset */
> -                               dstRowStride,
> -                               &dstMap,
> -                               width, 1, 1,
> -                               format, type, pixels, packing);
> -
> -      ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
> -   }
> -   else {
> -      success = GL_FALSE;
> -   }
> -
> -   if (!success)
> -      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
> -
> -   _mesa_unmap_teximage_pbo(ctx, packing);
> +   store_texsubimage(ctx, texImage,
> +                     xoffset, 0, 0, width, 1, 1,
> +                     format, type, pixels, packing,
> "glTexSubImage1D");
>  }
>  
>  
>  
>  /**
> - * This is the software fallback for Driver.TexSubImage2D()
> - * and Driver.CopyTexSubImage2D().
> + * This is the fallback for Driver.TexSubImage2D().
>   */
>  void
>  _mesa_store_texsubimage2d(struct gl_context *ctx, GLenum target,
>  GLint level,
> @@ -4887,69 +4811,14 @@ _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);
> -   GLboolean success = GL_FALSE;
> -   GLuint slice, numSlices, sliceOffset, srcImageStride;
> -   const GLubyte *src;
> -
> -   /* get pointer to src pixels (may be in a pbo which we'll map
> here) */
> -   src = (const GLubyte *)
> -      _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format,
> type,
> -                                  pixels, packing,
> "glTexSubImage2D");
> -   if (!src)
> -      return;
> -
> -   if (target == GL_TEXTURE_1D_ARRAY) {
> -      /* map each slice of the 1D array separately */
> -      numSlices = height;
> -      sliceOffset = yoffset;
> -      height = 1;
> -      yoffset = 0;
> -      srcImageStride = _mesa_image_row_stride(packing, width,
> format, type);
> -   }
> -   else {
> -      /* regular 2D image */
> -      numSlices = 1;
> -      sliceOffset = 0;
> -      srcImageStride = 0;
> -   }
> -
> -   for (slice = 0; slice < numSlices; slice++) {
> -      GLubyte *dstMap;
> -      GLint dstRowStride;
> -
> -      ctx->Driver.MapTextureImage(ctx, texImage,
> -                                  slice + sliceOffset,
> -                                  xoffset, yoffset, width, height,
> -                                  rwMode, &dstMap, &dstRowStride);
> -      if (dstMap) {
> -         success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
> -                                  texImage->TexFormat,
> -                                  0, 0, 0,  /* dstX/Y/Zoffset */
> -                                  dstRowStride,
> -                                  &dstMap,
> -                                  width, height, 1,  /* w, h, d */
> -                                  format, type, src, packing);
> -
> -         ctx->Driver.UnmapTextureImage(ctx, texImage, slice +
> sliceOffset);
> -      }
> -
> -      src += srcImageStride;
> -
> -      if (!success)
> -         break;
> -   }
> -
> -   if (!success)
> -      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
> -
> -   _mesa_unmap_teximage_pbo(ctx, packing);
> +   store_texsubimage(ctx, texImage,
> +                     xoffset, yoffset, 0, width, height, 1,
> +                     format, type, pixels, packing,
> "glTexSubImage2D");
>  }
>  
>  
>  /*
> - * This is the software fallback for Driver.TexSubImage3D().
> - * and Driver.CopyTexSubImage3D().
> + * This is the fallback for Driver.TexSubImage3D().
>   */
>  void
>  _mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target,
>  GLint level,
> @@ -4960,56 +4829,9 @@ _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 = GL_TRUE;
> -   GLint slice;
> -   GLubyte **sliceMaps;
> -   GLint dstRowStride;
> -
> -   /* 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,
> -                                        "glTexSubImage3D");
> -   if (!pixels)
> -      return;
> -
> -   sliceMaps = (GLubyte **) calloc(depth, sizeof(GLubyte *));
> -
> -   /* Map dest texture buffer slices */
> -   for (slice = 0; slice < depth; slice++) {
> -      ctx->Driver.MapTextureImage(ctx, texImage, zoffset + slice,
> -                                  xoffset, yoffset, width, height,
> -                                  rwMode,
> -                                  &sliceMaps[slice], &dstRowStride);
> -      if (!sliceMaps[slice]) {
> -         success = GL_FALSE;
> -         break;
> -      }
> -   }
> -
> -   if (success) {
> -      success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
> -                               texImage->TexFormat,
> -                               0, 0, 0,
> -                               dstRowStride,
> -                               sliceMaps,
> -                               width, height, depth,
> -                               format, type, pixels, packing);
> -   }
> -
> -   /* Unmap dest texture buffer slices */
> -   for (slice = 0; slice < depth; slice++) {
> -      if (sliceMaps[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);
> +   store_texsubimage(ctx, texImage,
> +                     xoffset, yoffset, zoffset, width, height,
> depth,
> +                     format, type, pixels, packing,
> "glTexSubImage3D");
>  }
>  
>  
> --
> 1.7.1
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 


More information about the mesa-dev mailing list