diff options
-rw-r--r-- | src/mesa/state_tracker/st_cb_texture.c | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 62f149aa0fb..867d4daad68 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -388,6 +388,43 @@ guess_base_level_size(GLenum target, /** + * Try to determine whether we should allocate memory for a full texture + * mipmap. The problem is when we get a glTexImage(level=0) call, we + * can't immediately know if other mipmap levels are coming next. Here + * we try to guess whether to allocate memory for a mipmap or just the + * 0th level. + * + * If we guess incorrectly here we'll later reallocate the right amount of + * memory either in st_AllocTextureImageBuffer() or st_finalize_texture(). + * + * \param stObj the texture object we're going to allocate memory for. + * \param stImage describes the incoming image which we need to store. + */ +static boolean +allocate_full_mipmap(const struct st_texture_object *stObj, + const struct st_texture_image *stImage) +{ + if (stImage->base.Level > 0 || stObj->base.GenerateMipmap) + return TRUE; + + if (stImage->base._BaseFormat == GL_DEPTH_COMPONENT || + stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) + /* depth/stencil textures are seldom mipmapped */ + return FALSE; + + if (stObj->base.BaseLevel == 0 && stObj->base.MaxLevel == 0) + return FALSE; + + if (stObj->base.Sampler.MinFilter == GL_NEAREST || + stObj->base.Sampler.MinFilter == GL_LINEAR) + /* not a mipmap minification filter */ + return FALSE; + + return TRUE; +} + + +/** * Try to allocate a pipe_resource object for the given st_texture_object. * * We use the given st_texture_image as a clue to determine the size of the @@ -431,22 +468,15 @@ guess_and_alloc_texture(struct st_context *st, * to re-allocating a texture buffer with space for more (or fewer) * mipmap levels later. */ - if ((stObj->base.Sampler.MinFilter == GL_NEAREST || - stObj->base.Sampler.MinFilter == GL_LINEAR || - (stObj->base.BaseLevel == 0 && - stObj->base.MaxLevel == 0) || - stImage->base._BaseFormat == GL_DEPTH_COMPONENT || - stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) && - !stObj->base.GenerateMipmap && - stImage->base.Level == 0) { - /* only alloc space for a single mipmap level */ - lastLevel = 0; - } - else { + if (allocate_full_mipmap(stObj, stImage)) { /* alloc space for a full mipmap */ lastLevel = _mesa_get_tex_max_num_levels(stObj->base.Target, width, height, depth) - 1; } + else { + /* only alloc space for a single mipmap level */ + lastLevel = 0; + } /* Save the level=0 dimensions */ stObj->width0 = width; |