diff options
-rw-r--r-- | src/mesa/main/teximage.c | 145 |
1 files changed, 64 insertions, 81 deletions
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 8885a14cc15..0f501604227 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -3525,68 +3525,74 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, /** * First-part of error checking for glCompressedTexSubImage[123]D(). * These are the checks which are independent of the destination image. - * \return GL_TRUE if error, GL_FALSE otherwise + * \return error code or GL_NO_ERROR. */ -static GLboolean -compressed_subtexture_error_check1(struct gl_context *ctx, GLint dims, - GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLsizei depth, - GLenum format, GLsizei imageSize) +static GLenum +compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize) { - GLint expectedSize; - GLboolean targetOK = GL_TRUE; + GLint expectedSize, maxLevels = 0, maxTextureSize; + + (void) zoffset; - /* check the target */ - if (dims == 1 || dims == 3) { - /* No 1D/3D compressed textures at this time */ - targetOK = GL_FALSE; + if (dimensions == 1) { + /* 1D compressed textures not allowed */ + return GL_INVALID_ENUM; } - else { - assert(dims == 2); - switch (target) { - case GL_PROXY_TEXTURE_2D: - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - /* XXX texture rectangle? */ - /* OK */ - default: - targetOK = GL_FALSE; + else if (dimensions == 2) { + if (target == GL_PROXY_TEXTURE_2D) { + maxLevels = ctx->Const.MaxTextureLevels; + } + else if (target == GL_TEXTURE_2D) { + maxLevels = ctx->Const.MaxTextureLevels; + } + else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { + if (!ctx->Extensions.ARB_texture_cube_map) + return GL_INVALID_ENUM; /*target*/ + maxLevels = ctx->Const.MaxCubeTextureLevels; + } + else if (_mesa_is_cube_face(target)) { + if (!ctx->Extensions.ARB_texture_cube_map) + return GL_INVALID_ENUM; /*target*/ + maxLevels = ctx->Const.MaxCubeTextureLevels; + } + else { + return GL_INVALID_ENUM; /*target*/ } } - - if (!targetOK) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glCompressedTexSubImage%uD(target=0x%x)", dims, target); - return GL_TRUE; + else if (dimensions == 3) { + /* 3D compressed textures not allowed */ + return GL_INVALID_ENUM; } + maxTextureSize = 1 << (maxLevels - 1); + /* this will catch any invalid compressed format token */ - if (!_mesa_is_compressed_format(ctx, format)) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glCompressedTexSubImage%uD(format)", dims); - return GL_TRUE; - } + if (!_mesa_is_compressed_format(ctx, format)) + return GL_INVALID_ENUM; - if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glCompressedTexSubImage%uD(level=%d)", dims, level); - return GL_TRUE; - } + if (width < 1 || width > maxTextureSize) + return GL_INVALID_VALUE; + + if ((height < 1 || height > maxTextureSize) + && dimensions > 1) + return GL_INVALID_VALUE; + + if (level < 0 || level >= maxLevels) + return GL_INVALID_VALUE; + + /* + * do checks which depend on compression block size + */ expectedSize = compressed_tex_size(width, height, depth, format); - if (expectedSize != imageSize) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glCompressedTexSubImage%uD(imageSize=%d)", dims, imageSize); - return GL_TRUE; - } + if (expectedSize != imageSize) + return GL_INVALID_VALUE; - return GL_FALSE; + return GL_NO_ERROR; } @@ -3596,7 +3602,7 @@ compressed_subtexture_error_check1(struct gl_context *ctx, GLint dims, */ static GLboolean compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims, - GLint xoffset, GLint yoffset, GLint zoffset, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, struct gl_texture_image *texImage) @@ -3608,32 +3614,6 @@ compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims, return GL_TRUE; } - /* check for negative offsets */ - if (xoffset < 0 || yoffset < 0 || zoffset < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glCompressedTexSubImage%uD(xoffset=%d yoffset=%d " - "zoffset=%d)", dims, xoffset, yoffset, zoffset); - return GL_TRUE; - } - - /* check for bad width, height, depth */ - if (width < 0 || height < 0 || depth < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glCompressedTexSubImage%uD(width=%d height=%d depth=%d)", - dims, width, height, depth); - return GL_TRUE; - } - - /* check offset + size */ - if (xoffset + width > texImage->Width || - yoffset + height > texImage->Height || - zoffset + depth > texImage->Depth) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glCompressedTexSubImage%uD(x+width, y+height, z+depth)", - dims); - return GL_TRUE; - } - if (compressedteximage_only_format(ctx, format)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCompressedTexSubImage%uD(format=0x%x cannot be updated)" @@ -3699,13 +3679,16 @@ compressed_tex_sub_image(GLuint dims, GLenum target, GLint level, { struct gl_texture_object *texObj; struct gl_texture_image *texImage; + GLenum error; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (compressed_subtexture_error_check1(ctx, dims, target, level, - xoffset, yoffset, - width, height, depth, /* size */ - format, imageSize)) { + error = compressed_subtexture_error_check(ctx, dims, target, level, + xoffset, 0, 0, /* pos */ + width, height, depth, /* size */ + format, imageSize); + if (error) { + _mesa_error(ctx, error, "glCompressedTexSubImage%uD", dims); return; } @@ -3717,7 +3700,7 @@ compressed_tex_sub_image(GLuint dims, GLenum target, GLint level, assert(texImage); if (compressed_subtexture_error_check2(ctx, dims, xoffset, yoffset, - zoffset, width, height, depth, + width, height, depth, format, texImage)) { /* error was recorded */ } |