From a08bff1e98b8e630f8bdf341af1491cd99e7d104 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Thu, 26 Feb 2015 12:53:50 +0000 Subject: [PATCH] meta: Allow GL_UN/PACK_IMAGE_HEIGHT in _mesa_meta_pbo_Get/TexSubImage Now that a layered source PBO is interpreted as a single tall 2D image it's quite easy to accept the image height packing option by just creating an image that is tall enough to include the image padding. I'm not sure whether the image height property should affect 1D_ARRAY textures. My intuition and interpretation of the GL spec (which is a bit vague) would be that it shouldn't. However the software fallback path in Mesa uses the property for packing but not for unpacking. The binary NVidia driver uses it for both. This patch doesn't use it for either case so it is different from the software fallback. There is some discussion about this here: http://lists.freedesktop.org/archives/mesa-dev/2015-February/077925.html This is tested by the texsubimage Piglit test with the array and pbo arguments. Previously this test was skipping this code path because it always sets the image height. I've also tested it by modifying the getteximage-targets test. It wasn't using this code path before because it was using the default texture object so this code couldn't successfully create a frame buffer. I also modified it to add some image padding with the image height in the PBO. Reviewed-by: Jason Ekstrand Cc: "10.5" --- src/mesa/drivers/common/meta_tex_subimage.c | 32 ++++++++++++++++++----------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/mesa/drivers/common/meta_tex_subimage.c b/src/mesa/drivers/common/meta_tex_subimage.c index 1fef79db7b8..f360d649d16 100644 --- a/src/mesa/drivers/common/meta_tex_subimage.c +++ b/src/mesa/drivers/common/meta_tex_subimage.c @@ -144,6 +144,7 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims, const struct gl_pixelstore_attrib *packing) { GLuint pbo = 0, pbo_tex = 0, fbos[2] = { 0, 0 }; + int full_height, image_height; struct gl_texture_image *pbo_tex_image; GLenum status; bool success = false; @@ -177,14 +178,16 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims, return true; } - /* Only accept tightly packed pixels from the user. */ - if (packing->ImageHeight != 0 && packing->ImageHeight != height) - return false; + /* For arrays, use a tall (height * depth) 2D texture but taking into + * account the inter-image padding specified with the image height packing + * property. + */ + image_height = packing->ImageHeight == 0 ? height : packing->ImageHeight; + full_height = image_height * (depth - 1) + height; - /* For arrays, use a tall (height * depth) 2D texture. */ pbo_tex_image = create_texture_for_pbo(ctx, create_pbo, GL_PIXEL_UNPACK_BUFFER, - width, height * depth, + width, full_height, format, type, pixels, packing, &pbo, &pbo_tex); if (!pbo_tex_image) @@ -236,7 +239,8 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims, _mesa_update_state(ctx); _mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, - 0, z * height, width, (z + 1) * height, + 0, z * image_height, + width, z * image_height + height, xoffset, yoffset, xoffset + width, yoffset + height, GL_COLOR_BUFFER_BIT, GL_NEAREST); @@ -263,6 +267,7 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims, const struct gl_pixelstore_attrib *packing) { GLuint pbo = 0, pbo_tex = 0, fbos[2] = { 0, 0 }; + int full_height, image_height; struct gl_texture_image *pbo_tex_image; GLenum status; bool success = false; @@ -296,13 +301,15 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims, return true; } - /* Only accept tightly packed pixels from the user. */ - if (packing->ImageHeight != 0 && packing->ImageHeight != height) - return false; + /* For arrays, use a tall (height * depth) 2D texture but taking into + * account the inter-image padding specified with the image height packing + * property. + */ + image_height = packing->ImageHeight == 0 ? height : packing->ImageHeight; + full_height = image_height * (depth - 1) + height; - /* For arrays, use a tall (height * depth) 2D texture. */ pbo_tex_image = create_texture_for_pbo(ctx, false, GL_PIXEL_PACK_BUFFER, - width, height * depth, + width, full_height * depth, format, type, pixels, packing, &pbo, &pbo_tex); if (!pbo_tex_image) @@ -361,7 +368,8 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims, _mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, xoffset, yoffset, xoffset + width, yoffset + height, - 0, z * height, width, (z + 1) * height, + 0, z * image_height, + width, z * image_height + height, GL_COLOR_BUFFER_BIT, GL_NEAREST); } -- 2.11.0