diff options
Diffstat (limited to 'src/mesa/main/teximage.c')
-rw-r--r-- | src/mesa/main/teximage.c | 239 |
1 files changed, 187 insertions, 52 deletions
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index fb775dddfe7..4d2b9ab2cc4 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -2330,7 +2330,8 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, 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; } @@ -4350,15 +4351,22 @@ out: */ 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: @@ -4378,7 +4386,52 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dims, } 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); @@ -4388,62 +4441,60 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dims, } 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; } @@ -4495,27 +4546,30 @@ _mesa_CompressedTexImage3D(GLenum target, GLint level, /** - * 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); { @@ -4541,33 +4595,114 @@ compressed_tex_sub_image(GLuint dims, GLenum target, GLint level, 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 |