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:
parent
105fe52784
commit
d8d029f22b
1 changed files with 21 additions and 75 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue