From ccc5ce6f72c1ec86be4dfcef96c0b51fba0faa6d Mon Sep 17 00:00:00 2001 From: Laura Ekstrand Date: Tue, 24 Feb 2015 14:51:29 -0800 Subject: [PATCH] common: Correct PBO 2D_ARRAY handling. Changes PBO uploads and downloads to use a tall (height * depth) 2D texture for blitting. This fixes the bug where 2D_ARRAY, 3D, and CUBE_MAP_ARRAY textures are not properly uploaded and downloaded. Removes the option to use a 2D ARRAY texture for the PBO during upload and download. This option didn't work because the miptree couldn't be set up reliably. v2: Review from Jason Ekstrand and Neil Roberts: -Delete the depth parameter from create_texture_for_pbo -Abandon the option to create a 2D ARRAY texture in create_texture_for_pbo Reviewed-by: Ian Romanick Reviewed-by: Jason Ekstrand Cc: "10.4, 10.5" --- src/mesa/drivers/common/meta_tex_subimage.c | 26 ++++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/mesa/drivers/common/meta_tex_subimage.c b/src/mesa/drivers/common/meta_tex_subimage.c index 2d2b9d86b24..b659426243d 100644 --- a/src/mesa/drivers/common/meta_tex_subimage.c +++ b/src/mesa/drivers/common/meta_tex_subimage.c @@ -44,7 +44,7 @@ static struct gl_texture_image * create_texture_for_pbo(struct gl_context *ctx, bool create_pbo, - GLenum pbo_target, int width, int height, int depth, + GLenum pbo_target, int width, int height, GLenum format, GLenum type, const void *pixels, const struct gl_pixelstore_attrib *packing, GLuint *tmp_pbo, GLuint *tmp_tex) @@ -57,8 +57,7 @@ create_texture_for_pbo(struct gl_context *ctx, bool create_pbo, struct gl_texture_image *tex_image; bool read_only; - if ((packing->ImageHeight != 0 && packing->ImageHeight != height) || - packing->SwapBytes || + if (packing->SwapBytes || packing->LsbFirst || packing->Invert) return NULL; @@ -99,7 +98,6 @@ create_texture_for_pbo(struct gl_context *ctx, bool create_pbo, _mesa_GenTextures(1, tmp_tex); tex_obj = _mesa_lookup_texture(ctx, *tmp_tex); - tex_obj->Target = depth > 1 ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; _mesa_initialize_texture_object(ctx, tex_obj, *tmp_tex, GL_TEXTURE_2D); /* This must be set after _mesa_initialize_texture_object, not before. */ tex_obj->Immutable = GL_TRUE; @@ -109,7 +107,7 @@ create_texture_for_pbo(struct gl_context *ctx, bool create_pbo, internal_format = _mesa_get_format_base_format(pbo_format); tex_image = _mesa_get_tex_image(ctx, tex_obj, tex_obj->Target, 0); - _mesa_init_teximage_fields(ctx, tex_image, width, height, depth, + _mesa_init_teximage_fields(ctx, tex_image, width, height, 1, 0, internal_format, pbo_format); read_only = pbo_target == GL_PIXEL_UNPACK_BUFFER; @@ -169,9 +167,14 @@ _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. */ pbo_tex_image = create_texture_for_pbo(ctx, create_pbo, GL_PIXEL_UNPACK_BUFFER, - width, height, depth, + width, height * depth, format, type, pixels, packing, &pbo, &pbo_tex); if (!pbo_tex_image) @@ -225,7 +228,7 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims, _mesa_update_state(ctx); _mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer, - 0, 0, width, height, + 0, z * height, width, (z + 1) * height, xoffset, yoffset, xoffset + width, yoffset + height, GL_COLOR_BUFFER_BIT, GL_NEAREST); @@ -285,8 +288,13 @@ _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. */ pbo_tex_image = create_texture_for_pbo(ctx, false, GL_PIXEL_PACK_BUFFER, - width, height, depth, + width, height * depth, format, type, pixels, packing, &pbo, &pbo_tex); if (!pbo_tex_image) @@ -347,7 +355,7 @@ _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, 0, width, height, + 0, z * height, width, (z + 1) * height, GL_COLOR_BUFFER_BIT, GL_NEAREST); } -- 2.30.2