On Fri, Feb 27, 2015 at 4:07 PM, Laura Ekstrand <la...@jlekstrand.net> wrote:
> ---
>  src/mesa/main/teximage.c | 204 
> ++++++++++++++++++++++++++++++++++++++++-------
>  src/mesa/main/teximage.h |   3 +-
>  2 files changed, 179 insertions(+), 28 deletions(-)
>
> diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
> index dfad9ed..d454dd9 100644
> --- a/src/mesa/main/teximage.c
> +++ b/src/mesa/main/teximage.c
> @@ -4747,30 +4747,19 @@ _mesa_CompressedTexImage3D(GLenum target, GLint level,
>  void
>  _mesa_compressed_texture_sub_image(struct gl_context *ctx, GLuint dims,
>                                     struct gl_texture_object *texObj,
> +                                   struct gl_texture_image *texImage,
>                                     GLenum target, GLint level,
>                                     GLint xoffset, GLint yoffset,
>                                     GLint zoffset,
>                                     GLsizei width, GLsizei height,
>                                     GLsizei depth,
>                                     GLenum format, GLsizei imageSize,
> -                                   const GLvoid *data, bool dsa)
> +                                   const GLvoid *data)
>  {
> -   struct gl_texture_image *texImage;
> -
> -   if (compressed_subtexture_error_check(ctx, dims, texObj, target,
> -                                         level, xoffset, yoffset, zoffset,
> -                                         width, height, depth,
> -                                         format, imageSize, dsa)) {
> -      return;
> -   }
> -
>     FLUSH_VERTICES(ctx, 0);
>
>     _mesa_lock_texture(ctx, texObj);
>     {
> -      texImage = _mesa_select_tex_image(texObj, target, level);
> -      assert(texImage);
> -
>        if (width > 0 && height > 0 && depth > 0) {
>           ctx->Driver.CompressedTexSubImage(ctx, dims, texImage,
>                                             xoffset, yoffset, zoffset,
> @@ -4794,6 +4783,8 @@ _mesa_CompressedTexSubImage1D(GLenum target, GLint 
> level, GLint xoffset,
>                                GLsizei imageSize, const GLvoid *data)
>  {
>     struct gl_texture_object *texObj;
> +   struct gl_texture_image *texImage;
> +
>     GET_CURRENT_CONTEXT(ctx);
>
>     if (compressed_subtexture_target_check(ctx, target, 1, format, false,
> @@ -4805,9 +4796,20 @@ _mesa_CompressedTexSubImage1D(GLenum target, GLint 
> level, GLint xoffset,
>     if (!texObj)
>        return;
>
> -   _mesa_compressed_texture_sub_image(ctx, 1, texObj, target, level,
> +   if (compressed_subtexture_error_check(ctx, 1, texObj, target,
> +                                         level, xoffset, 0, 0,
> +                                         width, 1, 1,
> +                                         format, imageSize, false)) {
> +      return;
> +   }
> +
> +   texImage = _mesa_select_tex_image(texObj, target, level);
> +   if (!texImage)
> +      return;
> +
compressed_subtexture_error_check() already does this check. Instead add
assert(texImage) here and all other places in this patch. Otherwise patch looks
good to me.

> +   _mesa_compressed_texture_sub_image(ctx, 1, texObj, texImage, target, 
> level,
>                                        xoffset, 0, 0, width, 1, 1,
> -                                      format, imageSize, data, false);
> +                                      format, imageSize, data);
>  }
>
>  void GLAPIENTRY
> @@ -4816,6 +4818,8 @@ _mesa_CompressedTextureSubImage1D(GLuint texture, GLint 
> level, GLint xoffset,
>                                    GLsizei imageSize, const GLvoid *data)
>  {
>     struct gl_texture_object *texObj;
> +   struct gl_texture_image *texImage;
> +
>     GET_CURRENT_CONTEXT(ctx);
>
>     texObj = _mesa_lookup_texture_err(ctx, texture,
> @@ -4829,9 +4833,21 @@ _mesa_CompressedTextureSubImage1D(GLuint texture, 
> GLint level, GLint xoffset,
>        return;
>     }
>
> -   _mesa_compressed_texture_sub_image(ctx, 1, texObj, texObj->Target, level,
> +   if (compressed_subtexture_error_check(ctx, 1, texObj, texObj->Target,
> +                                         level, xoffset, 0, 0,
> +                                         width, 1, 1,
> +                                         format, imageSize, true)) {
> +      return;
> +   }
> +
> +   texImage = _mesa_select_tex_image(texObj, texObj->Target, level);
> +   if (!texImage)
> +      return;
> +
> +   _mesa_compressed_texture_sub_image(ctx, 1, texObj, texImage,
> +                                      texObj->Target, level,
>                                        xoffset, 0, 0, width, 1, 1,
> -                                      format, imageSize, data, true);
> +                                      format, imageSize, data);
>  }
>
>
> @@ -4842,6 +4858,8 @@ _mesa_CompressedTexSubImage2D(GLenum target, GLint 
> level, GLint xoffset,
>                                const GLvoid *data)
>  {
>     struct gl_texture_object *texObj;
> +   struct gl_texture_image *texImage;
> +
>     GET_CURRENT_CONTEXT(ctx);
>
>     if (compressed_subtexture_target_check(ctx, target, 2, format, false,
> @@ -4853,9 +4871,21 @@ _mesa_CompressedTexSubImage2D(GLenum target, GLint 
> level, GLint xoffset,
>     if (!texObj)
>        return;
>
> -   _mesa_compressed_texture_sub_image(ctx, 2, texObj, target, level,
> +   if (compressed_subtexture_error_check(ctx, 2, texObj, target,
> +                                         level, xoffset, yoffset, 0,
> +                                         width, height, 1,
> +                                         format, imageSize, false)) {
> +      return;
> +   }
> +
> +
> +   texImage = _mesa_select_tex_image(texObj, target, level);
> +   if (!texImage)
> +      return;
> +
> +   _mesa_compressed_texture_sub_image(ctx, 2, texObj, texImage, target, 
> level,
>                                        xoffset, yoffset, 0, width, height, 1,
> -                                      format, imageSize, data, false);
> +                                      format, imageSize, data);
>  }
>
>  void GLAPIENTRY
> @@ -4866,6 +4896,8 @@ _mesa_CompressedTextureSubImage2D(GLuint texture, GLint 
> level, GLint xoffset,
>                                    const GLvoid *data)
>  {
>     struct gl_texture_object *texObj;
> +   struct gl_texture_image *texImage;
> +
>     GET_CURRENT_CONTEXT(ctx);
>
>     texObj = _mesa_lookup_texture_err(ctx, texture,
> @@ -4879,9 +4911,21 @@ _mesa_CompressedTextureSubImage2D(GLuint texture, 
> GLint level, GLint xoffset,
>        return;
>     }
>
> -   _mesa_compressed_texture_sub_image(ctx, 2, texObj, texObj->Target, level,
> +   if (compressed_subtexture_error_check(ctx, 2, texObj, texObj->Target,
> +                                         level, xoffset, yoffset, 0,
> +                                         width, height, 1,
> +                                         format, imageSize, true)) {
> +      return;
> +   }
> +
> +   texImage = _mesa_select_tex_image(texObj, texObj->Target, level);
> +   if (!texImage)
> +      return;
> +
> +   _mesa_compressed_texture_sub_image(ctx, 2, texObj, texImage,
> +                                      texObj->Target, level,
>                                        xoffset, yoffset, 0, width, height, 1,
> -                                      format, imageSize, data, true);
> +                                      format, imageSize, data);
>  }
>
>  void GLAPIENTRY
> @@ -4891,6 +4935,8 @@ _mesa_CompressedTexSubImage3D(GLenum target, GLint 
> level, GLint xoffset,
>                                GLsizei imageSize, const GLvoid *data)
>  {
>     struct gl_texture_object *texObj;
> +   struct gl_texture_image *texImage;
> +
>     GET_CURRENT_CONTEXT(ctx);
>
>     if (compressed_subtexture_target_check(ctx, target, 3, format, false,
> @@ -4902,10 +4948,22 @@ _mesa_CompressedTexSubImage3D(GLenum target, GLint 
> level, GLint xoffset,
>     if (!texObj)
>        return;
>
> -   _mesa_compressed_texture_sub_image(ctx, 3, texObj, target, level,
> +   if (compressed_subtexture_error_check(ctx, 3, texObj, target,
> +                                         level, xoffset, yoffset, zoffset,
> +                                         width, height, depth,
> +                                         format, imageSize, false)) {
> +      return;
> +   }
> +
> +
> +   texImage = _mesa_select_tex_image(texObj, target, level);
> +   if (!texImage)
> +      return;
> +
> +   _mesa_compressed_texture_sub_image(ctx, 3, texObj, texImage, target, 
> level,
>                                        xoffset, yoffset, zoffset,
>                                        width, height, depth,
> -                                      format, imageSize, data, false);
> +                                      format, imageSize, data);
>  }
>
>  void GLAPIENTRY
> @@ -4916,6 +4974,8 @@ _mesa_CompressedTextureSubImage3D(GLuint texture, GLint 
> level, GLint xoffset,
>                                    const GLvoid *data)
>  {
>     struct gl_texture_object *texObj;
> +   struct gl_texture_image *texImage;
> +
>     GET_CURRENT_CONTEXT(ctx);
>
>     texObj = _mesa_lookup_texture_err(ctx, texture,
> @@ -4929,10 +4989,100 @@ _mesa_CompressedTextureSubImage3D(GLuint texture, 
> GLint level, GLint xoffset,
>        return;
>     }
>
> -   _mesa_compressed_texture_sub_image(ctx, 3, texObj, texObj->Target, level,
> -                                      xoffset, yoffset, zoffset,
> -                                      width, height, depth,
> -                                      format, imageSize, data, true);
> +   if (compressed_subtexture_error_check(ctx, 3, texObj, texObj->Target,
> +                                         level, xoffset, yoffset, zoffset,
> +                                         width, height, depth,
> +                                         format, imageSize, true)) {
> +      return;
> +   }
> +
> +   /* Must handle special case GL_TEXTURE_CUBE_MAP. */
> +   if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
> +      const char *pixels = data;
> +      int i;
> +      GLint image_stride;
> +
> +      /* Error checking */
> +      if (texObj->NumLayers < 6) {
> +         /* Not enough image planes for a cube map.  The spec does not say
> +          * what should happen in this case because the user has always
> +          * specified each cube face separately (using
> +          * GL_TEXTURE_CUBE_MAP_POSITIVE_X+i) in previous GL versions.
> +          * This is addressed in Khronos Bug 13223.
> +          */
> +         _mesa_error(ctx, GL_INVALID_OPERATION,
> +                     "glCompressedTextureSubImage3D"
> +                     "(insufficient cube map storage)");
> +         return;
> +      }
> +
> +      /*
> +       * What do we do if the user created a texture with the following code
> +       * and then called this function with its handle?
> +       *
> +       *    GLuint tex;
> +       *    glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &tex);
> +       *    glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
> +       *    glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, ...);
> +       *    glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, ...);
> +       *    glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, ...);
> +       *    // Note: GL_TEXTURE_CUBE_MAP_NEGATIVE_Y not set, or given the
> +       *    // wrong format, or given the wrong size, etc.
> +       *    glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, ...);
> +       *    glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, ...);
> +       *
> +       * A bug has been filed against the spec for this case.  In the
> +       * meantime, we will check for cube completeness.
> +       *
> +       * According to Section 8.17 Texture Completeness in the OpenGL 4.5
> +       * Core Profile spec (30.10.2014):
> +       *    "[A] cube map texture is cube complete if the
> +       *    following conditions all hold true: The [base level] texture
> +       *    images of each of the six cube map faces have identical, 
> positive,
> +       *    and square dimensions. The [base level] images were each 
> specified
> +       *    with the same internal format."
> +       *
> +       * It seems reasonable to check for cube completeness of an arbitrary
> +       * level here so that the image data has a consistent format and size.
> +       */
> +      if (!_mesa_cube_level_complete(texObj, level)) {
> +         _mesa_error(ctx, GL_INVALID_OPERATION,
> +                     "glCompressedTextureSubImage3D(cube map incomplete)");
> +         return;
> +      }
> +
> +      /* Copy in each face. */
> +      for (i = 0; i < 6; ++i) {
> +         texImage = texObj->Image[i][level];
> +         if (!texImage)
> +            return;
> +
> +         _mesa_compressed_texture_sub_image(ctx, 3, texObj, texImage,
> +                                            texObj->Target, level,
> +                                            xoffset, yoffset, zoffset,
> +                                            width, height, 1,
> +                                            format, imageSize, pixels);
> +
> +         /* Compressed images don't have a client format */
> +         image_stride = _mesa_format_image_size(texImage->TexFormat,
> +                                                texImage->Width,
> +                                                texImage->Height, 1);
> +
> +         pixels += image_stride;
> +         imageSize -= image_stride;
> +      }
> +   }
> +   else {
> +      texImage = _mesa_select_tex_image(texObj, texObj->Target, level);
> +      if (!texImage)
> +         return;
> +
> +      _mesa_compressed_texture_sub_image(ctx, 3, texObj, texImage,
> +                                         texObj->Target, level,
> +                                         xoffset, yoffset, zoffset,
> +                                         width, height, depth,
> +                                         format, imageSize, data);
> +   }
>  }
>
>  static mesa_format
> diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h
> index b7336bc..9468650 100644
> --- a/src/mesa/main/teximage.h
> +++ b/src/mesa/main/teximage.h
> @@ -181,13 +181,14 @@ _mesa_texture_sub_image(struct gl_context *ctx, GLuint 
> dims,
>  extern void
>  _mesa_compressed_texture_sub_image(struct gl_context *ctx, GLuint dims,
>                                     struct gl_texture_object *texObj,
> +                                   struct gl_texture_image *texImage,
>                                     GLenum target, GLint level,
>                                     GLint xoffset, GLint yoffset,
>                                     GLint zoffset,
>                                     GLsizei width, GLsizei height,
>                                     GLsizei depth,
>                                     GLenum format, GLsizei imageSize,
> -                                   const GLvoid *data, bool dsa);
> +                                   const GLvoid *data);
>
>  extern void
>  _mesa_copy_texture_sub_image(struct gl_context *ctx, GLuint dims,
> --
> 2.1.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to