--- 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; + + _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