Some initial RGB and RGBA floating point texture formats.
[mesa.git] / src / mesa / main / teximage.c
index de28839463aa65c56b62d44fb66991046885b239..3833b2681e6e48cc33ebee21910eba261fed1595 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  5.1
+ * Version:  6.1
  *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
+
+/**
+ * \file teximage.c
+ * Texture images manipulation functions.
+ *
+ * \note Mesa's native texture data type is GLchan.  Native formats are
+ * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA, and
+ * GL_COLOR_INDEX.
+ *
+ * \note Device drivers are free to implement any internal format they want.
+ */
+
+
 #include "glheader.h"
 #include "context.h"
 #include "convolve.h"
 #include "mtypes.h"
 
 
-/*
- * NOTES:
- *
- * Mesa's native texture datatype is GLchan.  Native formats are
- * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA,
- * and GL_COLOR_INDEX.
- * Device drivers are free to implement any internal format they want.
- */
-
-
 #if 0
 static void PrintTexture(GLcontext *ctx, const struct gl_texture_image *img)
 {
@@ -101,10 +104,9 @@ static void PrintTexture(GLcontext *ctx, const struct gl_texture_image *img)
 #endif
 
 
-
 /*
  * Compute floor(log_base_2(n)).
- * If n <= 0 return -1.
+ * If n < 0 return -1.
  */
 static int
 logbase2( int n )
@@ -112,9 +114,11 @@ logbase2( int n )
    GLint i = 1;
    GLint log2 = 0;
 
-   if (n <= 0) {
+   if (n < 0)
       return -1;
-   }
+
+   if (n == 0)
+      return 0;
 
    while ( n > i ) {
       i *= 2;
@@ -130,15 +134,17 @@ logbase2( int n )
 
 
 
-/*
- * Given an internal texture format enum or 1, 2, 3, 4 return the
- * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
- * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
+/**
+ * Get base internal format.
+ *
+ * \param ctx GL context.
+ * \param format internal texture format enum or 1, 2, 3, 4.
+ *
+ * \return the corresponding \u base internal format (GL_ALPHA, GL_LUMINANCE,
+ * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA), or -1 if invalid enum.
  *
  * This is the format which is used during texture application (i.e. the
  * texture format and env mode determine the arithmetic used.
- *
- * Return -1 if invalid enum.
  */
 GLint
 _mesa_base_tex_format( GLcontext *ctx, GLint format )
@@ -257,6 +263,30 @@ _mesa_base_tex_format( GLcontext *ctx, GLint format )
             return GL_RGBA;
          else
             return -1;
+      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+         if (ctx->Extensions.EXT_texture_compression_s3tc)
+            return GL_RGB;
+         else
+            return -1;
+      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+         if (ctx->Extensions.EXT_texture_compression_s3tc)
+            return GL_RGBA;
+         else
+            return -1;
+      case GL_RGB_S3TC:
+      case GL_RGB4_S3TC:
+         if (ctx->Extensions.S3_s3tc)
+            return GL_RGB;
+         else
+            return -1;
+      case GL_RGBA_S3TC:
+      case GL_RGBA4_S3TC:
+         if (ctx->Extensions.S3_s3tc)
+            return GL_RGBA;
+         else
+            return -1;
 
       case GL_YCBCR_MESA:
          if (ctx->Extensions.MESA_ycbcr_texture)
@@ -270,9 +300,9 @@ _mesa_base_tex_format( GLcontext *ctx, GLint format )
 }
 
 
-/*
- * Test if the given image format is a color/rgba format.  That is,
- * not color index, depth, stencil, etc.
+/**
+ * Test if the given image format is a color/RGBA format, i.e., not
+ * color index, depth, stencil, etc.
  */
 static GLboolean
 is_color_format(GLenum format)
@@ -328,6 +358,9 @@ is_color_format(GLenum format)
 }
 
 
