[Mesa-dev] [PATCH 2/3] mesa: consolidate glTexImage and glCompressedTexImage code

Brian Paul brianp at vmware.com
Tue Aug 21 19:30:00 PDT 2012


There was a lot of similar or duplicated code before.
To minimize this patch's size, use a forward declaration for
compressed_texture_error_check().  Move the function in the next patch.
---
 src/mesa/main/teximage.c |  319 ++++++++++++++++++----------------------------
 1 files changed, 122 insertions(+), 197 deletions(-)

diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index c645721..8dc8e3f 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -1766,6 +1766,13 @@ texture_error_check( struct gl_context *ctx,
 }
 
 
+static GLenum
+compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
+                               GLenum target, GLint level,
+                               GLenum internalFormat, GLsizei width,
+                               GLsizei height, GLsizei depth, GLint border,
+                               GLsizei imageSize);
+
 /**
  * Test glTexSubImage[123]D() parameters for errors.
  * 
@@ -2480,16 +2487,23 @@ strip_texture_border(GLenum target,
    }
 }
 
+
 /**
- * Common code to implement all the glTexImage1D/2D/3D functions.
+ * Common code to implement all the glTexImage1D/2D/3D functions
+ * as well as glCompressedTexImage1D/2D/3D.
+ * \param compressed  only GL_TRUE for glCompressedTexImage1D/2D/3D calls.
+ * \param format  the user's image format (only used if !compressed)
+ * \param type  the user's image type (only used if !compressed)
+ * \param imageSize  only used for glCompressedTexImage1D/2D/3D calls.
  */
 static void
-teximage(struct gl_context *ctx, GLuint dims,
+teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
          GLenum target, GLint level, GLint internalFormat,
          GLsizei width, GLsizei height, GLsizei depth,
          GLint border, GLenum format, GLenum type,
-         const GLvoid *pixels)
+         GLsizei imageSize, const GLvoid *pixels)
 {
+   const char *func = compressed ? "glCompressedTexImage" : "glTexImage";
    GLenum error;
    struct gl_pixelstore_attrib unpack_no_border;
    const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
@@ -2497,8 +2511,8 @@ teximage(struct gl_context *ctx, GLuint dims,
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx, "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n",
-                  dims,
+      _mesa_debug(ctx, "%s%uD %s %d %s %d %d %d %d %s %s %p\n",
+                  func, dims,
                   _mesa_lookup_enum_by_nr(target), level,
                   _mesa_lookup_enum_by_nr(internalFormat),
                   width, height, depth, border,
@@ -2509,14 +2523,46 @@ teximage(struct gl_context *ctx, GLuint dims,
 
    /* target error checking */
    if (!legal_teximage_target(ctx, dims, target)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uD(target=%s)",
-                  dims, _mesa_lookup_enum_by_nr(target));
+      _mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)",
+                  func, dims, _mesa_lookup_enum_by_nr(target));
       return;
    }
 
    /* general error checking */
-   error = texture_error_check(ctx, dims, target, level, internalFormat,
-                               format, type, width, height, depth, border);
+   if (compressed) {
+      error = compressed_texture_error_check(ctx, dims, target, level,
+                                             internalFormat,
+                                             width, height, depth,
+                                             border, imageSize);
+   }
+   else {
+      error = texture_error_check(ctx, dims, target, level, internalFormat,
+                                  format, type, width, height, depth, border);
+   }
+
+#if FEATURE_ES
+   /* Here we convert a cpal compressed image into a regular glTexImage2D
+    * call by decompressing the texture.  If we really want to support cpal
+    * textures in any driver this would have to be changed.
+    */
+   if (compressed && !error && dims == 2) {
+      switch (internalFormat) {
+      case GL_PALETTE4_RGB8_OES:
+      case GL_PALETTE4_RGBA8_OES:
+      case GL_PALETTE4_R5_G6_B5_OES:
+      case GL_PALETTE4_RGBA4_OES:
+      case GL_PALETTE4_RGB5_A1_OES:
+      case GL_PALETTE8_RGB8_OES:
+      case GL_PALETTE8_RGBA8_OES:
+      case GL_PALETTE8_R5_G6_B5_OES:
+      case GL_PALETTE8_RGBA4_OES:
+      case GL_PALETTE8_RGB5_A1_OES:
+         _mesa_cpal_compressed_teximage2d(target, level, internalFormat,
+                                          width, height, imageSize, data);
+         return;
+      }
+   }
+#endif
 
    if (_mesa_is_proxy_texture(target)) {
       /* Proxy texture: just clear or set state depending on error checking */
@@ -2537,8 +2583,6 @@ teximage(struct gl_context *ctx, GLuint dims,
          }
       }
 
-      texImage = get_proxy_tex_image(ctx, target, level);
-
       if (error == PROXY_ERROR) {
          /* image too large, etc.  Clear all proxy texture image parameters. */
          if (texImage)
@@ -2585,7 +2629,7 @@ teximage(struct gl_context *ctx, GLuint dims,
 	 texImage = _mesa_get_tex_image(ctx, texObj, target, level);
 
 	 if (!texImage) {
-	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
+	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims);
 	 }
          else {
             gl_format texFormat;
@@ -2602,8 +2646,14 @@ teximage(struct gl_context *ctx, GLuint dims,
                                           border, internalFormat, texFormat);
 
                /* Give the texture to the driver.  <pixels> may be null. */
-               ctx->Driver.TexImage(ctx, dims, texImage, format,
-                                    type, pixels, unpack);
+               if (compressed) {
+                  ctx->Driver.CompressedTexImage(ctx, dims, texImage,
+                                                 imageSize, pixels);
+               }
+               else {
+                  ctx->Driver.TexImage(ctx, dims, texImage, format,
+                                       type, pixels, unpack);
+               }
 
                check_gen_mipmap(ctx, target, texObj, level);
 
@@ -2612,7 +2662,7 @@ teximage(struct gl_context *ctx, GLuint dims,
                _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
             }
             else {
-               _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
+               _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims);
             }
          }
       }
