summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorNicolai Hähnle <[email protected]>2016-06-06 23:15:10 +0200
committerNicolai Hähnle <[email protected]>2016-06-10 20:20:39 +0200
commit42624ea837e8f422f1cd04403af915bd7f218b8d (patch)
treefac2cdc59adebf7637fb2fefc46ed548899d5e84 /src/mesa
parenta1e69930e43f2876f662042bb94b76124dbe7dfc (diff)
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 <[email protected]> Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 22a58517fc7..3e504965fc0 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -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;