+/**
+ * Test if the given image format is a color index format.
+ */
 static GLboolean
 is_index_format(GLenum format)
 {
@@ -347,26 +380,49 @@ is_index_format(GLenum format)
 
 
 /**
- * Return GL_TRUE if internalFormat is a supported compressed format,
- * return GL_FALSE otherwise.
- * \param - internalFormat - the internal format token provided by the user
+ * Test if it is a supported compressed format.
+ * 
+ * \param internalFormat the internal format token provided by the user.
+ * 
+ * \ret GL_TRUE if \p internalFormat is a supported compressed format, or
+ * GL_FALSE otherwise.
+ *
+ * Currently only GL_COMPRESSED_RGB_FXT1_3DFX and GL_COMPRESSED_RGBA_FXT1_3DFX
+ * are supported.
  */
 static GLboolean
-is_compressed_format(GLenum internalFormat)
+is_compressed_format(GLcontext *ctx, GLenum internalFormat)
 {
    switch (internalFormat) {
       case GL_COMPRESSED_RGB_FXT1_3DFX:
       case GL_COMPRESSED_RGBA_FXT1_3DFX:
+      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+      case GL_RGB_S3TC:
+      case GL_RGB4_S3TC:
+      case GL_RGBA_S3TC:
+      case GL_RGBA4_S3TC:
          return GL_TRUE;
       default:
+         if (ctx->Driver.IsCompressedFormat) {
+            return ctx->Driver.IsCompressedFormat(ctx, internalFormat);
+         }
          return GL_FALSE;
    }
 }
 
 
-/*
+/**
  * Store a gl_texture_image pointer in a gl_texture_object structure
  * according to the target and level parameters.
+ * 
+ * \param tObj texture object.
+ * \param target texture target.
+ * \param level image level.
+ * \param texImage texture image.
+ * 
  * This was basically prompted by the introduction of cube maps.
  */
 void
@@ -411,11 +467,14 @@ _mesa_set_tex_image(struct gl_texture_object *tObj,
 }
 
 
-
 /**
- * Return new gl_texture_image struct with all fields initialized to zero.
+ * Allocate a texture image structure.
+ * 
  * Called via ctx->Driver.NewTextureImage() unless overriden by a device
  * driver.
+ *
+ * \return a pointer to gl_texture_image struct with all fields initialized to
+ * zero.
  */
 struct gl_texture_image *
 _mesa_new_texture_image( GLcontext *ctx )
@@ -425,9 +484,12 @@ _mesa_new_texture_image( GLcontext *ctx )
 }
 
 
-
 /**
- * Delete/free the given texture image and associated image data if it's not
+ * Free texture image.
+ *
+ * \param teximage texture image.
+ *
+ * Free the texture image structure and the associated image data if it's not
  * marked as client data.
  */
 void
@@ -441,8 +503,12 @@ _mesa_delete_texture_image( struct gl_texture_image *teximage )
 }
 
 
-/*
- * Return GL_TRUE if the target is a proxy target.
+/**
+ * Test if a target is a proxy target.
+ *
+ * \param target texture target.
+ *
+ * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise.
  */
 static GLboolean
 is_proxy_target(GLenum target)
@@ -455,9 +521,16 @@ is_proxy_target(GLenum target)
 }
 
 
-/*
- * Given a texture unit and a texture target, return the corresponding
- * texture object.
+/**
+ * Get the texture object that corresponds to the target of the given texture unit.
+ *
+ * \param ctx GL context.
+ * \param texUnit texture unit.
+ * \param target texture target.
+ *
+ * \return pointer to the texture object on success, or NULL on failure.
+ * 
+ * \sa gl_texture_unit.
  */
 struct gl_texture_object *
 _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit,
@@ -501,9 +574,18 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit,
 }
 
 
-/*
- * Return the texture image struct which corresponds to target and level
- * for the given texture unit.
+/**
+ * Get the texture image struct which corresponds to target and level
+ * of the given texture unit.
+ *
+ * \param ctx GL context.
+ * \param texUnit texture unit.
+ * \param target texture target.
+ * \param level image level.
+ *
+ * \return pointer to the texture image structure on success, or NULL on failure.
+ *
+ * \sa gl_texture_unit.
  */
 struct gl_texture_image *
 _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
@@ -694,9 +776,16 @@ _mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level)
 }
 
 
-/*
- * Return the maximum number of allows mipmap levels for the given
- * texture target.
+/**
+ * Get the maximum number of allowed mipmap levels.
+ *
+ * \param ctx GL context.
+ * \param target texture target.
+ * 
+ * \return the maximum number of allowed mipmap levels for the given
+ * texture target, or zero if passed a bad target.
+ *
+ * \sa gl_constants.
  */
 GLint
 _mesa_max_texture_levels(GLcontext *ctx, GLenum target)