@@ -2630,8 +2680,8 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
                   GLenum type, const GLvoid *pixels )
 {
    GET_CURRENT_CONTEXT(ctx);
-   teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
-            border, format, type, pixels);
+   teximage(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1, 1,
+            border, format, type, 0, pixels);
 }
 
 
@@ -2642,8 +2692,8 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
                   const GLvoid *pixels )
 {
    GET_CURRENT_CONTEXT(ctx);
-   teximage(ctx, 2, target, level, internalFormat, width, height, 1,
-            border, format, type, pixels);
+   teximage(ctx, GL_FALSE, 2, target, level, internalFormat, width, height, 1,
+            border, format, type, 0, pixels);
 }
 
 
@@ -2658,8 +2708,9 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
                   const GLvoid *pixels )
 {
    GET_CURRENT_CONTEXT(ctx);
-   teximage(ctx, 3, target, level, internalFormat, width, height, depth,
-            border, format, type, pixels);
+   teximage(ctx, GL_FALSE, 3, target, level, internalFormat,
+            width, height, depth,
+            border, format, type, 0, pixels);
 }
 
 
@@ -3126,7 +3177,7 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
                                GLenum target, GLint level,
                                GLenum internalFormat, GLsizei width,
                                GLsizei height, GLsizei depth, GLint border,
-                               GLsizei imageSize, char **reason)
+                               GLsizei imageSize)
 {
    const GLenum proxyTarget = get_proxy_target(target);
    const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
@@ -3134,18 +3185,20 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
    GLenum choose_format;
    GLenum choose_type;
    GLenum proxy_format;
-
-   *reason = ""; /* no error */
+   GLenum error = GL_NO_ERROR;
+   char *reason = ""; /* no error */
 
    if (!target_can_be_compressed(ctx, target, internalFormat)) {
-      *reason = "target";
-      return GL_INVALID_ENUM;
+      reason = "target";
+      error = GL_INVALID_ENUM;
+      goto error;
    }
 
    /* This will detect any invalid internalFormat value */
    if (!_mesa_is_compressed_format(ctx, internalFormat)) {
-      *reason = "internalFormat";
-      return GL_INVALID_ENUM;
+      reason = "internalFormat";
+      error = GL_INVALID_ENUM;
+      goto error;
    }
 
    switch (internalFormat) {
@@ -3164,15 +3217,17 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
 					&choose_type);
       proxy_format = choose_format;
 
-      /* check level */
+      /* check level (note that level should be zero or less!) */
       if (level > 0 || level < -maxLevels) {
-	 *reason = "level";
-	 return GL_INVALID_VALUE;
+	 reason = "level";
+	 error = GL_INVALID_VALUE;
+         goto error;
       }
 
       if (dimensions != 2) {
-	 *reason = "compressed paletted textures must be 2D";
-	 return GL_INVALID_OPERATION;
+	 reason = "compressed paletted textures must be 2D";
+	 error = GL_INVALID_OPERATION;
+         goto error;
       }
 
       /* Figure out the expected texture size (in bytes).  This will be
@@ -3199,8 +3254,9 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
 
       /* check level */
       if (level < 0 || level >= maxLevels) {
-	 *reason = "level";
-	 return GL_INVALID_VALUE;
+	 reason = "level";
+	 error = GL_INVALID_VALUE;
+         goto error;
       }
 
       /* Figure out the expected texture size (in bytes).  This will be
@@ -3212,20 +3268,23 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
 
    /* This should really never fail */
    if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
-      *reason = "internalFormat";
-      return GL_INVALID_ENUM;
+      reason = "internalFormat";
+      error = GL_INVALID_ENUM;
+      goto error;
    }
 
    /* No compressed formats support borders at this time */
    if (border != 0) {
-      *reason = "border != 0";
-      return GL_INVALID_VALUE;
+      reason = "border != 0";
+      error = GL_INVALID_VALUE;
+      goto error;
    }
 
    /* For cube map, width must equal height */
    if (_mesa_is_cube_face(target) && width != height) {
-      *reason = "width != height";
-      return GL_INVALID_VALUE;
+      reason = "width != height";
+      error = GL_INVALID_VALUE;
+      goto error;
    }
 
    /* check image size against compression block size */
