diff options
Diffstat (limited to 'src/mesa')
| -rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_image.c | 143 | 
1 files changed, 66 insertions, 77 deletions
| diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 450c3ceee6..cd8c4c22e5 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -56,11 +56,11 @@ logbase2(int n)   * 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) +static 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; @@ -73,70 +73,71 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel,     DBG("%s\n", __FUNCTION__);     if (intelImage->base.Border) -      return; +      return NULL;     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; - +         intelImage->base.Depth == 1))) { +      /* For this combination, we're at some lower mipmap level and +       * some important dimension is 1.  We can't extrapolate up to a +       * likely base level width/height/depth for a full mipmap stack +       * from this info, so just allocate this one level. +       */ +      firstLevel = intelImage->level; +      lastLevel = intelImage->level; +   } else { +      /* 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 > firstLevel; i--) { -      width <<= 1; -      if (height != 1) -         height <<= 1; -      if (depth != 1) -         depth <<= 1; -   } +      /* Figure out image dimensions at start level. */ +      for (i = intelImage->level; i > firstLevel; i--) { +	 width <<= 1; +	 if (height != 1) +	    height <<= 1; +	 if (depth != 1) +	    depth <<= 1; +      } -   /* Guess a reasonable value for lastLevel.  This is probably going -    * to be wrong fairly often and might mean that we have to look at -    * resizable buffers, or require that buffers implement lazy -    * pagetable arrangements. -    */ -   if ((intelObj->base.MinFilter == GL_NEAREST || -        intelObj->base.MinFilter == GL_LINEAR) && -       intelImage->level == firstLevel && -       (intel->gen < 4 || firstLevel == 0)) { -      lastLevel = firstLevel; -   } -   else { -      lastLevel = firstLevel + logbase2(MAX2(MAX2(width, height), depth)); +      /* Guess a reasonable value for lastLevel.  This is probably going +       * to be wrong fairly often and might mean that we have to look at +       * resizable buffers, or require that buffers implement lazy +       * pagetable arrangements. +       */ +      if ((intelObj->base.MinFilter == GL_NEAREST || +	   intelObj->base.MinFilter == GL_LINEAR) && +	  intelImage->level == firstLevel && +	  (intel->gen < 4 || firstLevel == 0)) { +	 lastLevel = firstLevel; +      } else { +	 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); -   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, +			       firstLevel, +			       lastLevel, +			       width, +			       height, +			       depth, +			       texelBytes, +			       comp_byte, +			       expect_accelerated_upload);  } @@ -344,41 +345,29 @@ 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)) { - +      /* Use an existing miptree when possible */        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); -      } -        /* 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.         */ -      intelImage->mt = intel_miptree_create(intel, target, -					    baseFormat, -					    internalFormat, -					    level, level, -					    width, height, depth, -					    texelBytes, -					    comp_byte, pixels == NULL); +      intelImage->mt = intel_miptree_create_for_teximage(intel, intelObj, +							 intelImage, +							 pixels == NULL); +      /* Even if the object currently has a mipmap tree associated +       * with it, this one is a more likely candidate to represent the +       * whole object since our level didn't fit what was there +       * before, and any lower levels would fit into our miptree. +       */ +      if (intelImage->mt) +	 intel_miptree_reference(&intelObj->mt, intelImage->mt);     }     /* PBO fastpaths: | 
