/**
* 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;
}
*/
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)
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)"
{
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;
}
assert(texImage);
if (compressed_subtexture_error_check2(ctx, dims, xoffset, yoffset,
- zoffset, width, height, depth,
+ width, height, depth,
format, texImage)) {
/* error was recorded */
}