summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/intel/intel_tex_image.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2011-01-10 10:01:12 -0800
committerEric Anholt <eric@anholt.net>2011-01-10 17:21:10 -0800
commit5b3eb7538cd9ceb967b6e9e765896183e7c2c4d4 (patch)
tree220862ba5058742e9330550c995c687737fd07bf /src/mesa/drivers/dri/intel/intel_tex_image.c
parentda0c0dbab060416452e7c96415abef91ec7d64f4 (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.c125
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)) {