i915: satisfy certain alignment restrictions for small
authorXiang, Haihao <haihao.xiang@intel.com>
Mon, 13 Aug 2007 03:43:37 +0000 (11:43 +0800)
committerXiang, Haihao <haihao.xiang@intel.com>
Mon, 13 Aug 2007 03:43:37 +0000 (11:43 +0800)
compressed texture

src/mesa/drivers/dri/i915/i915_texstate.c
src/mesa/drivers/dri/i915/intel_tex.c

index a19d4b65840a330e0bac03bdbe77017ebfafffd2..2b806cc36ef16773626f83af32cbd69979305f36 100644 (file)
@@ -60,6 +60,33 @@ static GLint step_offsets[6][2] = { {0,2},
 
 #define I915_TEX_UNIT_ENABLED(unit)            (1<<unit)
 
+static GLuint i915_compressed_alignment(GLint internal_fmt)
+{
+    GLuint alignment = 4;
+
+    switch (internal_fmt) {
+    case GL_COMPRESSED_RGB_FXT1_3DFX:
+    case GL_COMPRESSED_RGBA_FXT1_3DFX:
+        alignment = 8;
+        break;
+
+    default:
+        break;
+    }
+
+    return alignment;
+}
+
+static int align(int value, GLuint alignment)
+{
+    return (value + alignment - 1) & ~(alignment - 1);
+}
+
+static GLuint minify(GLuint d)
+{
+    return MAX2(1, d >> 1);
+}
+
 static void i915LayoutTextureImages( i915ContextPtr i915,
                                     struct gl_texture_object *tObj )
 {
@@ -161,8 +188,15 @@ static void i915LayoutTextureImages( i915ContextPtr i915,
       break;
    }
    default:
-      pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
-      pitch = (pitch + 3) & ~3;
+      if (baseImage->IsCompressed) {
+          GLuint alignment = i915_compressed_alignment(baseImage->InternalFormat);
+          
+          pitch = align(tObj->Image[0][firstLevel]->Width, alignment) * t->intel.texelBytes;
+      } else {
+          pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
+          pitch = (pitch + 3) & ~3;
+      }
+
       t->intel.base.dirty_images[0] = ~0;
 
       for ( total_height = i = 0 ; i < numLevels ; i++ ) {
@@ -343,8 +377,23 @@ static void i945LayoutTextureImages( i915ContextPtr i915,
       break;
    }
    default:
-      pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
-      pitch = (pitch + 3) & ~3;
+      if (baseImage->IsCompressed) {
+          GLuint alignment = i915_compressed_alignment(baseImage->InternalFormat);
+          
+          pitch = align(tObj->Image[0][firstLevel]->Width, alignment);
+          if (numLevels > 2) {
+              GLint width0 = align(minify(tObj->Image[0][firstLevel]->Width), alignment) +
+                  + align(minify(minify(tObj->Image[0][firstLevel]->Width)), alignment);
+
+              if (width0 > pitch)
+                  pitch = width0;
+          }
+          pitch = pitch * t->intel.texelBytes;
+      } else {
+          pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
+          pitch = (pitch + 3) & ~3;
+      }
+
       t->intel.base.dirty_images[0] = ~0;
       max_offset = 0;
 
index 5bd280652afb0939a6d690bc38f70522fb584d35..978945f26b5a4b57bc49a23a8f3177c5f86fc19c 100644 (file)
@@ -643,17 +643,19 @@ static void intelUploadTexImage( intelContextPtr intel,
       switch (image->InternalFormat) {
        case GL_COMPRESSED_RGB_FXT1_3DFX:
        case GL_COMPRESSED_RGBA_FXT1_3DFX:
+          row_len = ((image->Width + 7) & ~7) * 2;  
+          break;
        case GL_RGB_S3TC:
        case GL_RGB4_S3TC:
        case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
        case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-         row_len = (image->Width * 2 + 7) & ~7;
+         row_len = ((image->Width + 3) & ~3) * 2;  
          break;
        case GL_RGBA_S3TC:
        case GL_RGBA4_S3TC:
        case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
        case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-         row_len = (image->Width * 4 + 15) & ~15;
+         row_len = ((image->Width + 3) & ~3) * 4;  
          break;
        default:
          fprintf(stderr,"Internal Compressed format not supported %d\n", image->InternalFormat);