diff options
author | Eric Anholt <eric@anholt.net> | 2011-01-10 10:01:12 -0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2011-01-10 17:21:10 -0800 |
commit | 5b3eb7538cd9ceb967b6e9e765896183e7c2c4d4 (patch) | |
tree | 220862ba5058742e9330550c995c687737fd07bf /src/mesa/drivers/dri/intel/intel_tex_image.c | |
parent | da0c0dbab060416452e7c96415abef91ec7d64f4 (diff) |
Revert "intel: Always allocate miptrees from level 0, not tObj->BaseLevel."
This reverts commit 7ce6517f3ac41bf770ab39aba4509d4f535ef663.
This reverts commit d60145d06d999c5c76000499e6fa9351e11d17fa.
I was wrong about which generations supported baselevel adjustment --
it's just gen4, nothing earlier. This meant that i915 would have
never used the mag filter when baselevel != 0. Not a severe bug, but
not an intentional regression. I think we can fix the performance
issue another way.
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, 90 insertions, 35 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 3b173bc257..450c3ceee6 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -45,12 +45,24 @@ logbase2(int n) return log2; } -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) + +/* 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) { + GLuint firstLevel; GLuint lastLevel; GLuint width = intelImage->base.Width; GLuint height = intelImage->base.Height; @@ -61,11 +73,28 @@ intel_miptree_create_for_teximage(struct intel_context *intel, DBG("%s\n", __FUNCTION__); if (intelImage->base.Border) - return NULL; + 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; + /* Figure out image dimensions at start level. */ - for (i = intelImage->level; i > 0; i--) { + for (i = intelImage->level; i > firstLevel; i--) { width <<= 1; if (height != 1) height <<= 1; @@ -80,29 +109,34 @@ intel_miptree_create_for_teximage(struct intel_context *intel, */ if ((intelObj->base.MinFilter == GL_NEAREST || intelObj->base.MinFilter == GL_LINEAR) && - intelImage->level == 0) { - lastLevel = 0; + intelImage->level == firstLevel && + (intel->gen < 4 || firstLevel == 0)) { + lastLevel = firstLevel; } else { - lastLevel = logbase2(MAX2(MAX2(width, height), depth)); + lastLevel = firstLevel + 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); - 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); + 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__); } @@ -310,23 +344,41 @@ intelTexImage(struct gl_context * ctx, texImage->Data = NULL; } - if (intelObj->mt && intel_miptree_match_image(intelObj->mt, - &intelImage->base)) { - intel_miptree_reference(&intelImage->mt, intelObj->mt); - } else { - intel_miptree_release(intel, &intelImage->mt); - intelImage->mt = intel_miptree_create_for_teximage(intel, intelObj, - intelImage, - pixels == NULL); - if (!intelImage->mt) { + 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)) { + + 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); + } - /* Speculatively set up the object with this miptree so that the - * later levels can just load into the miptree we just made. + /* 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. */ - if (!intelObj->mt && intelImage->mt) - intel_miptree_reference(&intelObj->mt, intelImage->mt); + intelImage->mt = intel_miptree_create(intel, target, + baseFormat, + internalFormat, + level, level, + width, height, depth, + texelBytes, + comp_byte, pixels == NULL); + } /* PBO fastpaths: @@ -345,7 +397,10 @@ intelTexImage(struct gl_context * ctx, * performance (in particular when intel_region_cow() is * required). */ - if (intelImage->mt->levels == 1) { + if (intelObj->mt == intelImage->mt && + intelObj->mt->first_level == level && + intelObj->mt->last_level == level) { + if (try_pbo_zcopy(intel, intelImage, unpack, internalFormat, width, height, format, type, pixels)) { |