diff options
author | Ilia Mirkin <[email protected]> | 2015-11-08 04:46:38 -0500 |
---|---|---|
committer | Ilia Mirkin <[email protected]> | 2015-11-11 14:37:55 -0500 |
commit | 912babba7bf1abd3caa49f6372d581ae1afe7e84 (patch) | |
tree | e2a6a6a084d8d8638ca925694920ee7a0ed027d5 | |
parent | 80890eb0d322483fb13558afddc4feae5210f996 (diff) |
mesa/copyimage: allow width/height to not be multiples of block
For compressed textures, the image size is not necessarily a multiple of
the block size (e.g. the last mip levels). Section 18.3.2 (Copying
Between Images) of the OpenGL 4.5 Core Profile spec says:
An INVALID_VALUE error is generated if the dimensions of either
subregion exceeds the boundaries of the corresponding image
object, or if the image format is compressed and the dimensions of
the subregion fail to meet the alignment constraints of the
format.
and Section 8.7 (Compressed Texture Images) says:
An INVALID_OPERATION error is generated if any of the following
conditions occurs:
* width is not a multiple of four, and width + xoffset is not
equal to the value of TEXTURE_WIDTH.
* height is not a multiple of four, and height + yoffset is not
equal to the value of TEXTURE_HEIGHT.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92860
Signed-off-by: Ilia Mirkin <[email protected]>
Acked-by: Alex Deucher <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
Reviewed-by: Ian Romanick <[email protected]>
Cc: [email protected]
-rw-r--r-- | src/mesa/main/copyimage.c | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/src/mesa/main/copyimage.c b/src/mesa/main/copyimage.c index f02e842f34d..d571d221bce 100644 --- a/src/mesa/main/copyimage.c +++ b/src/mesa/main/copyimage.c @@ -62,6 +62,8 @@ prepare_target(struct gl_context *ctx, GLuint name, GLenum target, struct gl_renderbuffer **renderbuffer, mesa_format *format, GLenum *internalFormat, + GLuint *width, + GLuint *height, const char *dbg_prefix) { if (name == 0) { @@ -126,6 +128,8 @@ prepare_target(struct gl_context *ctx, GLuint name, GLenum target, *renderbuffer = rb; *format = rb->Format; *internalFormat = rb->InternalFormat; + *width = rb->Width; + *height = rb->Height; *tex_image = NULL; } else { struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, name); @@ -194,6 +198,8 @@ prepare_target(struct gl_context *ctx, GLuint name, GLenum target, *renderbuffer = NULL; *format = (*tex_image)->TexFormat; *internalFormat = (*tex_image)->InternalFormat; + *width = (*tex_image)->Width; + *height = (*tex_image)->Height; } return true; @@ -423,6 +429,7 @@ _mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, struct gl_renderbuffer *srcRenderbuffer, *dstRenderbuffer; mesa_format srcFormat, dstFormat; GLenum srcIntFormat, dstIntFormat; + GLuint src_w, src_h, dst_w, dst_h; GLuint src_bw, src_bh, dst_bw, dst_bh; int dstWidth, dstHeight, dstDepth; int i; @@ -445,17 +452,41 @@ _mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, if (!prepare_target(ctx, srcName, srcTarget, srcLevel, srcZ, srcDepth, &srcTexImage, &srcRenderbuffer, &srcFormat, - &srcIntFormat, "src")) + &srcIntFormat, &src_w, &src_h, "src")) return; if (!prepare_target(ctx, dstName, dstTarget, dstLevel, dstZ, srcDepth, &dstTexImage, &dstRenderbuffer, &dstFormat, - &dstIntFormat, "dst")) + &dstIntFormat, &dst_w, &dst_h, "dst")) return; _mesa_get_format_block_size(srcFormat, &src_bw, &src_bh); + + /* Section 18.3.2 (Copying Between Images) of the OpenGL 4.5 Core Profile + * spec says: + * + * An INVALID_VALUE error is generated if the dimensions of either + * subregion exceeds the boundaries of the corresponding image object, + * or if the image format is compressed and the dimensions of the + * subregion fail to meet the alignment constraints of the format. + * + * and Section 8.7 (Compressed Texture Images) says: + * + * An INVALID_OPERATION error is generated if any of the following + * conditions occurs: + * + * * width is not a multiple of four, and width + xoffset is not + * equal to the value of TEXTURE_WIDTH. + * * height is not a multiple of four, and height + yoffset is not + * equal to the value of TEXTURE_HEIGHT. + * + * so we take that to mean that you can copy the "last" block of a + * compressed texture image even if it's smaller than the minimum block + * dimensions. + */ if ((srcX % src_bw != 0) || (srcY % src_bh != 0) || - (srcWidth % src_bw != 0) || (srcHeight % src_bh != 0)) { + (srcWidth % src_bw != 0 && (srcX + srcWidth) != src_w) || + (srcHeight % src_bh != 0 && (srcY + srcHeight) != src_h)) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyImageSubData(unaligned src rectangle)"); return; |