From: Yevhenii Kharchenko Date: Wed, 1 Jul 2020 14:36:18 +0000 (+0300) Subject: st/mesa: fix corrupted texture levels, when adding more levels than expected X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a0f84396913d478c926626593514de1ab6ebb439;p=mesa.git st/mesa: fix corrupted texture levels, when adding more levels than expected Some of existing texture levels can be corruted, after calling 'glTexImage' with param 'level' higher than max expected value 'floor(log2(max(width, height, depth)))'. To fix we prevent overwriting image buffer pointer in 'st_texture_object', if it was already allocated for multiple mip-levels storage. Fixes piglit test: 'arb_copy_image add-illegal-levels' Signed-off-by: Yevhenii Kharchenko Reviewed-by: Marek Olšák Part-of: --- diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index b0ea844c071..a2d7aa6a6d3 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -709,7 +709,6 @@ st_AllocTextureImageBuffer(struct gl_context *ctx, struct st_context *st = st_context(ctx); struct st_texture_image *stImage = st_texture_image(texImage); struct st_texture_object *stObj = st_texture_object(texImage->TexObject); - const GLuint level = texImage->Level; GLuint width = texImage->Width; GLuint height = texImage->Height; GLuint depth = texImage->Depth; @@ -721,29 +720,34 @@ st_AllocTextureImageBuffer(struct gl_context *ctx, stObj->needs_validation = true; compressed_tex_fallback_allocate(st, stImage); + const bool allowAllocateToStObj = !stObj->pt || + stObj->pt->last_level == 0 || + texImage->Level == 0; - /* Look if the parent texture object has space for this image */ - if (stObj->pt && - level <= stObj->pt->last_level && - st_texture_match_image(st, stObj->pt, texImage)) { - /* this image will fit in the existing texture object's memory */ - pipe_resource_reference(&stImage->pt, stObj->pt); - return GL_TRUE; - } + if (allowAllocateToStObj) { + /* Look if the parent texture object has space for this image */ + if (stObj->pt && + st_texture_match_image(st, stObj->pt, texImage)) { + /* this image will fit in the existing texture object's memory */ + pipe_resource_reference(&stImage->pt, stObj->pt); + assert(stImage->pt); + return GL_TRUE; + } - /* The parent texture object does not have space for this image */ + /* The parent texture object does not have space for this image */ - pipe_resource_reference(&stObj->pt, NULL); - st_texture_release_all_sampler_views(st, stObj); + pipe_resource_reference(&stObj->pt, NULL); + st_texture_release_all_sampler_views(st, stObj); - if (!guess_and_alloc_texture(st, stObj, stImage)) { - /* Probably out of memory. - * Try flushing any pending rendering, then retry. - */ - st_finish(st); if (!guess_and_alloc_texture(st, stObj, stImage)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); - return GL_FALSE; + /* Probably out of memory. + * Try flushing any pending rendering, then retry. + */ + st_finish(st); + if (!guess_and_alloc_texture(st, stObj, stImage)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + return GL_FALSE; + } } }