@@ -3243,8 +3302,9 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
           * generated [...] if any parameter combinations are not
           * supported by the specific compressed internal format. 
           */
-         *reason = "invalid width or height for compression format";
-         return GL_INVALID_OPERATION;
+         reason = "invalid width or height for compression format";
+         error = GL_INVALID_OPERATION;
+         goto error;
       }
    }
 
@@ -3254,11 +3314,12 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
 				      choose_type,
 				      width, height, depth, border)) {
       /* See error comment above */
-      *reason = "invalid width, height or format";
       if (target == proxyTarget) {
          return PROXY_ERROR;
       }
-      return GL_INVALID_OPERATION;
+      reason = "invalid width, height or format";
+      error = GL_INVALID_OPERATION;
+      goto error;
    }
 
    /* check image size in bytes */
@@ -3267,16 +3328,22 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
        * if <imageSize> is not consistent with the format, dimensions, and
        * contents of the specified image.
        */
-      *reason = "imageSize inconsistant with width/height/format";
-      return GL_INVALID_VALUE;
+      reason = "imageSize inconsistant with width/height/format";
+      error = GL_INVALID_VALUE;
+      goto error;
    }
 
    if (!mutable_tex_object(ctx, target)) {
-      *reason = "immutable texture";
-      return GL_INVALID_OPERATION;
+      reason = "immutable texture";
+      error = GL_INVALID_OPERATION;
+      goto error;
    }
 
    return GL_NO_ERROR;
+
+error:
+   _mesa_error(ctx, error, "glCompressedTexImage%dD(%s)", dimensions, reason);
+   return error;
 }
 
 
@@ -3422,148 +3489,6 @@ compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims,
 }
 
 
