st/mesa: simplify st_generate_mipmap()

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.

v2: fix a comment typo, per Sinclair

Reviewed-by: Sinclair Yeh <syeh@vmware.com>
Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
This commit is contained in:
Brian Paul 2016-03-24 14:09:24 -06:00
parent 105fe52784
commit d8d029f22b

View file

@ -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;
const GLboolean genSave = texObj->GenerateMipmap;
/* 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);
/* Temporarily set GenerateMipmap to true so that allocate_full_mipmap()
* makes the right decision about full mipmap allocation.
*/
texObj->GenerateMipmap = GL_TRUE;
/* This will copy the old texture's base image into the new texture
* which we just allocated.
*/
st_finalize_texture(ctx, st->pipe, texObj);
_mesa_prepare_mipmap_levels(ctx, texObj, baseLevel, lastLevel);
/* 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);
}
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 latter.
*
* 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);
}
}