Fix up texture compression at least Get and TexImage, not too sure about
authorDave Airlie <airliedfreedesktop.org>
Fri, 10 Nov 2006 00:32:35 +0000 (00:32 +0000)
committerDave Airlie <airliedfreedesktop.org>
Fri, 10 Nov 2006 00:32:35 +0000 (00:32 +0000)
how to fix SubTexImage with compressed textures

src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c
src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h
src/mesa/drivers/dri/i915tex/intel_tex.c
src/mesa/drivers/dri/i915tex/intel_tex.h
src/mesa/drivers/dri/i915tex/intel_tex_format.c
src/mesa/drivers/dri/i915tex/intel_tex_image.c
src/mesa/drivers/dri/i915tex/intel_tex_validate.c

index 2ebe3ae14e1b38d8972861445c4711756f91f7f4..2b1077aee0dc355ce5d777652d5cad20afd38bec 100644 (file)
@@ -56,7 +56,7 @@ intel_miptree_create(struct intel_context *intel,
                      GLuint last_level,
                      GLuint width0,
                      GLuint height0,
-                     GLuint depth0, GLuint cpp, GLboolean compressed)
+                     GLuint depth0, GLuint cpp, GLuint compress_byte)
 {
    GLboolean ok;
    struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
@@ -72,8 +72,8 @@ intel_miptree_create(struct intel_context *intel,
    mt->width0 = width0;
    mt->height0 = height0;
    mt->depth0 = depth0;
-   mt->cpp = compressed ? 2 : cpp;
-   mt->compressed = compressed;
+   mt->cpp = compress_byte ? compress_byte : cpp;
+   mt->compressed = compress_byte ? 1 : 0;
    mt->refcount = 1; 
 
    switch (intel->intelScreen->deviceID) {
@@ -302,11 +302,15 @@ 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 height = 0;
 
    DBG("%s\n", __FUNCTION__);
    for (i = 0; i < depth; i++) {
+      height = dst->level[level].height;
+      if(dst->compressed)
+        height /= 4;
       intel_region_data(intel->intelScreen, dst->region, dst_offset + dst_depth_offset[i], 0, 0, src, src_row_pitch, 0, 0,   /* source x,y */
-                        dst->level[level].width, dst->level[level].height);
+                        dst->level[level].width, height);
 
       src += src_image_pitch;
    }
@@ -329,6 +333,8 @@ 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;
    for (i = 0; i < depth; i++) {
       intel_region_copy(intel->intelScreen,
                         dst->region, dst_offset + dst_depth_offset[i],
index e6dd5bb60088a8fb3920cbe1f5fcde604397457b..ecdb7be244f3b779987527819b9dc4218c385596 100644 (file)
@@ -121,7 +121,7 @@ struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel,
                                                GLuint height0,
                                                GLuint depth0,
                                                GLuint cpp,
-                                               GLboolean compressed);
+                                               GLuint compress_byte);
 
 void intel_miptree_reference(struct intel_mipmap_tree **dst,
                              struct intel_mipmap_tree *src);
index 8046c29d950c30def59ae9d89e632324a5d1b38d..b08dee43bc1f7d356eea80f1c5e62919026e919d 100644 (file)
@@ -171,6 +171,11 @@ intelInitTextureFuncs(struct dd_function_table *functions)
    functions->CopyTexSubImage1D = intelCopyTexSubImage1D;
    functions->CopyTexSubImage2D = intelCopyTexSubImage2D;
    functions->GetTexImage = intelGetTexImage;
+
+   /* compressed texture functions */
+   functions->CompressedTexImage2D = intelCompressedTexImage2D;
+   functions->GetCompressedTexImage = intelGetCompressedTexImage;
+
    functions->NewTextureObject = intelNewTextureObject;
    functions->NewTextureImage = intelNewTextureImage;
    functions->DeleteTexture = intelDeleteTextureObject;
index 2f3d4ec2d11f5be38e8420be14bd00abf8d6ed4f..6e9938fe534491aca7ed8414716d6b7ec3d40089 100644 (file)
@@ -123,6 +123,18 @@ void intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
                       struct gl_texture_object *texObj,
                       struct gl_texture_image *texImage);
 
+void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
+                               GLint internalFormat,
+                               GLint width, GLint height, GLint border,
+                               GLsizei imageSize, const GLvoid *data,
+                               struct gl_texture_object *texObj,
+                               struct gl_texture_image *texImage );
+
+void intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
+                               GLvoid *pixels,
+                               const struct gl_texture_object *texObj,
+                               const struct gl_texture_image *texImage);
+
 GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit);
 
 void intel_tex_map_images(struct intel_context *intel,
@@ -131,4 +143,6 @@ void intel_tex_map_images(struct intel_context *intel,
 void intel_tex_unmap_images(struct intel_context *intel,
                             struct intel_texture_object *intelObj);
 
+int intel_compressed_num_bytes(GLuint mesaFormat);
+
 #endif
index 33281295dc26083b2af485692274a12534fe055b..6e058dff69f8088ba15a31b72c291aafb9c7dc25 100644 (file)
@@ -148,3 +148,25 @@ intelChooseTextureFormat(GLcontext * ctx, GLint internalFormat,
 
    return NULL;                 /* never get here */
 }
+
+int intel_compressed_num_bytes(GLuint mesaFormat)
+{
+   int bytes = 0;
+   switch(mesaFormat) {
+     
+   case MESA_FORMAT_RGB_FXT1:
+   case MESA_FORMAT_RGBA_FXT1:
+   case MESA_FORMAT_RGB_DXT1:
+   case MESA_FORMAT_RGBA_DXT1:
+     bytes = 2;
+     break;
+     
+   case MESA_FORMAT_RGBA_DXT3:
+   case MESA_FORMAT_RGBA_DXT5:
+     bytes = 4;
+   default:
+     break;
+   }
+   
+   return bytes;
+}
index 48c2f35d3b91c9ab988a45a2d5c58f569722ff6c..79f377a4b72d1f1698c9831eeef9c36d5233069d 100644 (file)
@@ -69,7 +69,7 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel,
    GLuint height = intelImage->base.Height;
    GLuint depth = intelImage->base.Depth;
    GLuint l2width, l2height, l2depth;
-   GLuint i;
+   GLuint i, comp_byte = 0;
 
    DBG("%s\n", __FUNCTION__);
 
@@ -121,6 +121,8 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel,
    }
 
    assert(!intelObj->mt);
+   if (intelImage->base.IsCompressed)
+      comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat->MesaFormat);
    intelObj->mt = intel_miptree_create(intel,
                                        intelObj->base.Target,
                                        intelImage->base.InternalFormat,
@@ -130,7 +132,7 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel,
                                        height,
                                        depth,
                                        intelImage->base.TexFormat->TexelBytes,
-                                       intelImage->base.IsCompressed);
+                                       comp_byte);
 
    DBG("%s - success\n", __FUNCTION__);
 }
