Am 26.03.2016 um 18:21 schrieb Brian Paul: > The whole st_generate_mipmap() function was overly complicated. Now > we just call the new _mesa_prepare_mipmap_levels() function to prepare > the texture mipmap memory, then call the generate function which fills > in the texture images. > > This fixes a failed assertion in llvmpipe/softpipe which is hit with the > new piglit generatemipmap-base-change test. Also fixes some device errors > (format mismatches) with the VMware svga driver. > --- > src/mesa/state_tracker/st_gen_mipmap.c | 102 > ++++++++------------------------- > 1 file changed, 24 insertions(+), 78 deletions(-) > > diff --git a/src/mesa/state_tracker/st_gen_mipmap.c > b/src/mesa/state_tracker/st_gen_mipmap.c > index c4b3492..d854e20 100644 > --- a/src/mesa/state_tracker/st_gen_mipmap.c > +++ b/src/mesa/state_tracker/st_gen_mipmap.c > @@ -82,7 +82,6 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target, > const uint baseLevel = texObj->BaseLevel; > enum pipe_format format; > uint lastLevel, first_layer, last_layer; > - uint dstLevel; > > if (!pt) > return; > @@ -103,42 +102,33 @@ st_generate_mipmap(struct gl_context *ctx, GLenum > target, > stObj->lastLevel = lastLevel; > > if (!texObj->Immutable) { > - if (pt->last_level < lastLevel) { > - /* The current gallium texture doesn't have space for all the > - * mipmap levels we need to generate. So allocate a new texture. > - */ > - struct pipe_resource *oldTex = stObj->pt; > - > - /* create new texture with space for more levels */ > - stObj->pt = st_texture_create(st, > - oldTex->target, > - oldTex->format, > - lastLevel, > - oldTex->width0, > - oldTex->height0, > - oldTex->depth0, > - oldTex->array_size, > - 0, > - oldTex->bind); > - > - /* This will copy the old texture's base image into the new texture > - * which we just allocated. > - */ > - st_finalize_texture(ctx, st->pipe, texObj); > - > - /* release the old tex (will likely be freed too) */ > - pipe_resource_reference(&oldTex, NULL); > - st_texture_release_all_sampler_views(st, stObj); > - } > - else { > - /* Make sure that the base texture image data is present in the > - * texture buffer. > - */ > - st_finalize_texture(ctx, st->pipe, texObj); > - } > + const GLboolean genSave = texObj->GenerateMipmap; > + > + /* Temporarily set GenerateMipmap to true so that > allocate_full_mipmap() > + * makes the right decision about full mipmap allocation. > + */ > + texObj->GenerateMipmap = GL_TRUE; > + > + _mesa_prepare_mipmap_levels(ctx, texObj, baseLevel, lastLevel); > + > + texObj->GenerateMipmap = genSave; > + > + /* At this point, memory for all the texture levels has been > + * allocated. However, the base level image may be in one resource > + * while the subsequent/smaller levels may be in another resource. > + * Finalizing the texture will copy the base images from the former > + * resource to the later. > + * > + * After this, we'll have all mipmap levels in one resource. > + */ > + st_finalize_texture(ctx, st->pipe, texObj); > } > > pt = stObj->pt; > + if (!pt) { > + _mesa_error(ctx, GL_OUT_OF_MEMORY, "mipmap generation"); > + return; > + } > > assert(pt->last_level >= lastLevel); > > @@ -169,48 +159,4 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target, > _mesa_generate_mipmap(ctx, target, texObj); > } > } > - > - /* Fill in the Mesa gl_texture_image fields */ > - for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { > - const uint srcLevel = dstLevel - 1; > - const struct gl_texture_image *srcImage > - = _mesa_get_tex_image(ctx, texObj, target, srcLevel); > - struct gl_texture_image *dstImage; > - struct st_texture_image *stImage; > - uint border = srcImage->Border; > - uint dstWidth, dstHeight, dstDepth; > - > - dstWidth = u_minify(pt->width0, dstLevel); > - if (texObj->Target == GL_TEXTURE_1D_ARRAY) { > - dstHeight = pt->array_size; > - } > - else { > - dstHeight = u_minify(pt->height0, dstLevel); > - } > - if (texObj->Target == GL_TEXTURE_2D_ARRAY || > - texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) { > - dstDepth = pt->array_size; > - } > - else { > - dstDepth = u_minify(pt->depth0, dstLevel); > - } > - > - dstImage = _mesa_get_tex_image(ctx, texObj, target, dstLevel); > - if (!dstImage) { > - _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); > - return; > - } > - > - /* Free old image data */ > - ctx->Driver.FreeTextureImageBuffer(ctx, dstImage); > - > - /* initialize new image */ > - _mesa_init_teximage_fields(ctx, dstImage, dstWidth, dstHeight, > - dstDepth, border, srcImage->InternalFormat, > - srcImage->TexFormat); > - > - stImage = st_texture_image(dstImage); > - > - pipe_resource_reference(&stImage->pt, pt); > - } > } >
This looks good to me. For the series: Reviewed-by: Roland Scheidegger <srol...@vmware.com> _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev