i965/i915tex: applying right alignment to compressed texture,
authorXiang, Haihao <haihao.xiang@intel.com>
Fri, 10 Aug 2007 08:23:14 +0000 (16:23 +0800)
committerXiang, Haihao <haihao.xiang@intel.com>
Fri, 10 Aug 2007 08:23:14 +0000 (16:23 +0800)
which make small textures(4x4,2x2,1x1) work well.

src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c
src/mesa/drivers/dri/i965/intel_mipmap_tree.c
src/mesa/drivers/dri/intel/intel_tex_layout.c
src/mesa/drivers/dri/intel/intel_tex_layout.h

index 843a78eb82b44d78753a88b3210715d835a1aeeb..fc38a28290d5237ac8ec1f64bba75804d413f2e2 100644 (file)
@@ -325,6 +325,7 @@ intel_miptree_image_data(struct intel_context *intel,
    }
 }
 
+extern GLuint intel_compressed_alignment(GLenum);
 /* Copy mipmap image between trees
  */
 void
@@ -342,8 +343,12 @@ intel_miptree_image_copy(struct intel_context *intel,
    const GLuint *src_depth_offset = intel_miptree_depth_offsets(src, level);
    GLuint i;
 
-   if (dst->compressed)
-      height /= 4;
+   if (dst->compressed) {
+       GLuint alignment = intel_compressed_alignment(dst->internal_format);
+       height = (height + 3) / 4;
+       width = ((width + alignment - 1) & ~(alignment - 1));
+   }
+
    for (i = 0; i < depth; i++) {
       intel_region_copy(intel->intelScreen,
                         dst->region, dst_offset + dst_depth_offset[i],
index d7b1946ce3424de2ae109628b541e8b41a956a1b..f24f234682296e0dcccd9b7e7a23277ff4cac16e 100644 (file)
@@ -211,7 +211,7 @@ GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt,
 
 
 
-
+extern GLuint intel_compressed_alignment(GLenum);
 /* Upload data for a particular image.
  */
 GLboolean intel_miptree_image_data(struct intel_context *intel, 
@@ -226,6 +226,16 @@ GLboolean intel_miptree_image_data(struct intel_context *intel,
    GLuint dst_offset = intel_miptree_image_offset(dst, face, level);
    const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level);
    GLuint i;
+   GLuint width, height, alignment;
+
+   width = dst->level[level].width;
+   height = dst->level[level].height;
+
+   if (dst->compressed) {
+       alignment = intel_compressed_alignment(dst->internal_format);
+       width = ((width + alignment - 1) & ~(alignment - 1));
+       height = (height + 3) / 4;
+   }
 
    DBG("%s\n", __FUNCTION__);
    for (i = 0; i < depth; i++) {
@@ -237,8 +247,8 @@ GLboolean intel_miptree_image_data(struct intel_context *intel,
                             src,
                             src_row_pitch,
                             0, 0,      /* source x,y */
-                            dst->level[level].width,
-                            dst->level[level].height))
+                            width,
+                            height))
         return GL_FALSE;
       src += src_image_pitch;
    }
index fcb5cc390682587c36db93ff630d339b71269e30..fdecd3e186847be7a6c747da5b29484ac92eb4d8 100644 (file)
@@ -40,6 +40,23 @@ static int align(int value, int alignment)
    return (value + alignment - 1) & ~(alignment - 1);
 }
 
+GLuint intel_compressed_alignment(GLenum internalFormat)
+{
+    GLuint alignment = 4;
+
+    switch (internalFormat) {
+    case GL_COMPRESSED_RGB_FXT1_3DFX:
+    case GL_COMPRESSED_RGBA_FXT1_3DFX:
+        alignment = 8;
+        break;
+
+    default:
+        break;
+    }
+
+    return alignment;
+}
+
 void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
 {
    GLint align_h = 2, align_w = 4;
@@ -51,17 +68,30 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
 
    mt->pitch = mt->width0;
 
+   if (mt->compressed) {
+       align_w = intel_compressed_alignment(mt->internal_format);
+       mt->pitch = align(mt->width0, align_w);
+   }
+
    /* 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));
+       GLuint mip1_width;
+
+       if (mt->compressed) {
+           mip1_width = align(minify(mt->width0), align_w)
+               + align(minify(minify(mt->width0)), align_w);
+       } else {
+           mip1_width = align(minify(mt->width0), align_w)
+               + minify(minify(mt->width0));
+       }
 
-      if (mip1_width > mt->width0)
-        mt->pitch = mip1_width;
+       if (mip1_width > mt->pitch) {
+           mt->pitch = mip1_width;
+       }
    }
 
    /* Pitch must be a whole number of dwords, even though we
index 1e37f8f525faa6da98e7dc138d1a4ca6ded5f6bd..99d41c3629e4444ae5246b62db8de5c7ca3b8222 100644 (file)
@@ -39,3 +39,4 @@ static GLuint minify( GLuint d )
 }
 
 extern void i945_miptree_layout_2d( struct intel_mipmap_tree *mt );
+extern GLuint intel_compressed_alignment(GLenum);