@@ -716,6 +805,7 @@ _mesa_max_texture_levels(GLcontext *ctx, GLenum target)
    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+   case GL_TEXTURE_CUBE_MAP_ARB:
    case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
       return ctx->Const.MaxCubeTextureLevels;
       break;
@@ -786,6 +876,9 @@ make_null_texture(GLint width, GLint height, GLint depth, GLenum format)
 
 /**
  * Reset the fields of a gl_texture_image struct to zero.
+ * 
+ * \param img texture image structure.
+ *
  * This is called when a proxy texture test fails, we set all the
  * image members (except DriverData) to zero.
  * It's also used in glTexImage[123]D as a safeguard to be sure all
@@ -811,14 +904,26 @@ clear_teximage_fields(struct gl_texture_image *img)
    img->DepthLog2 = 0;
    img->Data = NULL;
    img->TexFormat = &_mesa_null_texformat;
-   img->FetchTexel = NULL;
+   img->FetchTexelc = NULL;
+   img->FetchTexelf = NULL;
    img->IsCompressed = 0;
    img->CompressedSize = 0;
 }
 
 
-/*
+/**
  * Initialize basic fields of the gl_texture_image struct.
+ *
+ * \param ctx GL context.
+ * \param target texture target.
+ * \param img texture image structure to be initialized.
+ * \param width image width.
+ * \param height image height.
+ * \param depth image depth.
+ * \param border image border.
+ * \param internalFormat internal format.
+ *
+ * Fills in the fields of \p img with the given information.
  * Note: width, height and depth include the border.
  */
 void
@@ -849,7 +954,7 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
    img->Height2 = height - 2 * border; /*1 << img->HeightLog2;*/
    img->Depth2 = depth - 2 * border; /*1 << img->DepthLog2;*/
    img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
-   img->IsCompressed = is_compressed_format(internalFormat);
+   img->IsCompressed = is_compressed_format(ctx, internalFormat);
    if (img->IsCompressed)
       img->CompressedSize = _mesa_compressed_texture_size(ctx, width, height,
                                                        depth, internalFormat);
@@ -978,11 +1083,25 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
 
 
 /**
- * Test glTexImage[123]D() parameters for errors.
- * This function calls the ctx->Driver.TestProxyTexImage() function to
- * check the level and size.
- * \param dimensions  must be 1 or 2 or 3
- * \return  GL_TRUE if an error was detected or GL_FALSE if no errors
+ * Test the glTexImage[123]D() parameters for errors.
+ * 
+ * \param ctx GL context.
+ * \param target texture target given by the user.
+ * \param level image level given by the user.
+ * \param internalFormat internal format given by the user.
+ * \param format pixel data format given by the user.
+ * \param type pixel data type given by the user.
+ * \param dimensions texture image dimensions (must be 1, 2 or 3).
+ * \param width image width given by the user.
+ * \param height image height given by the user.
+ * \param depth image depth given by the user.
+ * \param border image border given by the user.
+ * 
+ * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
+ *
+ * Verifies each of the parameters against the constants specified in
+ * __GLcontextRec::Const and the supported extensions, and according to the
+ * OpenGL specification.
  */
 static GLboolean
 texture_error_check( GLcontext *ctx, GLenum target,
@@ -1015,10 +1134,10 @@ texture_error_check( GLcontext *ctx, GLenum target,
       return GL_TRUE;
    }
 
-   if (width < 1 || height < 1 || depth < 1) {
+   if (width < 0 || height < 0 || depth < 0) {
       if (!isProxy) {
          _mesa_error(ctx, GL_INVALID_VALUE,
-                     "glTexImage%dD(width, height or depth < 1)", dimensions);
+                     "glTexImage%dD(width, height or depth < 0)", dimensions);
       }
       return GL_TRUE;
    }
@@ -1155,7 +1274,7 @@ texture_error_check( GLcontext *ctx, GLenum target,
       }
    }
 