@@ -298,7 +300,7 @@ intelTexImage(GLcontext * ctx,
               GLenum format, GLenum type, const void *pixels,
               const struct gl_pixelstore_attrib *unpack,
               struct gl_texture_object *texObj,
-              struct gl_texture_image *texImage)
+              struct gl_texture_image *texImage, GLsizei imageSize, int compressed)
 {
    struct intel_context *intel = intel_context(ctx);
    struct intel_texture_object *intelObj = intel_texture_object(texObj);
@@ -346,17 +348,26 @@ intelTexImage(GLcontext * ctx,
       break;
    }
 
-   texelBytes = texImage->TexFormat->TexelBytes;
-
-
-   /* Minimum pitch of 32 bytes */
-   if (postConvWidth * texelBytes < 32) {
-      postConvWidth = 32 / texelBytes;
-      texImage->RowStride = postConvWidth;
+   if (texImage->TexFormat->TexelBytes == 0) {
+      /* must be a compressed format */
+      texelBytes = 0;
+      texImage->IsCompressed = GL_TRUE;
+      texImage->CompressedSize =
+        ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
+                                          texImage->Height, texImage->Depth,
+                                          texImage->TexFormat->MesaFormat);
+   } else {
+      texelBytes = texImage->TexFormat->TexelBytes;
+      
+      /* Minimum pitch of 32 bytes */
+      if (postConvWidth * texelBytes < 32) {
+        postConvWidth = 32 / texelBytes;
+        texImage->RowStride = postConvWidth;
+      }
+      
+      assert(texImage->RowStride == postConvWidth);
    }
 
-   assert(texImage->RowStride == postConvWidth);
-
    /* Release the reference to a potentially orphaned buffer.   
     * Release any old malloced memory.
     */
@@ -453,9 +464,15 @@ intelTexImage(GLcontext * ctx,
     * the expectation that the mipmap tree will be set up but nothing
     * more will be done.  This is where those calls return:
     */
-   pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
-                                        format, type,
-                                        pixels, unpack, "glTexImage");
+   if (compressed) {
+      pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
+                                                     unpack,
+                                                     "glCompressedTexImage");
+   } else {
+      pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
+                                          format, type,
+                                          pixels, unpack, "glTexImage");
+   }
    if (!pixels)
       return;
 
