error:
/* Note: not all error paths exit through here. */
- _mesa_error(ctx, error, "glCompressedTexImage%dD(%s)", dimensions, reason);
+ _mesa_error(ctx, error, "glCompressedTexImage%dD(%s)",
+ dimensions, reason);
return GL_TRUE;
}
*/
static GLboolean
compressed_subtexture_error_check(struct gl_context *ctx, GLint dims,
+ const struct gl_texture_object *texObj,
GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLsizei imageSize)
+ GLenum format, GLsizei imageSize, bool dsa)
{
- struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
GLint expectedSize;
GLboolean targetOK;
+ const char *suffix = dsa ? "ture" : "";
+
+ if (dsa && target == GL_TEXTURE_RECTANGLE) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCompressedSubTexture%dD(target)", dims);
+ return GL_TRUE;
+ }
switch (dims) {
case 2:
}
break;
case 3:
- targetOK = (target == GL_TEXTURE_2D_ARRAY);
+ targetOK = (target == GL_TEXTURE_3D) ||
+ (target == GL_TEXTURE_2D_ARRAY) ||
+ (target == GL_TEXTURE_CUBE_MAP_ARRAY) ||
+ (target == GL_TEXTURE_CUBE_MAP && dsa);
+
+ /* OpenGL 4.5 spec (30.10.2014) says in Section 8.7 Compressed Texture
+ * Images:
+ * "An INVALID_OPERATION error is generated by
+ * CompressedTex*SubImage3D if the internal format of the texture is
+ * one of the EAC, ETC2, or RGTC formats and either border is
+ * non-zero, or the effective target for the texture is not
+ * TEXTURE_2D_ARRAY."
+ */
+ if (target != GL_TEXTURE_2D_ARRAY) {
+ bool invalidformat;
+ switch (format) {
+ /* These came from _mesa_is_compressed_format in glformats.c. */
+ /* EAC formats */
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ case GL_COMPRESSED_R11_EAC:
+ case GL_COMPRESSED_RG11_EAC:
+ case GL_COMPRESSED_SIGNED_R11_EAC:
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ /* ETC2 formats */
+ case GL_COMPRESSED_RGB8_ETC2:
+ case GL_COMPRESSED_SRGB8_ETC2:
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ /* RGTC formats */
+ case GL_COMPRESSED_RED_RGTC1:
+ case GL_COMPRESSED_SIGNED_RED_RGTC1:
+ case GL_COMPRESSED_RG_RGTC2:
+ case GL_COMPRESSED_SIGNED_RG_RGTC2:
+ invalidformat = true;
+ break;
+ default:
+ invalidformat = false;
+ }
+ if (invalidformat) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCompressedTex%sSubImage%uD(target)", suffix, dims);
+ return GL_TRUE;
+ }
+ }
+
break;
default:
assert(dims == 1);
}
if (!targetOK) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexSubImage%uD(target)",
- dims);
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glCompressedTex%sSubImage%uD(target)", suffix, dims);
return GL_TRUE;
}
/* this will catch any invalid compressed format token */
if (!_mesa_is_compressed_format(ctx, format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage%uD(format)",
- dims);
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glCompressedTex%sSubImage%uD(format)", suffix, dims);
return GL_TRUE;
}
if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage%uD(level=%d)",
- dims, level);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCompressedTex%sSubImage%uD(level=%d)",
+ suffix, dims, level);
return GL_TRUE;
}
/* Check for invalid pixel storage modes */
if (!_mesa_compressed_pixel_storage_error_check(ctx, dims,
- &ctx->Unpack,
- "glCompressedTexSubImage")) {
+ &ctx->Unpack,
+ dsa ? "glCompressedTextureSubImage" :
+ "glCompressedTexSubImage")) {
return GL_TRUE;
}
expectedSize = compressed_tex_size(width, height, depth, format);
if (expectedSize != imageSize) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage%uD(size=%d)",
- dims, imageSize);
- return GL_TRUE;
- }
-
- texObj = _mesa_get_current_tex_object(ctx, target);
- if (!texObj) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY,
- "glCompressedTexSubImage%uD()", dims);
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCompressedTex%sSubImage%uD(size=%d)",
+ suffix, dims, imageSize);
return GL_TRUE;
}
texImage = _mesa_select_tex_image(texObj, target, level);
if (!texImage) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glCompressedTexSubImage%uD(invalid texture image)", dims);
+ "glCompressedTex%sSubImage%uD(invalid texture image)",
+ suffix, dims);
return GL_TRUE;
}
if ((GLint) format != texImage->InternalFormat) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glCompressedTexSubImage%uD(format=0x%x)", dims, format);
+ "glCompressedTex%sSubImage%uD(format=0x%x)",
+ suffix, dims, format);
return GL_TRUE;
}
if (compressedteximage_only_format(ctx, format)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glCompressedTexSubImage%uD(format=0x%x cannot be updated)"
- , dims, format);
+ "glCompressedTex%sSubImage%uD(format=0x%x cannot be updated)",
+ suffix, dims, format);
return GL_TRUE;
}
/**
- * Common helper for glCompressedTexSubImage1/2/3D().
+ * Common helper for glCompressedTexSubImage1/2/3D() and
+ * glCompressedTextureSubImage1/2/3D().
*/
-static void
-compressed_tex_sub_image(GLuint dims, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLsizei imageSize, const GLvoid *data)
+void
+_mesa_compressed_texture_sub_image(struct gl_context *ctx, GLuint dims,
+ struct gl_texture_object *texObj,
+ 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)
{
- struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- GET_CURRENT_CONTEXT(ctx);
- FLUSH_VERTICES(ctx, 0);
- if (compressed_subtexture_error_check(ctx, dims, target, level,
- xoffset, yoffset, zoffset,
+ if (compressed_subtexture_error_check(ctx, dims, texObj, target,
+ level, xoffset, yoffset, zoffset,
width, height, depth,
- format, imageSize)) {
+ format, imageSize, dsa)) {
return;
}
- texObj = _mesa_get_current_tex_object(ctx, target);
+ FLUSH_VERTICES(ctx, 0);
_mesa_lock_texture(ctx, texObj);
{
void GLAPIENTRY
_mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset,
- GLsizei width, GLenum format,
- GLsizei imageSize, const GLvoid *data)
+ GLsizei width, GLenum format,
+ GLsizei imageSize, const GLvoid *data)
{
- compressed_tex_sub_image(1, target, level, xoffset, 0, 0, width, 1, 1,
- format, imageSize, data);
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
+ if (!texObj)
+ return;
+
+ _mesa_compressed_texture_sub_image(ctx, 1, texObj, target, level,
+ xoffset, 0, 0, width, 1, 1,
+ format, imageSize, data, false);
+}
+
+void GLAPIENTRY
+_mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset,
+ GLsizei width, GLenum format,
+ GLsizei imageSize, const GLvoid *data)
+{
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+
+ texObj = _mesa_lookup_texture_err(ctx, texture,
+ "glCompressedTextureSubImage1D");
+ if (!texObj)
+ return;
+
+ _mesa_compressed_texture_sub_image(ctx, 1, texObj, texObj->Target, level,
+ xoffset, 0, 0, width, 1, 1,
+ format, imageSize, data, true);
}
void GLAPIENTRY
_mesa_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
- GLint yoffset, GLsizei width, GLsizei height,
- GLenum format, GLsizei imageSize,
- const GLvoid *data)
+ GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize,
+ const GLvoid *data)
{
- compressed_tex_sub_image(2, target, level, xoffset, yoffset, 0,
- width, height, 1, format, imageSize, data);
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
+ if (!texObj)
+ return;
+
+ _mesa_compressed_texture_sub_image(ctx, 2, texObj, target, level,
+ xoffset, yoffset, 0, width, height, 1,
+ format, imageSize, data, false);
}
+void GLAPIENTRY
+_mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset,
+ GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize,
+ const GLvoid *data)
+{
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+
+ texObj = _mesa_lookup_texture_err(ctx, texture,
+ "glCompressedTextureSubImage2D");
+ if (!texObj)
+ return;
+
+ _mesa_compressed_texture_sub_image(ctx, 2, texObj, texObj->Target, level,
+ xoffset, yoffset, 0, width, height, 1,
+ format, imageSize, data, true);
+}
void GLAPIENTRY
_mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset,
- GLint yoffset, GLint zoffset, GLsizei width,
- GLsizei height, GLsizei depth, GLenum format,
- GLsizei imageSize, const GLvoid *data)
+ GLint yoffset, GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imageSize, const GLvoid *data)
+{
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
+ if (!texObj)
+ return;
+
+ _mesa_compressed_texture_sub_image(ctx, 3, texObj, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, imageSize, data, false);
+}
+
+void GLAPIENTRY
+_mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset,
+ GLint yoffset, GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize,
+ const GLvoid *data)
{
- compressed_tex_sub_image(3, target, level, xoffset, yoffset, zoffset,
- width, height, depth, format, imageSize, data);
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+
+ texObj = _mesa_lookup_texture_err(ctx, texture,
+ "glCompressedTextureSubImage3D");
+
+ _mesa_compressed_texture_sub_image(ctx, 3, texObj, texObj->Target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, imageSize, data, true);
}
static mesa_format