-   if (is_compressed_format(internalFormat)) {
+   if (is_compressed_format(ctx, internalFormat)) {
       if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
          /* OK */
       }
@@ -1186,12 +1305,27 @@ texture_error_check( GLcontext *ctx, GLenum target,
 }
 
 
-
-/*
+/**
  * Test glTexSubImage[123]D() parameters for errors.
- * Input:
- *         dimensions - must be 1 or 2 or 3
- * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
+ * 
+ * \param ctx GL context.
+ * \param dimensions texture image dimensions (must be 1, 2 or 3).
+ * \param target texture target given by the user.
+ * \param level image level given by the user.
+ * \param xoffset sub-image x offset given by the user.
+ * \param yoffset sub-image y offset given by the user.
+ * \param zoffset sub-image z offset given by the user.
+ * \param format pixel data format given by the user.
+ * \param type pixel data type given by the user.
+ * \param width image width given by the user.
+ * \param height image height given by the user.
+ * \param depth image depth given by the user.
+ * 
+ * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
+ *
+ * Verifies each of the parameters against the constants specified in
+ * __GLcontextRec::Const and the supported extensions, and according to the
+ * OpenGL specification.
  */
 static GLboolean
 subtexture_error_check( GLcontext *ctx, GLuint dimensions,
@@ -1353,10 +1487,24 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions,
 }
 
 
-/*
+/**
  * Test glCopyTexImage[12]D() parameters for errors.
- * Input:  dimensions - must be 1 or 2 or 3
- * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
+ * 
+ * \param ctx GL context.
+ * \param dimensions texture image dimensions (must be 1, 2 or 3).
+ * \param target texture target given by the user.
+ * \param level image level given by the user.
+ * \param internalFormat internal format given by the user.
+ * \param width image width given by the user.
+ * \param height image height given by the user.
+ * \param depth image depth given by the user.
+ * \param border texture border.
+ * 
+ * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
+ * 
+ * Verifies each of the parameters against the constants specified in
+ * __GLcontextRec::Const and the supported extensions, and according to the
+ * OpenGL specification.
  */
 static GLboolean
 copytexture_error_check( GLcontext *ctx, GLuint dimensions,
@@ -1459,7 +1607,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
       return GL_TRUE;
    }
 
-   if (is_compressed_format(internalFormat)) {
+   if (is_compressed_format(ctx, internalFormat)) {
       if (target != GL_TEXTURE_2D) {
          _mesa_error(ctx, GL_INVALID_ENUM,
                      "glCopyTexImage%d(target)", dimensions);
@@ -1477,6 +1625,25 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
 }
 
 
+/**
+ * Test glCopyTexImage[12]D() parameters for errors.
+ * 
+ * \param ctx GL context.
+ * \param dimensions texture image dimensions (must be 1, 2 or 3).
+ * \param target texture target given by the user.
+ * \param level image level given by the user.
+ * \param xoffset sub-image x offset given by the user.
+ * \param yoffset sub-image y offset given by the user.
+ * \param zoffset sub-image z offset given by the user.
+ * \param width image width given by the user.
+ * \param height image height given by the user.
+ * 
+ * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
+ * 
+ * Verifies each of the parameters against the constants specified in
+ * __GLcontextRec::Const and the supported extensions, and according to the
+ * OpenGL specification.
+ */
 static GLboolean
 copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
                              GLenum target, GLint level,
@@ -1618,8 +1785,16 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions,
 }
 
 
-
-void
+/**
+ * Get texture image.
+ *
+ * \param target texture target.
+ * \param level image level.
+ * \param format pixel data format.
+ * \param type pixel data type.
+ * \param pixels pixel data.
+ */
+void GLAPIENTRY
 _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
                    GLenum type, GLvoid *pixels )
 {
@@ -1701,8 +1876,9 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
                GLuint indexRow[MAX_WIDTH];
                GLint col;
                for (col = 0; col < width; col++) {
-                  (*texImage->FetchTexel)(texImage, col, row, img,
-                                          (GLvoid *) &indexRow[col]);
+                  GLchan indx;
+                  (*texImage->FetchTexelc)(texImage, col, row, img, &indx);
+                  indexRow[col] = indx;
                }
                _mesa_pack_index_span(ctx, width, type, dest,
                                      indexRow, &ctx->Pack,
@@ -1712,8 +1888,8 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
                GLfloat depthRow[MAX_WIDTH];
                GLint col;
                for (col = 0; col < width; col++) {
-                  (*texImage->FetchTexel)(texImage, col, row, img,
-                                          (GLvoid *) &depthRow[col]);
+                  (*texImage->FetchTexelf)(texImage, col, row, img,
+                                           (GLvoid *) &depthRow[col]);
                }
                _mesa_pack_depth_span(ctx, width, dest, type,
                                      depthRow, &ctx->Pack);
@@ -1741,8 +1917,7 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
                GLchan rgba[MAX_WIDTH][4];
                GLint col;
                for (col = 0; col < width; col++) {
-                  (*texImage->FetchTexel)(texImage, col, row, img,
-                                          (GLvoid *) rgba[col]);
+                  (*texImage->FetchTexelc)(texImage, col, row, img, rgba[col]);
                }
                _mesa_pack_rgba_span(ctx, width, (const GLchan (*)[4])rgba,
                                     format, type, dest, &ctx->Pack,
@@ -1758,7 +1933,7 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
 /*
  * Called from the API.  Note that width includes the border.
  */
-void
+void GLAPIENTRY
 _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
                   GLsizei width, GLint border, GLenum format,
                   GLenum type, const GLvoid *pixels )
@@ -1810,11 +1985,14 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
                                 &ctx->Unpack, texObj, texImage);
 
       ASSERT(texImage->TexFormat);
-      if (!texImage->FetchTexel) {
-         /* If driver didn't explicitly set this, use the default */
-         texImage->FetchTexel = texImage->TexFormat->FetchTexel1D;
-      }
-      ASSERT(texImage->FetchTexel);
+
+      /* If driver didn't explicitly set this, use the defaults */
+      if (!texImage->FetchTexelc)
+         texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
+      if (!texImage->FetchTexelf)
+         texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
+      ASSERT(texImage->FetchTexelc);
+      ASSERT(texImage->FetchTexelf);
 
       /* state update */
       texObj->Complete = GL_FALSE;
@@ -1847,7 +2025,7 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
 }
 
 
-void
+void GLAPIENTRY
 _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
                   GLsizei width, GLsizei height, GLint border,
                   GLenum format, GLenum type,
@@ -1907,11 +2085,14 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
                                 &ctx->Unpack, texObj, texImage);
 
       ASSERT(texImage->TexFormat);