-/**
- * Implementation of the glCompressedTexImage1/2/3D() functions.
- */
-static void
-compressedteximage(struct gl_context *ctx, GLuint dims,
-                   GLenum target, GLint level,
-                   GLenum internalFormat, GLsizei width,
-                   GLsizei height, GLsizei depth, GLint border,
-                   GLsizei imageSize, const GLvoid *data)
-{
-   GLenum error;
-   char *reason = "";
-
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
-   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
-      _mesa_debug(ctx,
-                  "glCompressedTexImage%uDARB %s %d %s %d %d %d %d %d %p\n",
-                  dims,
-                  _mesa_lookup_enum_by_nr(target), level,
-                  _mesa_lookup_enum_by_nr(internalFormat),
-                  width, height, depth, border, imageSize, data);
-
-   /* check target */
-   if (!legal_teximage_target(ctx, dims, target)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage%uD(target=%s)",
-                  dims, _mesa_lookup_enum_by_nr(target));
-      return;
-   }
-
-   error = compressed_texture_error_check(ctx, dims, target, level,
-                                          internalFormat, width, height, depth,
-                                          border, imageSize, &reason);
-
-#if FEATURE_ES
-   /* XXX this is kind of a hack */
-   if (!error && dims == 2) {
-      switch (internalFormat) {
-      case GL_PALETTE4_RGB8_OES:
-      case GL_PALETTE4_RGBA8_OES:
-      case GL_PALETTE4_R5_G6_B5_OES:
-      case GL_PALETTE4_RGBA4_OES:
-      case GL_PALETTE4_RGB5_A1_OES:
-      case GL_PALETTE8_RGB8_OES:
-      case GL_PALETTE8_RGBA8_OES:
-      case GL_PALETTE8_R5_G6_B5_OES:
-      case GL_PALETTE8_RGBA4_OES:
-      case GL_PALETTE8_RGB5_A1_OES:
-         _mesa_cpal_compressed_teximage2d(target, level, internalFormat,
-                                          width, height, imageSize, data);
-         return;
-      }
-   }
-#endif
-
-   if (_mesa_is_proxy_texture(target)) {
-      /* Proxy texture: just check for errors and update proxy state */
-      struct gl_texture_image *texImage =
-         get_proxy_tex_image(ctx, target, level);
-      gl_format texFormat = MESA_FORMAT_NONE;
-
-      if (!error) {
-         /* No parameter errors.  Choose a texture format and see if we
-          * can really allocate the texture.
-          */
-         struct gl_texture_object *texObj =
-            _mesa_get_current_tex_object(ctx, target);
-         texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
-                                                 internalFormat,
-                                                 GL_NONE, GL_NONE);
-         if (!legal_texture_size(ctx, texFormat, width, height, depth)) {
-            error = PROXY_ERROR;
-         }
-      }
-
-      if (error == PROXY_ERROR) {
-         /* image too large, etc.  Clear all proxy texture image parameters. */
-         if (texImage)
-            clear_teximage_fields(texImage);
-      }
-      else if (error == GL_NO_ERROR) {
-         /* no error: store the teximage parameters */
-         if (texImage)
-            _mesa_init_teximage_fields(ctx, texImage, width, height, depth,
-                                       border, internalFormat, texFormat);
-      }
-      else {
-         /* other, regular error */
-         _mesa_error(ctx, error, "glCompressedTexImage%uD(%s)", dims, reason);
-      }
-   }
-   else {
-      /* non-proxy target */
-      struct gl_texture_object *texObj;
-      struct gl_texture_image *texImage;
-
-      if (error) {
-         _mesa_error(ctx, error, "glCompressedTexImage%uD(%s)", dims, reason);
-         return;
-      }
-
-      texObj = _mesa_get_current_tex_object(ctx, target);
-
-      _mesa_lock_texture(ctx, texObj);
-      {
-	 texImage = _mesa_get_tex_image(ctx, texObj, target, level);
-	 if (!texImage) {
-	    _mesa_error(ctx, GL_OUT_OF_MEMORY,
-                        "glCompressedTexImage%uD", dims);
-	 }
-         else {
-            gl_format texFormat;
-
-            ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
-
-            texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
-                                                    internalFormat, GL_NONE,
-                                                    GL_NONE);
-
-            if (legal_texture_size(ctx, texFormat, width, height, depth)) {
-               _mesa_init_teximage_fields(ctx, texImage,
-                                          width, height, depth,
-                                          border, internalFormat, texFormat);
-
-               ctx->Driver.CompressedTexImage(ctx, dims, texImage, imageSize,
-                                              data);
-
-               check_gen_mipmap(ctx, target, texObj, level);
-
-               _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
-            }
-            else {
-               _mesa_error(ctx, GL_OUT_OF_MEMORY,
-                           "glCompressedTexImage%uD", dims);
-            }
-         }
-      }
-      _mesa_unlock_texture(ctx, texObj);
-   }
-}
-
-
 void GLAPIENTRY
 _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
                               GLenum internalFormat, GLsizei width,
@@ -3571,8 +3496,8 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
                               const GLvoid *data)
 {
    GET_CURRENT_CONTEXT(ctx);
-   compressedteximage(ctx, 1, target, level, internalFormat,
-                      width, 1, 1, border, imageSize, data);
+   teximage(ctx, GL_TRUE, 1, target, level, internalFormat,
+            width, 1, 1, border, GL_NONE, GL_NONE, imageSize, data);
 }
 
 
@@ -3583,8 +3508,8 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
                               const GLvoid *data)
 {
    GET_CURRENT_CONTEXT(ctx);
-   compressedteximage(ctx, 2, target, level, internalFormat,
-                      width, height, 1, border, imageSize, data);
+   teximage(ctx, GL_TRUE, 2, target, level, internalFormat,
+            width, height, 1, border, GL_NONE, GL_NONE, imageSize, data);
 }
 
 
@@ -3595,8 +3520,8 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
                               GLsizei imageSize, const GLvoid *data)
 {
    GET_CURRENT_CONTEXT(ctx);
-   compressedteximage(ctx, 3, target, level, internalFormat,
-                      width, height, depth, border, imageSize, data);
+   teximage(ctx, GL_TRUE, 3, target, level, internalFormat,
+            width, height, depth, border, GL_NONE, GL_NONE, imageSize, data);
 }
 
 
-- 
1.7.3.4



More information about the mesa-dev mailing list