diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/main/teximage.c | 145 |
1 files changed, 81 insertions, 64 deletions
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 0f501604227..8885a14cc15 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -3525,74 +3525,68 @@ _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 error code or GL_NO_ERROR. + * \return GL_TRUE if error, GL_FALSE otherwise */ -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) +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) { - GLint expectedSize, maxLevels = 0, maxTextureSize; - - (void) zoffset; + GLint expectedSize; + GLboolean targetOK = GL_TRUE; - if (dimensions == 1) { - /* 1D compressed textures not allowed */ - return GL_INVALID_ENUM; + /* check the target */ + if (dims == 1 || dims == 3) { + /* No 1D/3D compressed textures at this time */ + 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*/ + 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 == 3) { - /* 3D compressed textures not allowed */ - return GL_INVALID_ENUM; - } - maxTextureSize = 1 << (maxLevels - 1); + if (!targetOK) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glCompressedTexSubImage%uD(target=0x%x)", dims, target); + return GL_TRUE; + } /* this will catch any invalid compressed format token */ - if (!_mesa_is_compressed_format(ctx, format)) - return GL_INVALID_ENUM; - - 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; + if (!_mesa_is_compressed_format(ctx, format)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glCompressedTexSubImage%uD(format)", dims); + return GL_TRUE; + } - /* - * do checks which depend on compression block size - */ + 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; + } expectedSize = compressed_tex_size(width, height, depth, format); - if (expectedSize != imageSize) - return GL_INVALID_VALUE; + if (expectedSize != imageSize) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCompressedTexSubImage%uD(imageSize=%d)", dims, imageSize); + return GL_TRUE; + } - return GL_NO_ERROR; + return GL_FALSE; } @@ -3602,7 +3596,7 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions, */ static GLboolean compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims, - GLint xoffset, GLint yoffset, + GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, struct gl_texture_image *texImage) @@ -3614,6 +3608,32 @@ 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)" @@ -3679,16 +3699,13 @@ 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); - 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); + if (compressed_subtexture_error_check1(ctx, dims, target, level, + xoffset, yoffset, + width, height, depth, /* size */ + format, imageSize)) { return; } @@ -3700,7 +3717,7 @@ compressed_tex_sub_image(GLuint dims, GLenum target, GLint level, assert(texImage); if (compressed_subtexture_error_check2(ctx, dims, xoffset, yoffset, - width, height, depth, + zoffset, width, height, depth, format, texImage)) { /* error was recorded */ } |