-      if (!texImage->FetchTexel) {
-         /* If driver didn't explicitly set this, use the default */
-         texImage->FetchTexel = texImage->TexFormat->FetchTexel2D;
-      }
-      ASSERT(texImage->FetchTexel);
+
+      /* If driver didn't explicitly set these, use the defaults */
+      if (!texImage->FetchTexelc)
+         texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
+      if (!texImage->FetchTexelf)
+         texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
+      ASSERT(texImage->FetchTexelc);
+      ASSERT(texImage->FetchTexelf);
 
       /* state update */
       texObj->Complete = GL_FALSE;
@@ -1952,7 +2133,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
  * Called by the API or display list executor.
  * Note that width and height include the border.
  */
-void
+void GLAPIENTRY
 _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
                   GLsizei width, GLsizei height, GLsizei depth,
                   GLint border, GLenum format, GLenum type,
@@ -1998,11 +2179,14 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
                                 pixels, &ctx->Unpack, texObj, texImage);
 
       ASSERT(texImage->TexFormat);
-      if (!texImage->FetchTexel) {
-         /* If driver didn't explicitly set this, use the default */
-         texImage->FetchTexel = texImage->TexFormat->FetchTexel3D;
-      }
-      ASSERT(texImage->FetchTexel);
+
+      /* If driver didn't explicitly set these, use the defaults */
+      if (!texImage->FetchTexelc)
+         texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
+      if (!texImage->FetchTexelf)
+         texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
+      ASSERT(texImage->FetchTexelc);
+      ASSERT(texImage->FetchTexelf);
 
       /* state update */
       texObj->Complete = GL_FALSE;
@@ -2033,7 +2217,7 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
 }
 
 
-void
+void GLAPIENTRY
 _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat,
                      GLsizei width, GLsizei height, GLsizei depth,
                      GLint border, GLenum format, GLenum type,
@@ -2045,7 +2229,7 @@ _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat,
 
 
 
-void
+void GLAPIENTRY
 _mesa_TexSubImage1D( GLenum target, GLint level,
                      GLint xoffset, GLsizei width,
                      GLenum format, GLenum type,
@@ -2090,7 +2274,7 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
 }
 
 
