Revert "intel: Always allocate miptrees from level 0, not tObj->BaseLevel."
[mesa.git] / src / mesa / drivers / dri / intel / intel_tex_validate.c
index a284d5475f4bce9227fa5844954e8b46b2b88406..ab8aba31fe0d503a00de6c48df61a04032652330 100644 (file)
@@ -2,78 +2,27 @@
 #include "main/macros.h"
 
 #include "intel_context.h"
-#include "intel_batchbuffer.h"
 #include "intel_mipmap_tree.h"
 #include "intel_tex.h"
 
 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
 
 /**
- * Compute which mipmap levels that really need to be sent to the hardware.
- * This depends on the base image size, GL_TEXTURE_MIN_LOD,
- * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
+ * When validating, we only care about the texture images that could
+ * be seen, so for non-mipmapped modes we want to ignore everything
+ * but BaseLevel.
  */
 static void
-intel_calculate_first_last_level(struct intel_texture_object *intelObj)
+intel_update_max_level(struct intel_context *intel,
+                      struct intel_texture_object *intelObj)
 {
    struct gl_texture_object *tObj = &intelObj->base;
-   const struct gl_texture_image *const baseImage =
-      tObj->Image[0][tObj->BaseLevel];
 
-   /* These must be signed values.  MinLod and MaxLod can be negative numbers,
-    * and having firstLevel and lastLevel as signed prevents the need for
-    * extra sign checks.
-    */
-   int firstLevel;
-   int lastLevel;
-
-   /* Yes, this looks overly complicated, but it's all needed.
-    */
-   switch (tObj->Target) {
-   case GL_TEXTURE_1D:
-   case GL_TEXTURE_2D:
-   case GL_TEXTURE_3D:
-   case GL_TEXTURE_CUBE_MAP:
-      if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
-         /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
-          */
-         firstLevel = lastLevel = tObj->BaseLevel;
-      }
-      else {
-#ifdef I915
-         firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
-         firstLevel = MAX2(firstLevel, tObj->BaseLevel);
-         firstLevel = MIN2(firstLevel, tObj->BaseLevel + baseImage->MaxLog2);
-         lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
-         lastLevel = MAX2(lastLevel, tObj->BaseLevel);
-         lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
-         lastLevel = MIN2(lastLevel, tObj->MaxLevel);
-         lastLevel = MAX2(firstLevel, lastLevel);       /* need at least one level */
-#else
-        /* Currently not taking min/max lod into account here, those
-         * values are programmed as sampler state elsewhere and we
-         * upload the same mipmap levels regardless.  Not sure if
-         * this makes sense as it means it isn't possible for the app
-         * to use min/max lod to reduce texture memory pressure:
-         */
-        firstLevel = tObj->BaseLevel;
-        lastLevel = MIN2(tObj->BaseLevel + baseImage->MaxLog2,
-                         tObj->MaxLevel);
-        lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
-#endif
-      }
-      break;
-   case GL_TEXTURE_RECTANGLE_NV:
-   case GL_TEXTURE_4D_SGIS:
-      firstLevel = lastLevel = 0;
-      break;
-   default:
-      return;
+   if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
+      intelObj->_MaxLevel = tObj->BaseLevel;
+   } else {
+      intelObj->_MaxLevel = tObj->_MaxLevel;
    }
-
-   /* save these values */
-   intelObj->firstLevel = firstLevel;
-   intelObj->lastLevel = lastLevel;
 }
 
 /**
@@ -135,9 +84,8 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
 
    /* What levels must the tree include at a minimum?
     */
-   intel_calculate_first_last_level(intelObj);
-   firstImage =
-      intel_texture_image(intelObj->base.Image[0][intelObj->firstLevel]);
+   intel_update_max_level(intel, intelObj);
+   firstImage = intel_texture_image(tObj->Image[0][tObj->BaseLevel]);
 
    /* Fallback case:
     */
@@ -156,8 +104,8 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
     */
    if (firstImage->mt &&
        firstImage->mt != intelObj->mt &&
-       firstImage->mt->first_level <= intelObj->firstLevel &&
-       firstImage->mt->last_level >= intelObj->lastLevel) {
+       firstImage->mt->first_level <= tObj->BaseLevel &&
+       firstImage->mt->last_level >= intelObj->_MaxLevel) {
 
       if (intelObj->mt)
          intel_miptree_release(intel, &intelObj->mt);
@@ -165,11 +113,12 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
       intel_miptree_reference(&intelObj->mt, firstImage->mt);
    }
 
-   if (firstImage->base.IsCompressed) {
-      comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat->MesaFormat);
+   if (_mesa_is_format_compressed(firstImage->base.TexFormat)) {
+      comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat);
       cpp = comp_byte;
    }
-   else cpp = firstImage->base.TexFormat->TexelBytes;
+   else
+      cpp = _mesa_get_format_bytes(firstImage->base.TexFormat);
 
    /* Check tree can hold all active levels.  Check tree matches
     * target, imageFormat, etc.
@@ -183,13 +132,13 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
    if (intelObj->mt &&
        (intelObj->mt->target != intelObj->base.Target ||
        intelObj->mt->internal_format != firstImage->base.InternalFormat ||
-       intelObj->mt->first_level != intelObj->firstLevel ||
-       intelObj->mt->last_level != intelObj->lastLevel ||
+       intelObj->mt->first_level != tObj->BaseLevel ||
+       intelObj->mt->last_level != intelObj->_MaxLevel ||
        intelObj->mt->width0 != firstImage->base.Width ||
        intelObj->mt->height0 != firstImage->base.Height ||
        intelObj->mt->depth0 != firstImage->base.Depth ||
        intelObj->mt->cpp != cpp ||
-       intelObj->mt->compressed != firstImage->base.IsCompressed)) {
+       intelObj->mt->compressed != _mesa_is_format_compressed(firstImage->base.TexFormat))) {
       intel_miptree_release(intel, &intelObj->mt);
    }
 
@@ -201,8 +150,8 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
                                           intelObj->base.Target,
                                           firstImage->base._BaseFormat,
                                           firstImage->base.InternalFormat,
-                                          intelObj->firstLevel,
-                                          intelObj->lastLevel,
+                                          tObj->BaseLevel,
+                                          intelObj->_MaxLevel,
                                           firstImage->base.Width,
                                           firstImage->base.Height,
                                           firstImage->base.Depth,
@@ -215,13 +164,20 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
     */
    nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
    for (face = 0; face < nr_faces; face++) {
-      for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) {
+      for (i = tObj->BaseLevel; i <= intelObj->_MaxLevel; i++) {
          struct intel_texture_image *intelImage =
             intel_texture_image(intelObj->base.Image[face][i]);
-
-         /* Need to import images in main memory or held in other trees.
+        /* skip too small size mipmap */
+        if (intelImage == NULL)
+                break;
+        /* Need to import images in main memory or held in other trees.
+         * If it's a render target, then its data isn't needed to be in
+         * the object tree (otherwise we'd be FBO incomplete), and we need
+         * to keep track of the image's MT as needing to be pulled in still,
+         * or we'll lose the rendering that's done to it.
           */
-         if (intelObj->mt != intelImage->mt) {
+         if (intelObj->mt != intelImage->mt &&
+            !intelImage->used_as_render_target) {
             copy_image_data_to_tree(intel, intelObj, intelImage);
          }
       }
@@ -284,7 +240,7 @@ intel_tex_map_images(struct intel_context *intel,
 
    DBG("%s\n", __FUNCTION__);
 
-   for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++)
+   for (i = intelObj->base.BaseLevel; i <= intelObj->_MaxLevel; i++)
       intel_tex_map_level_images(intel, intelObj, i);
 }
 
@@ -294,6 +250,6 @@ intel_tex_unmap_images(struct intel_context *intel,
 {
    int i;
 
-   for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++)
+   for (i = intelObj->base.BaseLevel; i <= intelObj->_MaxLevel; i++)
       intel_tex_unmap_level_images(intel, intelObj, i);
 }