@@ -478,7 +495,7 @@ intelTexImage(GLcontext * ctx,
       if (texImage->IsCompressed) {
          sizeInBytes = texImage->CompressedSize;
          dstRowStride =
-            _mesa_compressed_row_stride(texImage->InternalFormat, width);
+            _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
          assert(dims != 3);
       }
       else {
@@ -497,14 +514,16 @@ intelTexImage(GLcontext * ctx,
     * the blitter to copy.  Or, use the hardware to do the format
     * conversion and copy:
     */
-   if (!texImage->TexFormat->StoreImage(ctx, dims, 
-                                       texImage->_BaseFormat, 
-                                       texImage->TexFormat, 
-                                       texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
-                                        dstRowStride,
-                                        texImage->ImageOffsets,
-                                        width, height, depth,
-                                        format, type, pixels, unpack)) {
+   if (compressed) {
+     memcpy(texImage->Data, pixels, imageSize);
+   } else if (!texImage->TexFormat->StoreImage(ctx, dims, 
+                                              texImage->_BaseFormat, 
+                                              texImage->TexFormat, 
+                                              texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
+                                              dstRowStride,
+                                              texImage->ImageOffsets,
+                                              width, height, depth,
+                                              format, type, pixels, unpack)) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
    }
 
@@ -541,7 +560,7 @@ intelTexImage3D(GLcontext * ctx,
 {
    intelTexImage(ctx, 3, target, level,
                  internalFormat, width, height, depth, border,
-                 format, type, pixels, unpack, texObj, texImage);
+                 format, type, pixels, unpack, texObj, texImage, 0, 0);
 }
 
 
@@ -557,7 +576,7 @@ intelTexImage2D(GLcontext * ctx,
 {
    intelTexImage(ctx, 2, target, level,
                  internalFormat, width, height, 1, border,
-                 format, type, pixels, unpack, texObj, texImage);
+                 format, type, pixels, unpack, texObj, texImage, 0, 0);
 }
 
 void
@@ -572,20 +591,30 @@ intelTexImage1D(GLcontext * ctx,
 {
    intelTexImage(ctx, 1, target, level,
                  internalFormat, width, 1, 1, border,
-                 format, type, pixels, unpack, texObj, texImage);
+                 format, type, pixels, unpack, texObj, texImage, 0, 0);
 }
 
-
+void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
+                               GLint internalFormat,
+                               GLint width, GLint height, GLint border,
+                               GLsizei imageSize, const GLvoid *data,
+                               struct gl_texture_object *texObj,
+                               struct gl_texture_image *texImage )
+{
+   intelTexImage(ctx, 2, target, level,
+                internalFormat, width, height, 1, border,
+                0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1);
+}
 
 /**
  * Need to map texture image into memory before copying image data,
  * then unmap it.
  */
-void
-intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
-                 GLenum format, GLenum type, GLvoid * pixels,
-                 struct gl_texture_object *texObj,
-                 struct gl_texture_image *texImage)
+static void
+intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
+                   GLenum format, GLenum type, GLvoid * pixels,
+                   struct gl_texture_object *texObj,
+                   struct gl_texture_image *texImage, int compressed)
 {
    struct intel_context *intel = intel_context(ctx);
    struct intel_texture_image *intelImage = intel_texture_image(texImage);
@@ -615,8 +644,15 @@ intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
       assert(intelImage->base.Data);
    }
 
-   _mesa_get_teximage(ctx, target, level, format, type, pixels,
-                      texObj, texImage);
+
+   if (compressed) {
+      _mesa_get_compressed_teximage(ctx, target, level, pixels,
+                                   texObj, texImage);
+   } else {
+      _mesa_get_teximage(ctx, target, level, format, type, pixels,
+                        texObj, texImage);
+   }
+     
 
    /* Unmap */
    if (intelImage->mt) {
@@ -624,3 +660,26 @@ intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
       intelImage->base.Data = NULL;
    }
 }
+
+void
+intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
+                 GLenum format, GLenum type, GLvoid * pixels,
+                 struct gl_texture_object *texObj,
+                 struct gl_texture_image *texImage)
+{
+   intel_get_tex_image(ctx, target, level, format, type, pixels,
+                      texObj, texImage, 0);
+
+
+}
+
+void
+intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
+                          GLvoid *pixels,
+                          const struct gl_texture_object *texObj,
+                          const struct gl_texture_image *texImage)
+{
+   intel_get_tex_image(ctx, target, level, 0, 0, pixels,
+                      texObj, texImage, 1);
+
+}
index e273716b090b9504e609f9bfb9bd132d05f52c3a..5f82dfa19e6395f8212b121856ee59b4d9f1b2d7 100644 (file)
@@ -165,6 +165,10 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
    /* May need to create a new tree:
     */
    if (!intelObj->mt) {
+      int comp_byte = 0;
+      
+      if (firstImage->base.IsCompressed)
+        comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat->MesaFormat);
       intelObj->mt = intel_miptree_create(intel,
                                           intelObj->base.Target,
                                           firstImage->base.InternalFormat,
@@ -175,7 +179,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
                                           firstImage->base.Depth,
                                           firstImage->base.TexFormat->
                                           TexelBytes,
-                                          firstImage->base.IsCompressed);
+                                          comp_byte);
    }
 
    /* Pull in any images not in the object's tree: