Merge branch 'mesa_7_7_branch'
[mesa.git] / src / mesa / drivers / dri / intel / intel_tex_validate.c
index 820683d42eb6d5e86922694e403b7953e5eaf25b..ed5c5d896b9c200eb8ebb1affbe3f2eceb773fbe 100644 (file)
@@ -2,7 +2,6 @@
 #include "main/macros.h"
 
 #include "intel_context.h"
-#include "intel_batchbuffer.h"
 #include "intel_mipmap_tree.h"
 #include "intel_tex.h"
 
@@ -14,7 +13,8 @@
  * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
  */
 static void
-intel_calculate_first_last_level(struct intel_texture_object *intelObj)
+intel_calculate_first_last_level(struct intel_context *intel,
+                                struct intel_texture_object *intelObj)
 {
    struct gl_texture_object *tObj = &intelObj->base;
    const struct gl_texture_image *const baseImage =
@@ -40,27 +40,27 @@ intel_calculate_first_last_level(struct intel_texture_object *intelObj)
          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
+        if (intel->gen == 2) {
+           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 {
+           /* Min/max LOD are taken into account in sampler state.  We don't
+            * want to re-layout textures just because clamping has been applied
+            * since it means a bunch of blitting around and probably no memory
+            * savings (since we have to keep the other levels around anyway).
+            */
+           firstLevel = tObj->BaseLevel;
+           lastLevel = MIN2(tObj->BaseLevel + baseImage->MaxLog2,
+                            tObj->MaxLevel);
+           /* need at least one level */
+           lastLevel = MAX2(firstLevel, lastLevel);
+        }
       }
       break;
    case GL_TEXTURE_RECTANGLE_NV:
@@ -135,9 +135,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_calculate_first_last_level(intel, intelObj);
+   firstImage = intel_texture_image(tObj->Image[0][intelObj->firstLevel]);
 
    /* Fallback case:
     */
@@ -165,11 +164,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.
@@ -189,7 +189,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
        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);
    }
 
@@ -199,6 +199,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
    if (!intelObj->mt) {
       intelObj->mt = intel_miptree_create(intel,
                                           intelObj->base.Target,
+                                          firstImage->base._BaseFormat,
                                           firstImage->base.InternalFormat,
                                           intelObj->firstLevel,
                                           intelObj->lastLevel,
@@ -206,7 +207,8 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
                                           firstImage->base.Height,
                                           firstImage->base.Depth,
                                           cpp,
-                                          comp_byte);
+                                          comp_byte,
+                                         GL_TRUE);
    }
 
    /* Pull in any images not in the object's tree:
@@ -218,8 +220,13 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
             intel_texture_image(intelObj->base.Image[face][i]);
 
          /* 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);
          }
       }
@@ -240,7 +247,7 @@ intel_tex_map_level_images(struct intel_context *intel,
       struct intel_texture_image *intelImage =
         intel_texture_image(intelObj->base.Image[face][level]);
 
-      if (intelImage->mt) {
+      if (intelImage && intelImage->mt) {
         intelImage->base.Data =
            intel_miptree_image_map(intel,
                                    intelImage->mt,
@@ -267,7 +274,7 @@ intel_tex_unmap_level_images(struct intel_context *intel,
       struct intel_texture_image *intelImage =
         intel_texture_image(intelObj->base.Image[face][level]);
 
-      if (intelImage->mt) {
+      if (intelImage && intelImage->mt) {
         intel_miptree_image_unmap(intel, intelImage->mt);
         intelImage->base.Data = NULL;
       }