diff options
author | Eric Anholt <[email protected]> | 2011-01-05 17:02:08 -0800 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2011-01-05 18:23:54 -0800 |
commit | 7ce6517f3ac41bf770ab39aba4509d4f535ef663 (patch) | |
tree | 3563dc5da10a71f71981a0ceb5fdbd00b37a1f79 /src/mesa/drivers/dri/intel/intel_tex_image.c | |
parent | 01b70c06284f3a0ab2de61228b73c78ed00a1a14 (diff) |
intel: Always allocate miptrees from level 0, not tObj->BaseLevel.
BaseLevel/MaxLevel are mostly used for two things: clamping texture
access for FBO rendering, and limiting the used mipmap levels when
incrementally loading textures. By restricting our mipmap trees to
just the current BaseLevel/MaxLevel, we caused reallocation thrashing
in the common case, for a theoretical win if someone really did want
just levels 2..4 or whatever of their texture object.
Bug #30366
Diffstat (limited to 'src/mesa/drivers/dri/intel/intel_tex_image.c')
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_image.c | 125 |
1 files changed, 35 insertions, 90 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 918740a773a..e0d4ca762f5 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -44,24 +44,12 @@ logbase2(int n) return log2; } - -/* Otherwise, store it in memory if (Border != 0) or (any dimension == - * 1). - * - * Otherwise, if max_level >= level >= min_level, create tree with - * space for textures from min_level down to max_level. - * - * Otherwise, create tree with space for textures from (level - * 0)..(1x1). Consider pruning this tree at a validation if the - * saving is worth it. - */ -static void -guess_and_alloc_mipmap_tree(struct intel_context *intel, - struct intel_texture_object *intelObj, - struct intel_texture_image *intelImage, - GLboolean expect_accelerated_upload) +struct intel_mipmap_tree * +intel_miptree_create_for_teximage(struct intel_context *intel, + struct intel_texture_object *intelObj, + struct intel_texture_image *intelImage, + GLboolean expect_accelerated_upload) { - GLuint firstLevel; GLuint lastLevel; GLuint width = intelImage->base.Width; GLuint height = intelImage->base.Height; @@ -72,28 +60,11 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel, DBG("%s\n", __FUNCTION__); if (intelImage->base.Border) - return; - - if (intelImage->level > intelObj->base.BaseLevel && - (intelImage->base.Width == 1 || - (intelObj->base.Target != GL_TEXTURE_1D && - intelImage->base.Height == 1) || - (intelObj->base.Target == GL_TEXTURE_3D && - intelImage->base.Depth == 1))) - return; - - /* If this image disrespects BaseLevel, allocate from level zero. - * Usually BaseLevel == 0, so it's unlikely to happen. - */ - if (intelImage->level < intelObj->base.BaseLevel) - firstLevel = 0; - else - firstLevel = intelObj->base.BaseLevel; - + return NULL; /* Figure out image dimensions at start level. */ - for (i = intelImage->level; i > firstLevel; i--) { + for (i = intelImage->level; i > 0; i--) { width <<= 1; if (height != 1) height <<= 1; @@ -108,34 +79,29 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel, */ if ((intelObj->base.MinFilter == GL_NEAREST || intelObj->base.MinFilter == GL_LINEAR) && - intelImage->level == firstLevel && - (intel->gen < 4 || firstLevel == 0)) { - lastLevel = firstLevel; + intelImage->level == 0) { + lastLevel = 0; } else { - lastLevel = firstLevel + logbase2(MAX2(MAX2(width, height), depth)); + lastLevel = logbase2(MAX2(MAX2(width, height), depth)); } - assert(!intelObj->mt); if (_mesa_is_format_compressed(intelImage->base.TexFormat)) comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat); texelBytes = _mesa_get_format_bytes(intelImage->base.TexFormat); - intelObj->mt = intel_miptree_create(intel, - intelObj->base.Target, - intelImage->base._BaseFormat, - intelImage->base.InternalFormat, - firstLevel, - lastLevel, - width, - height, - depth, - texelBytes, - comp_byte, - expect_accelerated_upload); - - DBG("%s - success\n", __FUNCTION__); + return intel_miptree_create(intel, + intelObj->base.Target, + intelImage->base._BaseFormat, + intelImage->base.InternalFormat, + lastLevel + 1, + width, + height, + depth, + texelBytes, + comp_byte, + expect_accelerated_upload); } @@ -343,41 +309,23 @@ intelTexImage(struct gl_context * ctx, texImage->Data = NULL; } - if (!intelObj->mt) { - guess_and_alloc_mipmap_tree(intel, intelObj, intelImage, pixels == NULL); - if (!intelObj->mt) { - DBG("guess_and_alloc_mipmap_tree: failed\n"); - } - } - - assert(!intelImage->mt); - - if (intelObj->mt && - intel_miptree_match_image(intelObj->mt, &intelImage->base)) { - + if (intelObj->mt && intel_miptree_match_image(intelObj->mt, + &intelImage->base)) { intel_miptree_reference(&intelImage->mt, intelObj->mt); - assert(intelImage->mt); - } else if (intelImage->base.Border == 0) { - int comp_byte = 0; - GLuint texelBytes = _mesa_get_format_bytes(intelImage->base.TexFormat); - GLenum baseFormat = _mesa_get_format_base_format(intelImage->base.TexFormat); - if (_mesa_is_format_compressed(intelImage->base.TexFormat)) { - comp_byte = - intel_compressed_num_bytes(intelImage->base.TexFormat); + } else { + intel_miptree_release(intel, &intelImage->mt); + intelImage->mt = intel_miptree_create_for_teximage(intel, intelObj, + intelImage, + pixels == NULL); + if (!intelImage->mt) { + DBG("guess_and_alloc_mipmap_tree: failed\n"); } - /* Didn't fit in the object miptree, but it's suitable for inclusion in - * a miptree, so create one just for our level and store it in the image. - * It'll get moved into the object miptree at validate time. + /* Speculatively set up the object with this miptree so that the + * later levels can just load into the miptree we just made. */ - intelImage->mt = intel_miptree_create(intel, target, - baseFormat, - internalFormat, - level, level, - width, height, depth, - texelBytes, - comp_byte, pixels == NULL); - + if (!intelObj->mt && intelImage->mt) + intel_miptree_reference(&intelObj->mt, intelImage->mt); } /* PBO fastpaths: @@ -396,10 +344,7 @@ intelTexImage(struct gl_context * ctx, * performance (in particular when intel_region_cow() is * required). */ - if (intelObj->mt == intelImage->mt && - intelObj->mt->first_level == level && - intelObj->mt->last_level == level) { - + if (intelImage->mt->levels == 1) { if (try_pbo_zcopy(intel, intelImage, unpack, internalFormat, width, height, format, type, pixels)) { |