-void
+void GLAPIENTRY
 _mesa_TexSubImage2D( GLenum target, GLint level,
                      GLint xoffset, GLint yoffset,
                      GLsizei width, GLsizei height,
@@ -2139,7 +2323,7 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
 
 
 
-void
+void GLAPIENTRY
 _mesa_TexSubImage3D( GLenum target, GLint level,
                      GLint xoffset, GLint yoffset, GLint zoffset,
                      GLsizei width, GLsizei height, GLsizei depth,
@@ -2184,7 +2368,7 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
 
 
 
-void
+void GLAPIENTRY
 _mesa_CopyTexImage1D( GLenum target, GLint level,
                       GLenum internalFormat,
                       GLint x, GLint y,
@@ -2231,11 +2415,14 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
                                  x, y, width, border);
 
    ASSERT(texImage->TexFormat);
-   if (!texImage->FetchTexel) {
-      /* If driver didn't explicitly set this, use the default */
-      texImage->FetchTexel = texImage->TexFormat->FetchTexel1D;
-   }
-   ASSERT(texImage->FetchTexel);
+
+   /* If driver didn't explicitly set these, use the defaults */
+   if (!texImage->FetchTexelc)
+      texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
+   if (!texImage->FetchTexelf)
+      texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
+   ASSERT(texImage->FetchTexelc);
+   ASSERT(texImage->FetchTexelf);
 
    /* state update */
    texObj->Complete = GL_FALSE;
@@ -2244,7 +2431,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
 
 
 
-void
+void GLAPIENTRY
 _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
                       GLint x, GLint y, GLsizei width, GLsizei height,
                       GLint border )
@@ -2291,11 +2478,14 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
                                  x, y, width, height, border);
 
    ASSERT(texImage->TexFormat);
-   if (!texImage->FetchTexel) {
-      /* If driver didn't explicitly set this, use the default */
-      texImage->FetchTexel = texImage->TexFormat->FetchTexel2D;
-   }
-   ASSERT(texImage->FetchTexel);
+
+   /* If driver didn't explicitly set these, use the defaults */
+   if (!texImage->FetchTexelc)
+      texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
+   if (!texImage->FetchTexelf)
+      texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
+   ASSERT(texImage->FetchTexelc);
+   ASSERT(texImage->FetchTexelf);
 
    /* state update */
    texObj->Complete = GL_FALSE;
@@ -2304,12 +2494,11 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
 
 
 
