Merge branch 'master' of git+ssh://brianp@git.freedesktop.org/git/mesa/mesa
[mesa.git] / src / mesa / drivers / dri / intel / intel_tex_layout.c
index 6b9e1de2ed3dc4a5ccfc421bc91a35004a4c0014..f35648021713b36f3b18b433b2336417c52645a4 100644 (file)
@@ -27,7 +27,7 @@
  /*
   * Authors:
   *   Keith Whitwell <keith@tungstengraphics.com>
-  *   Michel Dänzer <keith@tungstengraphics.com>
+  *   Michel Dänzer <michel@tungstengraphics.com>
   */
 
 #include "intel_mipmap_tree.h"
 #include "macros.h"
 
 
+static int align(int value, int alignment)
+{
+   return (value + alignment - 1) & ~(alignment - 1);
+}
+
 void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
 {
-   GLint align_h = 2;
+   GLint align_h = 2, align_w = 4;
    GLuint level;
    GLuint x = 0;
    GLuint y = 0;
    GLuint width = mt->width0;
    GLuint height = mt->height0;
 
-   mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
+   mt->pitch = mt->width0;
+
+   /* May need to adjust pitch to accomodate the placement of
+    * the 2nd mipmap.  This occurs when the alignment
+    * constraints of mipmap placement push the right edge of the
+    * 2nd mipmap out past the width of its parent.
+    */
+   if (mt->first_level != mt->last_level) {
+      GLuint mip1_width = align(minify(mt->width0), align_w)
+                       + minify(minify(mt->width0));
+
+      if (mip1_width > mt->width0)
+        mt->pitch = mip1_width;
+   }
+
+   /* Pitch must be a whole number of dwords, even though we
+    * express it in texels.
+    */
+   mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp;
    mt->total_height = 0;
 
    for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
@@ -56,7 +79,7 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
       if (mt->compressed)
         img_height = MAX2(1, height/4);
       else
-        img_height = MAX2(align_h, height);
+        img_height = align(height, align_h);
 
 
       /* Because the images are packed better, the final offset
@@ -67,13 +90,10 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
       /* Layout_below: step right after second mipmap.
        */
       if (level == mt->first_level + 1) {
-        x += mt->pitch / 2;
-        x = (x + 3) & ~ 3;
+        x += align(width, align_w);
       }
       else {
         y += img_height;
-        y += align_h - 1;
-        y &= ~(align_h - 1);
       }
 
       width  = minify(width);