From a0f84396913d478c926626593514de1ab6ebb439 Mon Sep 17 00:00:00 2001 From: Yevhenii Kharchenko Date: Wed, 1 Jul 2020 17:36:18 +0300 Subject: [PATCH] st/mesa: fix corrupted texture levels, when adding more levels than expected MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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: --- src/mesa/state_tracker/st_cb_texture.c | 42 ++++++++++++++------------ 1 file changed, 23 insertions(+), 19 deletions(-) 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; + } } } -- 2.30.2