-void
+void GLAPIENTRY
 _mesa_CopyTexSubImage1D( GLenum target, GLint level,
                          GLint xoffset, GLint x, GLint y, GLsizei width )
 {
    struct gl_texture_unit *texUnit;
-   struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
    GLsizei postConvWidth = width;
    GET_CURRENT_CONTEXT(ctx);
@@ -2326,7 +2515,6 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
       return;
 
    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-   texObj = _mesa_select_tex_object(ctx, texUnit, target);
    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
    ASSERT(texImage);
 
@@ -2340,13 +2528,12 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
 
 
 
-void
+void GLAPIENTRY
 _mesa_CopyTexSubImage2D( GLenum target, GLint level,
                          GLint xoffset, GLint yoffset,
                          GLint x, GLint y, GLsizei width, GLsizei height )
 {
    struct gl_texture_unit *texUnit;
-   struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
    GLsizei postConvWidth = width, postConvHeight = height;
    GET_CURRENT_CONTEXT(ctx);
@@ -2363,7 +2550,6 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
       return;
 
    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-   texObj = _mesa_select_tex_object(ctx, texUnit, target);
    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
    ASSERT(texImage);
 
@@ -2379,13 +2565,12 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
 
 
 
-void
+void GLAPIENTRY
 _mesa_CopyTexSubImage3D( GLenum target, GLint level,
                          GLint xoffset, GLint yoffset, GLint zoffset,
                          GLint x, GLint y, GLsizei width, GLsizei height )
 {
    struct gl_texture_unit *texUnit;
-   struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
    GLsizei postConvWidth = width, postConvHeight = height;
    GET_CURRENT_CONTEXT(ctx);
@@ -2402,7 +2587,6 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
       return;
 
    texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
-   texObj = _mesa_select_tex_object(ctx, texUnit, target);
    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
    ASSERT(texImage);
 
@@ -2437,7 +2621,6 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions,
                                GLsizei height, GLsizei depth, GLint border,
                                GLsizei imageSize)
 {
-   GLboolean isProxy = GL_FALSE;
    GLint expectedSize, maxLevels = 0, maxTextureSize;
 
    if (dimensions == 1) {
@@ -2447,7 +2630,6 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions,
    else if (dimensions == 2) {
       if (target == GL_PROXY_TEXTURE_2D) {
          maxLevels = ctx->Const.MaxTextureLevels;
-         isProxy = GL_TRUE;
       }
       else if (target == GL_TEXTURE_2D) {
          maxLevels = ctx->Const.MaxTextureLevels;
@@ -2456,7 +2638,6 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions,
          if (!ctx->Extensions.ARB_texture_cube_map)
             return GL_INVALID_ENUM; /*target*/
          maxLevels = ctx->Const.MaxCubeTextureLevels;
-         isProxy = GL_TRUE;
       }
       else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
                target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
@@ -2475,7 +2656,7 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions,
 
    maxTextureSize = 1 << (maxLevels - 1);
 
-   if (!is_compressed_format(internalFormat))
+   if (!is_compressed_format(ctx, internalFormat))
       return GL_INVALID_ENUM;
 
    if (border != 0)
@@ -2526,7 +2707,6 @@ compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions,
                                   GLsizei width, GLsizei height, GLsizei depth,
                                   GLenum format, GLsizei imageSize)
 {
-   GLboolean isProxy = GL_FALSE;
    GLint expectedSize, maxLevels = 0, maxTextureSize;
 
    if (dimensions == 1) {
@@ -2536,7 +2716,6 @@ compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions,
    else if (dimensions == 2) {
       if (target == GL_PROXY_TEXTURE_2D) {
          maxLevels = ctx->Const.MaxTextureLevels;
-         isProxy = GL_TRUE;
       }
       else if (target == GL_TEXTURE_2D) {
          maxLevels = ctx->Const.MaxTextureLevels;
@@ -2545,7 +2724,6 @@ compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions,
          if (!ctx->Extensions.ARB_texture_cube_map)
             return GL_INVALID_ENUM; /*target*/
          maxLevels = ctx->Const.MaxCubeTextureLevels;
-         isProxy = GL_TRUE;
       }
       else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
                target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
@@ -2564,7 +2742,7 @@ compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions,
 
    maxTextureSize = 1 << (maxLevels - 1);
 
-   if (!is_compressed_format(format))
+   if (!is_compressed_format(ctx, format))
       return GL_INVALID_ENUM;
 
    if (width < 1 || width > maxTextureSize)
@@ -2596,7 +2774,7 @@ compressed_subtexture_error_check(GLcontext *ctx, GLint dimensions,
 
 
 
-void
+void GLAPIENTRY
 _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
                               GLenum internalFormat, GLsizei width,
                               GLint border, GLsizei imageSize,
@@ -2675,7 +2853,7 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
 }
 
 
-void
+void GLAPIENTRY
 _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
                               GLenum internalFormat, GLsizei width,
                               GLsizei height, GLint border, GLsizei imageSize,
@@ -2759,7 +2937,7 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
 }
 
 
-void
+void GLAPIENTRY
 _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
                               GLenum internalFormat, GLsizei width,
                               GLsizei height, GLsizei depth, GLint border,
@@ -2839,7 +3017,7 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
 }
 
 
-void
+void GLAPIENTRY
 _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
                                  GLsizei width, GLenum format,
                                  GLsizei imageSize, const GLvoid *data)
@@ -2887,7 +3065,7 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
 }
 
 
-void
+void GLAPIENTRY
 _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
                                  GLint yoffset, GLsizei width, GLsizei height,
                                  GLenum format, GLsizei imageSize,
@@ -2903,6 +3081,7 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
    error = compressed_subtexture_error_check(ctx, 2, target, level,
                      xoffset, yoffset, 0, width, height, 1, format, imageSize);
    if (error) {
+      /* XXX proxy target? */
       _mesa_error(ctx, error, "glCompressedTexSubImage2D");
       return;
    }
@@ -2937,7 +3116,7 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
 }
 
 
-void
+void GLAPIENTRY
 _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
                                  GLint yoffset, GLint zoffset, GLsizei width,
                                  GLsizei height, GLsizei depth, GLenum format,
@@ -2989,7 +3168,7 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
 }
 
 
-void
+void GLAPIENTRY
 _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
 {
    const struct gl_texture_unit *texUnit;