st/mesa: use base level size as "guess" when available
When an applications specifies mip levels _before_ setting a mipmap texture filter, we will initially guess a single texture level. When the second level image is created, we try to allocate the full texture -- however, we get the base level size guess wrong if that size is odd. This leads to yet another re-allocation of the texture later during st_finalize_texture. Even worse, this re-allocation breaks a (reasonable) assumption made by st_generate_mipmaps, because the re-allocation in the finalization call will again allocate a single-level pipe texture (based on the non-mipmap texture filter!). As a result, mipmap generation fails in interesting ways. All of this can be avoided by just using the fact that we already know the size of the base level. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=95529 Cc: 12.0 <mesa-stable@lists.freedesktop.org> Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
@@ -456,21 +456,42 @@ guess_and_alloc_texture(struct st_context *st,
|
||||
struct st_texture_object *stObj,
|
||||
const struct st_texture_image *stImage)
|
||||
{
|
||||
const struct gl_texture_image *firstImage;
|
||||
GLuint lastLevel, width, height, depth;
|
||||
GLuint bindings;
|
||||
GLuint ptWidth, ptHeight, ptDepth, ptLayers;
|
||||
enum pipe_format fmt;
|
||||
bool guessed_box = false;
|
||||
|
||||
DBG("%s\n", __func__);
|
||||
|
||||
assert(!stObj->pt);
|
||||
|
||||
if (!guess_base_level_size(stObj->base.Target,
|
||||
stImage->base.Width2,
|
||||
stImage->base.Height2,
|
||||
stImage->base.Depth2,
|
||||
stImage->base.Level,
|
||||
&width, &height, &depth)) {
|
||||
/* If a base level image with compatible size exists, use that as our guess.
|
||||
*/
|
||||
firstImage = _mesa_base_tex_image(&stObj->base);
|
||||
if (firstImage &&
|
||||
guess_base_level_size(stObj->base.Target,
|
||||
firstImage->Width2,
|
||||
firstImage->Height2,
|
||||
firstImage->Depth2,
|
||||
firstImage->Level,
|
||||
&width, &height, &depth)) {
|
||||
if (stImage->base.Width2 == u_minify(width, stImage->base.Level) &&
|
||||
stImage->base.Height2 == u_minify(height, stImage->base.Level) &&
|
||||
stImage->base.Depth2 == u_minify(depth, stImage->base.Level))
|
||||
guessed_box = true;
|
||||
}
|
||||
|
||||
if (!guessed_box)
|
||||
guessed_box = guess_base_level_size(stObj->base.Target,
|
||||
stImage->base.Width2,
|
||||
stImage->base.Height2,
|
||||
stImage->base.Depth2,
|
||||
stImage->base.Level,
|
||||
&width, &height, &depth);
|
||||
|
||||
if (!guessed_box) {
|
||||
/* we can't determine the image size at level=0 */
|
||||
/* this is not an out of memory error */
|
||||
return GL_TRUE;
|
||||
|
Reference in New Issue
Block a user