Merge branch 'lp-offset-twoside'
[mesa.git] / src / mesa / drivers / dri / intel / intel_tex_validate.c
index d260a721d9a1d2d47a7d1118794559be09205c99..ed5c5d896b9c200eb8ebb1affbe3f2eceb773fbe 100644 (file)
@@ -1,8 +1,7 @@
-#include "mtypes.h"
-#include "macros.h"
+#include "main/mtypes.h"
+#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,26 +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);
-         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:
@@ -124,22 +125,18 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
    struct intel_texture_object *intelObj = intel_texture_object(tObj);
    int comp_byte = 0;
    int cpp;
-
    GLuint face, i;
    GLuint nr_faces = 0;
    struct intel_texture_image *firstImage;
 
-   GLboolean need_flush = GL_FALSE;
-
    /* We know/require this is true by now: 
     */
    assert(intelObj->base._Complete);
 
    /* 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:
     */
@@ -167,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.
@@ -191,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);
    }
 
@@ -201,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,
@@ -208,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:
@@ -220,77 +220,85 @@ 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);
-           need_flush = GL_TRUE;
          }
       }
    }
 
-#ifdef I915
-   /* XXX: what is this flush about?
-    * On 965, it causes a batch flush in the middle of the state relocation
-    * emits, which means that the eventual rendering doesn't have all of the
-    * required relocations in place.
-    */
-   if (need_flush)
-      intel_batchbuffer_flush(intel->batch);
-#endif
-
    return GL_TRUE;
 }
 
+void
+intel_tex_map_level_images(struct intel_context *intel,
+                          struct intel_texture_object *intelObj,
+                          int level)
+{
+   GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
+   GLuint face;
 
+   for (face = 0; face < nr_faces; face++) {
+      struct intel_texture_image *intelImage =
+        intel_texture_image(intelObj->base.Image[face][level]);
+
+      if (intelImage && intelImage->mt) {
+        intelImage->base.Data =
+           intel_miptree_image_map(intel,
+                                   intelImage->mt,
+                                   intelImage->face,
+                                   intelImage->level,
+                                   &intelImage->base.RowStride,
+                                   intelImage->base.ImageOffsets);
+        /* convert stride to texels, not bytes */
+        intelImage->base.RowStride /= intelImage->mt->cpp;
+        /* intelImage->base.ImageStride /= intelImage->mt->cpp; */
+      }
+   }
+}
 
 void
-intel_tex_map_images(struct intel_context *intel,
-                     struct intel_texture_object *intelObj)
+intel_tex_unmap_level_images(struct intel_context *intel,
+                            struct intel_texture_object *intelObj,
+                            int level)
 {
    GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
-   GLuint face, i;
-
-   DBG("%s\n", __FUNCTION__);
+   GLuint face;
 
    for (face = 0; face < nr_faces; face++) {
-      for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) {
-         struct intel_texture_image *intelImage =
-            intel_texture_image(intelObj->base.Image[face][i]);
+      struct intel_texture_image *intelImage =
+        intel_texture_image(intelObj->base.Image[face][level]);
 
-         if (intelImage->mt) {
-            intelImage->base.Data =
-               intel_miptree_image_map(intel,
-                                       intelImage->mt,
-                                       intelImage->face,
-                                       intelImage->level,
-                                       &intelImage->base.RowStride,
-                                       intelImage->base.ImageOffsets);
-            /* convert stride to texels, not bytes */
-            intelImage->base.RowStride /= intelImage->mt->cpp;
-/*             intelImage->base.ImageStride /= intelImage->mt->cpp; */
-         }
+      if (intelImage && intelImage->mt) {
+        intel_miptree_image_unmap(intel, intelImage->mt);
+        intelImage->base.Data = NULL;
       }
    }
 }
 
+void
+intel_tex_map_images(struct intel_context *intel,
+                     struct intel_texture_object *intelObj)
+{
+   int i;
 
+   DBG("%s\n", __FUNCTION__);
+
+   for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++)
+      intel_tex_map_level_images(intel, intelObj, i);
+}
 
 void
 intel_tex_unmap_images(struct intel_context *intel,
                        struct intel_texture_object *intelObj)
 {
-   GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
-   GLuint face, i;
+   int i;
 
-   for (face = 0; face < nr_faces; face++) {
-      for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) {
-         struct intel_texture_image *intelImage =
-            intel_texture_image(intelObj->base.Image[face][i]);
-
-         if (intelImage->mt) {
-            intel_miptree_image_unmap(intel, intelImage->mt);
-            intelImage->base.Data = NULL;
-         }
-      }
-   }
+   for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++)
+      intel_tex_unmap_level_images(intel, intelObj, i);
 }