initial support for GL_SGIS_generate_mipmap extension
authorBrian Paul <brian.paul@tungstengraphics.com>
Mon, 21 May 2001 16:41:03 +0000 (16:41 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Mon, 21 May 2001 16:41:03 +0000 (16:41 +0000)
src/mesa/main/context.c
src/mesa/main/extensions.c
src/mesa/main/get.c
src/mesa/main/hint.c
src/mesa/main/mtypes.h
src/mesa/main/teximage.c
src/mesa/main/teximage.h
src/mesa/main/texstate.c
src/mesa/main/texstore.c
src/mesa/main/texstore.h
src/mesa/swrast/s_texstore.c

index f855b90f3ce10c5050fb152488548c765db20582..d7cdf10b00a49c6126eaf692d2992aed7bdd5b80 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: context.c,v 1.137 2001/05/07 16:32:51 brianp Exp $ */
+/* $Id: context.c,v 1.138 2001/05/21 16:41:03 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -918,6 +918,7 @@ init_attrib_groups( GLcontext *ctx )
    ctx->Hint.Fog = GL_DONT_CARE;
    ctx->Hint.ClipVolumeClipping = GL_DONT_CARE;
    ctx->Hint.TextureCompression = GL_DONT_CARE;
+   ctx->Hint.GenerateMipmap = GL_DONT_CARE;
 
    /* Histogram group */
    ctx->Histogram.Width = 0;
index 3a0826781490d8a3a7f8a2c2027e5bef4fbe6027..8faeb090963e76ba9bbb7dc89374b0468376dfe6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: extensions.c,v 1.58 2001/04/24 21:52:36 brianp Exp $ */
+/* $Id: extensions.c,v 1.59 2001/05/21 16:41:03 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -106,6 +106,7 @@ static struct {
    { ON,  "GL_NV_texgen_reflection",           F(NV_texgen_reflection) },
    { OFF, "GL_SGI_color_matrix",               F(SGI_color_matrix) },
    { OFF, "GL_SGI_color_table",                F(SGI_color_table) },
+   /*{ OFF, "GL_SGIS_generate_mipmap",           F(SGIS_generate_mipmap) },*/
    { OFF, "GL_SGIS_pixel_texture",             F(SGIS_pixel_texture) },
    { OFF, "GL_SGIS_texture_border_clamp",      F(ARB_texture_border_clamp) },
    { OFF, "GL_SGIS_texture_edge_clamp",        F(SGIS_texture_edge_clamp) },
@@ -158,6 +159,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
       "GL_NV_texgen_reflection",
       "GL_SGI_color_matrix",
       "GL_SGI_color_table",
+      "GL_SGIS_generate_mipmap",
       "GL_SGIS_pixel_texture",
       "GL_SGIS_texture_edge_clamp",
       "GL_SGIS_texture_border_clamp",
index 1e9b7be3ce6603add33981f45bf2b3a78259aed4..b16343831db270b2890acea6163156612ad18c26 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: get.c,v 1.59 2001/05/03 23:55:38 brianp Exp $ */
+/* $Id: get.c,v 1.60 2001/05/21 16:41:03 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -1280,6 +1280,17 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
          }
          break;
 
+      /* GL_SGIS_generate_mipmap */
+      case GL_GENERATE_MIPMAP_HINT_SGIS:
+         if (ctx->Extensions.SGIS_generate_mipmap) {
+            *params = ENUM_TO_BOOL(ctx->Hint.GenerateMipmap);
+         }
+         else {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv");
+           return;
+         }
+         break;
+
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glGetBooleanv" );
    }
@@ -2484,6 +2495,17 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params )
          }
          break;
 
+      /* GL_SGIS_generate_mipmap */
+      case GL_GENERATE_MIPMAP_HINT_SGIS:
+         if (ctx->Extensions.SGIS_generate_mipmap) {
+            *params = (GLdouble) ctx->Hint.GenerateMipmap;
+         }
+         else {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev");
+           return;
+         }
+         break;
+
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glGetDoublev" );
    }
@@ -3662,6 +3684,17 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
          }
          break;
 
+      /* GL_SGIS_generate_mipmap */
+      case GL_GENERATE_MIPMAP_HINT_SGIS:
+         if (ctx->Extensions.SGIS_generate_mipmap) {
+            *params = (GLfloat) ctx->Hint.GenerateMipmap;
+         }
+         else {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv");
+           return;
+         }
+         break;
+
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glGetFloatv" );
    }
@@ -4889,6 +4922,17 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
          }
          break;
 
+      /* GL_SGIS_generate_mipmap */
+      case GL_GENERATE_MIPMAP_HINT_SGIS:
+         if (ctx->Extensions.SGIS_generate_mipmap) {
+            *params = (GLint) ctx->Hint.GenerateMipmap;
+         }
+         else {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv");
+           return;
+         }
+         break;
+
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glGetIntegerv" );
    }
index ce0b27394faaf0f76f0d81a46288d726f0dafd0d..e37cfb1a87d7c9ce8798ab7764635f033350bdff 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: hint.c,v 1.9 2001/03/12 00:48:38 gareth Exp $ */
+/* $Id: hint.c,v 1.10 2001/05/21 16:41:03 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -99,9 +99,9 @@ _mesa_try_Hint( GLcontext *ctx, GLenum target, GLenum mode )
 
       /* GL_ARB_texture_compression */
       case GL_TEXTURE_COMPRESSION_HINT_ARB:
-         if (ctx->Extensions.ARB_texture_compression) {
+         if (!ctx->Extensions.ARB_texture_compression) {
             _mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)");
-           return GL_TRUE;
+           return GL_FALSE;
          }
         if (ctx->Hint.TextureCompression == mode)
            return GL_TRUE;
@@ -109,6 +109,18 @@ _mesa_try_Hint( GLcontext *ctx, GLenum target, GLenum mode )
         ctx->Hint.TextureCompression = mode;
          break;
 
+      /* GL_SGIS_generate_mipmap */
+      case GL_GENERATE_MIPMAP_HINT_SGIS:
+         if (!ctx->Extensions.SGIS_generate_mipmap) {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)");
+           return GL_FALSE;
+         }
+         if (ctx->Hint.GenerateMipmap == mode)
+            return GL_TRUE;
+        FLUSH_VERTICES(ctx, _NEW_HINT);
+        ctx->Hint.GenerateMipmap = mode;
+         break;
+
       default:
          _mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)");
          return GL_FALSE;
index 651b6bb7b95fe8b0269fd7aad13573538a036132..b8c2ec7af6e1f178321506ef706051c24e7f7ee3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mtypes.h,v 1.41 2001/04/28 08:39:17 keithw Exp $ */
+/* $Id: mtypes.h,v 1.42 2001/05/21 16:41:03 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -430,12 +430,9 @@ struct gl_hint_attrib {
    GLenum LineSmooth;
    GLenum PolygonSmooth;
    GLenum Fog;
-
-   /* GL_EXT_clip_volume_hint */
-   GLenum ClipVolumeClipping;
-
-   /* GL_ARB_texture_compression */
-   GLenum TextureCompression;
+   GLenum ClipVolumeClipping;   /* GL_EXT_clip_volume_hint */
+   GLenum TextureCompression;   /* GL_ARB_texture_compression */
+   GLenum GenerateMipmap;       /* GL_SGIS_generate_mipmap */
 };
 
 
@@ -826,6 +823,8 @@ struct gl_texture_object {
    GLchan ShadowAmbient;       /* GL_SGIX_shadow_ambient */
    GLint _MaxLevel;            /* actual max mipmap level (q in the spec) */
    GLfloat _MaxLambda;         /* = _MaxLevel - BaseLevel (q - b in spec) */
+   GLboolean GenerateMipmap;    /* GL_SGIS_generate_mipmap */
+
    struct gl_texture_image *Image[MAX_TEXTURE_LEVELS];
 
    /* Texture cube faces */
@@ -1218,6 +1217,7 @@ struct gl_extensions {
    GLboolean NV_texgen_reflection;
    GLboolean SGI_color_matrix;
    GLboolean SGI_color_table;
+   GLboolean SGIS_generate_mipmap;
    GLboolean SGIS_pixel_texture;
    GLboolean SGIS_texture_edge_clamp;
    GLboolean SGIX_depth_texture;
index 723d74d7aae1b2cd9073d8495099e30fbb4456fe..2f1d4383926a4d55762dcacb16994528900ab3e0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: teximage.c,v 1.93 2001/04/24 03:00:17 brianp Exp $ */
+/* $Id: teximage.c,v 1.94 2001/05/21 16:41:03 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -39,6 +39,7 @@
 #include "texformat.h"
 #include "teximage.h"
 #include "texstate.h"
+#include "texstore.h"
 #include "mtypes.h"
 #include "swrast/s_span.h" /* XXX SWRAST hack */
 #endif
@@ -319,10 +320,10 @@ is_compressed_format(GLcontext *ctx, GLenum internalFormat)
  * according to the target and level parameters.
  * This was basically prompted by the introduction of cube maps.
  */
-static void
-set_tex_image(struct gl_texture_object *tObj,
-              GLenum target, GLint level,
-              struct gl_texture_image *texImage)
+void
+_mesa_set_tex_image(struct gl_texture_object *tObj,
+                    GLenum target, GLint level,
+                    struct gl_texture_image *texImage)
 {
    ASSERT(tObj);
    ASSERT(texImage);
@@ -349,7 +350,7 @@ set_tex_image(struct gl_texture_object *tObj,
          tObj->NegZ[level] = texImage;
          return;
       default:
-         _mesa_problem(NULL, "bad target in set_tex_image()");
+         _mesa_problem(NULL, "bad target in _mesa_set_tex_image()");
          return;
    }
 }
@@ -581,11 +582,11 @@ clear_teximage_fields(struct gl_texture_image *img)
 /*
  * Initialize basic fields of the gl_texture_image struct.
  */
-static void
-init_teximage_fields(GLcontext *ctx,
-                     struct gl_texture_image *img,
-                     GLsizei width, GLsizei height, GLsizei depth,
-                     GLint border, GLenum internalFormat)
+void
+_mesa_init_teximage_fields(GLcontext *ctx,
+                           struct gl_texture_image *img,
+                           GLsizei width, GLsizei height, GLsizei depth,
+                           GLint border, GLenum internalFormat)
 {
    ASSERT(img);
    img->Format = _mesa_base_tex_format( ctx, internalFormat );
@@ -1324,8 +1325,8 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
          texImage->Data = NULL;
       }
       clear_teximage_fields(texImage); /* not really needed, but helpful */
-      init_teximage_fields(ctx, texImage, postConvWidth, 1, 1,
-                           border, internalFormat);
+      _mesa_init_teximage_fields(ctx, texImage, postConvWidth, 1, 1,
+                                 border, internalFormat);
 
       if (ctx->NewState & _NEW_PIXEL)
          _mesa_update_state(ctx);
@@ -1368,8 +1369,8 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
          struct gl_texture_image *texImage;
          texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
          texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
-         init_teximage_fields(ctx, texImage, postConvWidth, 1, 1,
-                              border, internalFormat);
+         _mesa_init_teximage_fields(ctx, texImage, postConvWidth, 1, 1,
+                                    border, internalFormat);
          ASSERT(ctx->Driver.TestProxyTexImage);
          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
                                                   internalFormat, format, type,
@@ -1425,7 +1426,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
 
       if (!texImage) {
          texImage = _mesa_alloc_texture_image();
-         set_tex_image(texObj, target, level, texImage);
+         _mesa_set_tex_image(texObj, target, level, texImage);
          if (!texImage) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
             return;
@@ -1437,8 +1438,8 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
          texImage->Data = NULL;
       }
       clear_teximage_fields(texImage); /* not really needed, but helpful */
-      init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1,
-                           border, internalFormat);
+      _mesa_init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight,
+                                 1, border, internalFormat);
 
       if (ctx->NewState & _NEW_PIXEL)
          _mesa_update_state(ctx);
@@ -1481,8 +1482,8 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
          struct gl_texture_image *texImage;
          texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
          texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
-         init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1,
-                              border, internalFormat);
+         _mesa_init_teximage_fields(ctx, texImage, postConvWidth,
+                                    postConvHeight, 1, border, internalFormat);
          ASSERT(ctx->Driver.TestProxyTexImage);
          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
                                     internalFormat, format, type,
@@ -1542,8 +1543,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLenum internalFormat,
          texImage->Data = NULL;
       }
       clear_teximage_fields(texImage); /* not really needed, but helpful */
-      init_teximage_fields(ctx, texImage, width, height, depth, border,
-                           internalFormat);
+      _mesa_init_teximage_fields(ctx, texImage, width, height, depth, border,
+                                 internalFormat);
 
       if (ctx->NewState & _NEW_PIXEL)
          _mesa_update_state(ctx);
@@ -1587,8 +1588,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLenum internalFormat,
          struct gl_texture_image *texImage;
          texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
          texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
-         init_teximage_fields(ctx, texImage, width, height, 1,
-                              border, internalFormat);
+         _mesa_init_teximage_fields(ctx, texImage, width, height, 1,
+                                    border, internalFormat);
          ASSERT(ctx->Driver.TestProxyTexImage);
          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
                                                  internalFormat, format, type,
@@ -1788,7 +1789,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
    if (!texImage) {
       texImage = _mesa_alloc_texture_image();
-      set_tex_image(texObj, target, level, texImage);
+      _mesa_set_tex_image(texObj, target, level, texImage);
       if (!texImage) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
          return;
@@ -1801,8 +1802,8 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
    }
 
    clear_teximage_fields(texImage); /* not really needed, but helpful */
-   init_teximage_fields(ctx, texImage, postConvWidth, 1, 1,
-                        border, internalFormat);
+   _mesa_init_teximage_fields(ctx, texImage, postConvWidth, 1, 1,
+                              border, internalFormat);
 
 
    ASSERT(ctx->Driver.CopyTexImage1D);
@@ -1852,7 +1853,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
    texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
    if (!texImage) {
       texImage = _mesa_alloc_texture_image();
-      set_tex_image(texObj, target, level, texImage);
+      _mesa_set_tex_image(texObj, target, level, texImage);
       if (!texImage) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
          return;
@@ -1865,8 +1866,8 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
    }
 
    clear_teximage_fields(texImage); /* not really needed, but helpful */
-   init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1,
-                        border, internalFormat);
+   _mesa_init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1,
+                              border, internalFormat);
 
    ASSERT(ctx->Driver.CopyTexImage2D);
    (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat,
@@ -2049,7 +2050,8 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
          texImage->Data = NULL;
       }
 
-      init_teximage_fields(ctx, texImage, width, 1, 1, border, internalFormat);
+      _mesa_init_teximage_fields(ctx, texImage, width, 1, 1,
+                                 border, internalFormat);
 
       if (ctx->Extensions.ARB_texture_compression) {
          ASSERT(ctx->Driver.CompressedTexImage1D);
@@ -2073,8 +2075,8 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
          struct gl_texture_image *texImage;
          texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
          texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
-         init_teximage_fields(ctx, texImage, width, 1, 1,
-                              border, internalFormat);
+         _mesa_init_teximage_fields(ctx, texImage, width, 1, 1,
+                                    border, internalFormat);
          ASSERT(ctx->Driver.TestProxyTexImage);
          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
                                              internalFormat, GL_NONE, GL_NONE,
@@ -2147,8 +2149,8 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
          texImage->Data = NULL;
       }
 
-      init_teximage_fields(ctx, texImage, width, height, 1, border,
-                           internalFormat);
+      _mesa_init_teximage_fields(ctx, texImage, width, height, 1, border,
+                                 internalFormat);
 
       if (ctx->Extensions.ARB_texture_compression) {
          ASSERT(ctx->Driver.CompressedTexImage2D);
@@ -2172,8 +2174,8 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
          struct gl_texture_image *texImage;
          texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
          texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
-         init_teximage_fields(ctx, texImage, width, height, 1,
-                              border, internalFormat);
+         _mesa_init_teximage_fields(ctx, texImage, width, height, 1,
+                                    border, internalFormat);
          ASSERT(ctx->Driver.TestProxyTexImage);
          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
                                               internalFormat, GL_NONE, GL_NONE,
@@ -2243,8 +2245,8 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
          texImage->Data = NULL;
       }
 
-      init_teximage_fields(ctx, texImage, width, height, depth, border,
-                           internalFormat);
+      _mesa_init_teximage_fields(ctx, texImage, width, height, depth, border,
+                                 internalFormat);
 
       if (ctx->Extensions.ARB_texture_compression) {
          ASSERT(ctx->Driver.CompressedTexImage3D);
@@ -2269,8 +2271,8 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
          struct gl_texture_image *texImage;
          texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
          texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
-         init_teximage_fields(ctx, texImage, width, height, depth,
-                              border, internalFormat);
+         _mesa_init_teximage_fields(ctx, texImage, width, height, depth,
+                                    border, internalFormat);
          ASSERT(ctx->Driver.TestProxyTexImage);
          error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level,
                                              internalFormat, GL_NONE, GL_NONE,
index b5664e4efaa17dd471b1119aaeae1d78316121e9..12c6c99e5febac2715e12436d3dce08500fae5cf 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: teximage.h,v 1.18 2001/03/26 20:02:39 brianp Exp $ */
+/* $Id: teximage.h,v 1.19 2001/05/21 16:41:03 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -47,6 +47,19 @@ extern void
 _mesa_free_texture_image( struct gl_texture_image *teximage );
 
 
+extern void
+_mesa_init_teximage_fields(GLcontext *ctx,
+                           struct gl_texture_image *img,
+                           GLsizei width, GLsizei height, GLsizei depth,
+                           GLint border, GLenum internalFormat);
+
+
+extern void
+_mesa_set_tex_image(struct gl_texture_object *tObj,
+                    GLenum target, GLint level,
+                    struct gl_texture_image *texImage);
+
+
 extern struct gl_texture_object *
 _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit,
                         GLenum target);
index 2a4a9a9f96d2bb4094b7e0ebab6d593d0b980974..afa3d07753dd2cc3972255605a7f7f79aa64dfe8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: texstate.c,v 1.50 2001/05/18 22:10:49 brianp Exp $ */
+/* $Id: texstate.c,v 1.51 2001/05/21 16:41:03 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -1043,6 +1043,15 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
             return;
          }
          break;
+      case GL_GENERATE_MIPMAP_SGIS:
+         if (ctx->Extensions.SGIS_generate_mipmap) {
+            texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
+         }
+         else {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname)");
+            return;
+         }
+         break;
       default:
          _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(pname)" );
          return;
@@ -1272,25 +1281,25 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
    switch (pname) {
       case GL_TEXTURE_MAG_FILTER:
         *params = ENUM_TO_FLOAT(obj->MagFilter);
-        break;
+        return;
       case GL_TEXTURE_MIN_FILTER:
          *params = ENUM_TO_FLOAT(obj->MinFilter);
-         break;
+         return;
       case GL_TEXTURE_WRAP_S:
          *params = ENUM_TO_FLOAT(obj->WrapS);
-         break;
+         return;
       case GL_TEXTURE_WRAP_T:
          *params = ENUM_TO_FLOAT(obj->WrapT);
-         break;
+         return;
       case GL_TEXTURE_WRAP_R_EXT:
          *params = ENUM_TO_FLOAT(obj->WrapR);
-         break;
+         return;
       case GL_TEXTURE_BORDER_COLOR:
          params[0] = obj->BorderColor[0] / CHAN_MAXF;
          params[1] = obj->BorderColor[1] / CHAN_MAXF;
          params[2] = obj->BorderColor[2] / CHAN_MAXF;
          params[3] = obj->BorderColor[3] / CHAN_MAXF;
-         break;
+         return;
       case GL_TEXTURE_RESIDENT:
          {
             GLboolean resident;
@@ -1300,52 +1309,51 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
                resident = GL_TRUE;
             *params = ENUM_TO_FLOAT(resident);
          }
-         break;
+         return;
       case GL_TEXTURE_PRIORITY:
          *params = obj->Priority;
-         break;
+         return;
       case GL_TEXTURE_MIN_LOD:
          *params = obj->MinLod;
-         break;
+         return;
       case GL_TEXTURE_MAX_LOD:
          *params = obj->MaxLod;
-         break;
+         return;
       case GL_TEXTURE_BASE_LEVEL:
          *params = (GLfloat) obj->BaseLevel;
-         break;
+         return;
       case GL_TEXTURE_MAX_LEVEL:
          *params = (GLfloat) obj->MaxLevel;
-         break;
+         return;
       case GL_TEXTURE_COMPARE_SGIX:
          if (ctx->Extensions.SGIX_shadow) {
             *params = (GLfloat) obj->CompareFlag;
-         }
-         else {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
             return;
          }
          break;
       case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
          if (ctx->Extensions.SGIX_shadow) {
             *params = (GLfloat) obj->CompareOperator;
-         }
-         else {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
             return;
          }
          break;
       case GL_SHADOW_AMBIENT_SGIX:
          if (ctx->Extensions.SGIX_shadow_ambient) {
             *params = CHAN_TO_FLOAT(obj->ShadowAmbient);
+            return;
          }
-         else {
-            _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)");
+         break;
+      case GL_GENERATE_MIPMAP_SGIS:
+         if (ctx->Extensions.SGIS_generate_mipmap) {
+            *params = (GLfloat) obj->GenerateMipmap;
             return;
          }
          break;
       default:
-         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
+         ; /* silence warnings */
    }
+   /* If we get here, pname was an unrecognized enum */
+   _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" );
 }
 
 
@@ -1366,19 +1374,19 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
    switch (pname) {
       case GL_TEXTURE_MAG_FILTER:
          *params = (GLint) obj->MagFilter;
-         break;
+         return;
       case GL_TEXTURE_MIN_FILTER:
          *params = (GLint) obj->MinFilter;
-         break;
+         return;
       case GL_TEXTURE_WRAP_S:
          *params = (GLint) obj->WrapS;
-         break;
+         return;
       case GL_TEXTURE_WRAP_T:
          *params = (GLint) obj->WrapT;
-         break;
+         return;
       case GL_TEXTURE_WRAP_R_EXT:
          *params = (GLint) obj->WrapR;
-         break;
+         return;
       case GL_TEXTURE_BORDER_COLOR:
          {
             GLfloat color[4];
@@ -1391,7 +1399,7 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
             params[2] = FLOAT_TO_INT( color[2] );
             params[3] = FLOAT_TO_INT( color[3] );
          }
-         break;
+         return;
       case GL_TEXTURE_RESIDENT:
          {
             GLboolean resident;
@@ -1401,37 +1409,31 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
                resident = GL_TRUE;
             *params = (GLint) resident;
          }
-         break;
+         return;
       case GL_TEXTURE_PRIORITY:
          *params = (GLint) obj->Priority;
-         break;
+         return;
       case GL_TEXTURE_MIN_LOD:
          *params = (GLint) obj->MinLod;
-         break;
+         return;
       case GL_TEXTURE_MAX_LOD:
          *params = (GLint) obj->MaxLod;
-         break;
+         return;
       case GL_TEXTURE_BASE_LEVEL:
          *params = obj->BaseLevel;
-         break;
+         return;
       case GL_TEXTURE_MAX_LEVEL:
          *params = obj->MaxLevel;
-         break;
+         return;
       case GL_TEXTURE_COMPARE_SGIX:
          if (ctx->Extensions.SGIX_shadow) {
             *params = (GLint) obj->CompareFlag;
-         }
-         else {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
             return;
          }
          break;
       case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
          if (ctx->Extensions.SGIX_shadow) {
             *params = (GLint) obj->CompareOperator;
-         }
-         else {
-            _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
             return;
          }
          break;
@@ -1439,15 +1441,20 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
          if (ctx->Extensions.SGIX_shadow_ambient) {
             /* XXX range? */
             *params = (GLint) CHAN_TO_FLOAT(obj->ShadowAmbient);
+            return;
          }
-         else {
-            _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)");
+         break;
+      case GL_GENERATE_MIPMAP_SGIS:
+         if (ctx->Extensions.SGIS_generate_mipmap) {
+            *params = (GLint) obj->GenerateMipmap;
             return;
          }
          break;
       default:
-         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
+         ; /* silence warnings */
    }
+   /* If we get here, pname was an unrecognized enum */
+   _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" );
 }
 
 
index bfa23018cf7e71f14c5db961ae3c3b40dd523e3e..e3a4b108271708a91d7b56d6dbca82ef71769542 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: texstore.c,v 1.24 2001/04/20 16:46:04 brianp Exp $ */
+/* $Id: texstore.c,v 1.25 2001/05/21 16:41:03 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -642,6 +642,12 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
                            0, /* dstRowStride */
                            0, /* dstImageStride */
                            format, type, pixels, packing);
+
+   /* GL_SGIS_generate_mipmap */
+   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+      _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+                            texObj);
+   }
 }
 
 
@@ -674,6 +680,7 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
    texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
                                           internalFormat, format, type);
    assert(texImage->TexFormat);
+   texImage->FetchTexel = texImage->TexFormat->FetchTexel2D;
 
    texelBytes = texImage->TexFormat->TexelBytes;
 
@@ -691,6 +698,12 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
                            texImage->Width * texelBytes,
                            0, /* dstImageStride */
                            format, type, pixels, packing);
+
+   /* GL_SGIS_generate_mipmap */
+   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+      _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+                            texObj);
+   }
 }
 
 
@@ -735,6 +748,12 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
                            texImage->Width * texelBytes,
                            texImage->Width * texImage->Height * texelBytes,
                            format, type, pixels, packing);
+
+   /* GL_SGIS_generate_mipmap */
+   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+      _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+                            texObj);
+   }
 }
 
 
@@ -759,6 +778,12 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
                            0, /* dstRowStride */
                            0, /* dstImageStride */
                            format, type, pixels, packing);
+
+   /* GL_SGIS_generate_mipmap */
+   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+      _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+                            texObj);
+   }
 }
 
 
@@ -782,6 +807,12 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
                            texImage->Width * texImage->TexFormat->TexelBytes,
                            0, /* dstImageStride */
                            format, type, pixels, packing);
+
+   /* GL_SGIS_generate_mipmap */
+   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+      _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+                            texObj);
+   }
 }
 
 
@@ -806,6 +837,11 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
                            texImage->Width * texelBytes,
                            texImage->Width * texImage->Height * texelBytes,
                            format, type, pixels, packing);
+   /* GL_SGIS_generate_mipmap */
+   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+      _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+                            texObj);
+   }
 }
 
 
@@ -898,3 +934,375 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
 
    return GL_TRUE;
 }
+
+
+
+/*
+ * Average together two rows of a source image to produce a single new
+ * row in the dest image.  It's legal for the two source rows to point
+ * to the same data.  The source rows are to be twice as long as the
+ * dest row.
+ */
+static void
+do_row(const struct gl_texture_format *format, GLint dstWidth,
+       const GLvoid *srcRowA, const GLvoid *srcRowB, GLvoid *dstRow)
+{
+   switch (format->MesaFormat) {
+   case MESA_FORMAT_RGBA:
+      {
+         GLuint i, j;
+         const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA;
+         const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB;
+         GLchan (*dst)[4] = (GLchan (*)[4]) dstRow;
+         for (i = j = 0; i < dstWidth; i++, j+=2) {
+            dst[i][0] = (rowA[j][0] + rowA[j+1][0] +
+                         rowB[j][0] + rowB[j+1][0]) >> 2;
+            dst[i][1] = (rowA[j][1] + rowA[j+1][1] +
+                         rowB[j][1] + rowB[j+1][1]) >> 2;
+            dst[i][2] = (rowA[j][2] + rowA[j+1][2] +
+                         rowB[j][2] + rowB[j+1][2]) >> 2;
+            dst[i][3] = (rowA[j][3] + rowA[j+1][3] +
+                         rowB[j][3] + rowB[j+1][3]) >> 2;
+         }
+      }
+      return;
+   case MESA_FORMAT_RGB:
+      {
+         GLuint i, j;
+         const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA;
+         const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB;
+         GLchan (*dst)[3] = (GLchan (*)[3]) dstRow;
+         for (i = j = 0; i < dstWidth; i++, j+=2) {
+            dst[i][0] = (rowA[j][0] + rowA[j+1][0] +
+                         rowB[j][0] + rowB[j+1][0]) >> 2;
+            dst[i][1] = (rowA[j][1] + rowA[j+1][1] +
+                         rowB[j][1] + rowB[j+1][1]) >> 2;
+            dst[i][2] = (rowA[j][2] + rowA[j+1][2] +
+                         rowB[j][2] + rowB[j+1][2]) >> 2;
+         }
+      }
+      return;
+   case MESA_FORMAT_ALPHA:
+   case MESA_FORMAT_LUMINANCE:
+   case MESA_FORMAT_INTENSITY:
+   case MESA_FORMAT_COLOR_INDEX:
+      {
+         GLuint i, j;
+         const GLchan *rowA = (const GLchan *) srcRowA;
+         const GLchan *rowB = (const GLchan *) srcRowB;
+         GLchan *dst = (GLchan *) dstRow;
+         for (i = j = 0; i < dstWidth; i++, j+=2) {
+            dst[i] = (rowA[j] + rowA[j+1] + rowB[j] + rowB[j+1]) >> 2;
+         }
+      }
+      return;
+   case MESA_FORMAT_LUMINANCE_ALPHA:
+      {
+         GLuint i, j;
+         const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA;
+         const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB;
+         GLchan (*dst)[2] = (GLchan (*)[2]) dstRow;
+         for (i = j = 0; i < dstWidth; i++, j+=2) {
+            dst[i][0] = (rowA[j][0] + rowA[j+1][0] +
+                         rowB[j][0] + rowB[j+1][0]) >> 2;
+            dst[i][1] = (rowA[j][1] + rowA[j+1][1] +
+                         rowB[j][1] + rowB[j+1][1]) >> 2;
+         }
+      }
+      return;
+   case MESA_FORMAT_DEPTH_COMPONENT:
+
+   /* XXX do hardware texture formats */
+
+   default:
+      _mesa_problem(NULL, "bad format in do_row()");
+   }
+}
+
+
+
+
+static void
+make_1d_mipmap(const struct gl_texture_format *format, GLint border,
+               GLint srcWidth, const GLubyte *srcPtr,
+               GLint dstWidth, GLubyte *dstPtr)
+{
+   const GLint bpt = format->TexelBytes;
+   const GLubyte *src;
+   GLubyte *dst;
+
+   /* skip the border pixel, if any */
+   src = srcPtr + border * bpt;
+   dst = dstPtr + border * bpt;
+
+   /* we just duplicate the input row, kind of hack, saves code */
+   do_row(format, dstWidth - 2 * border, src, src, dst);
+
+   if (border) {
+      /* copy left-most pixel from source */
+      MEMCPY(dstPtr, srcPtr, bpt);
+      /* copy right-most pixel from source */
+      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
+             srcPtr + (srcWidth - 1) * bpt,
+             bpt);
+   }
+}
+
+
+static void
+make_2d_mipmap(const struct gl_texture_format *format, GLint border,
+               GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
+               GLint dstWidth, GLint dstHeight, GLubyte *dstPtr)
+{
+   const GLint bpt = format->TexelBytes;
+   const GLint srcRowStride = bpt * srcWidth;
+   const GLint dstRowStride = bpt * dstWidth;
+   const GLubyte *srcA, *srcB;
+   GLubyte *dst;
+   GLint row;
+
+   /* Compute src and dst pointers, skipping any border */
+   srcA = srcPtr + border * ((srcWidth + 1) * bpt);
+   if (srcHeight > 1)
+      srcB = srcA + srcRowStride;
+   else
+      srcB = srcA;
+   dst = dstPtr + border * ((dstWidth + 1) * bpt);
+
+   for (row = 0; row < dstHeight - 2 * border; row++) {
+      do_row(format, dstWidth - 2 * border, srcA, srcB, dst);
+      srcA += 2 * srcRowStride;
+      srcB += 2 * srcRowStride;
+      dst += dstRowStride;
+   }
+
+   if (border > 0) {
+      /* fill in dest border */
+      /* lower-left border pixel */
+      MEMCPY(dstPtr, srcPtr, bpt);
+      /* lower-right border pixel */
+      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
+             srcPtr + (srcWidth - 1) * bpt, bpt);
+      /* upper-left border pixel */
+      MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,
+             srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
+      /* upper-right border pixel */
+      MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,
+             srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
+      /* lower border */
+      do_row(format, dstWidth - 2 * border,
+             srcPtr + bpt, srcPtr + bpt, dstPtr + bpt);
+      /* upper border */
+      do_row(format, dstWidth - 2 * border,
+             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
+             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
+             dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
+      /* left and right borders */
+      for (row = 0; row < dstHeight - 2 * border; row += 2) {
+         GLubyte tempPixel[32];
+         GLint srcOffset;
+         srcOffset = (srcWidth * (row * 2 + 1)) * bpt;
+         MEMCPY(tempPixel, srcPtr + srcOffset, bpt);
+         srcOffset = (srcWidth * (row * 2 + 2)) * bpt;
+         MEMCPY(tempPixel + bpt, srcPtr + srcOffset, bpt);
+         do_row(format, 1, tempPixel, tempPixel,
+                dstPtr + (dstWidth * row + 1) * bpt);
+         srcOffset = (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt;
+         MEMCPY(tempPixel, srcPtr + srcOffset, bpt);
+         srcOffset = (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt;
+         MEMCPY(tempPixel, srcPtr + srcOffset, bpt);
+         do_row(format, 1, tempPixel, tempPixel,
+               dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);
+      }
+   }
+}
+
+
+static void
+make_3d_mipmap(const struct gl_texture_format *format, GLint border,
+               GLint srcWidth, GLint srcHeight, GLint srcDepth,
+               const GLubyte *srcPtr,
+               GLint dstWidth, GLint dstHeight, GLint dstDepth,
+               GLubyte *dstPtr)
+{
+   GLvoid *tmpRowA = MALLOC(dstWidth * format->TexelBytes);
+   GLvoid *tmpRowB = MALLOC(dstWidth * format->TexelBytes);
+   const GLubyte *srcA, *srcB, *srcC, *srcD;
+   GLint img, row;
+
+   if (!tmpRowA || !tmpRowB) {
+      if (tmpRowA)
+         FREE(tmpRowA);
+      return;
+   }
+
+   /*
+    * XXX lots of work to do here yet
+    */
+
+   for (img = 0; img < dstDepth - 2 * border; img++) {
+
+      for (row = 0; row < dstHeight - 2 * border; row++) {
+         do_row(format, dstWidth - 2 * border, srcA, srcB, tmpRowA);
+         do_row(format, dstWidth - 2 * border, srcC, srcD, tmpRowB);
+
+
+      }
+   }
+
+   FREE(tmpRowA);
+   FREE(tmpRowB);
+}
+
+
+/*
+ * For GL_SGIX_generate_mipmap:
+ * Generate a complete set of mipmaps from texObj's base-level image.
+ * Stop at texObj's MaxLevel or when we get to the 1x1 texture.
+ */
+void
+_mesa_generate_mipmap(GLcontext *ctx,
+                      const struct gl_texture_unit *texUnit,
+                      struct gl_texture_object *texObj)
+{
+   const GLenum targets1D[] = { GL_TEXTURE_1D, 0 };
+   const GLenum targets2D[] = { GL_TEXTURE_2D, 0 };
+   const GLenum targets3D[] = { GL_TEXTURE_3D, 0 };
+   const GLenum targetsCube[] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
+                                  GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
+                                  GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
+                                  GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
+                                  GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
+                                  GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
+                                  0 };
+   const GLenum *targets;
+   GLuint level;
+
+   ASSERT(texObj);
+   ASSERT(texObj->Image[texObj->BaseLevel]);
+
+   switch (texObj->Dimensions) {
+   case 1:
+      targets = targets1D;
+      break;
+   case 2:
+      targets = targets2D;
+      break;
+   case 3:
+      targets = targets3D;
+      break;
+   case 6:
+      targets = targetsCube;
+      break;
+   default:
+      _mesa_problem(ctx,
+                    "Bad texture object dimension in _mesa_generate_mipmaps");
+      return;
+   }
+
+   for (level = texObj->BaseLevel; level < texObj->MaxLevel; level++) {
+      /* generate level+1 from level */
+      const struct gl_texture_image *srcImage;
+      struct gl_texture_image *dstImage;
+      GLint srcWidth, srcHeight, srcDepth;
+      GLint dstWidth, dstHeight, dstDepth;
+      GLint border, bytesPerTexel;
+      GLint t;
+
+      srcImage = texObj->Image[level];
+      ASSERT(srcImage);
+      srcWidth = srcImage->Width;
+      srcHeight = srcImage->Height;
+      srcDepth = srcImage->Depth;
+      border = srcImage->Border;
+      bytesPerTexel = srcImage->TexFormat->TexelBytes;
+
+      /* compute next (level+1) image size */
+      if (srcWidth - 2 * border > 1) {
+         dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;
+      }
+      else {
+         dstWidth = srcWidth; /* can't go smaller */
+      }
+      if (srcHeight - 2 * border > 1) {
+         dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
+      }
+      else {
+         dstHeight = srcHeight; /* can't go smaller */
+      }
+      if (srcDepth - 2 * border > 1) {
+         dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
+      }
+      else {
+         dstDepth = srcDepth; /* can't go smaller */
+      }
+
+      if (dstWidth == srcWidth &&
+          dstHeight == srcHeight &&
+          dstDepth == srcDepth) {
+         /* all done */
+         return;
+      }
+
+      /* Need this loop just because of cubemaps */
+      for (t = 0; targets[t]; t++) {
+         ASSERT(t < 6);
+
+         dstImage = _mesa_select_tex_image(ctx, texUnit, targets[t], level+1);
+         if (!dstImage) {
+            dstImage = _mesa_alloc_texture_image();
+            if (!dstImage) {
+               _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
+               return;
+            }
+            _mesa_set_tex_image(texObj, targets[t], level + 1, dstImage);
+         }
+
+         /* Free old image data */
+         if (dstImage->Data)
+            FREE(dstImage->Data);
+
+         /* initialize new image */
+         _mesa_init_teximage_fields(ctx, dstImage, dstWidth, dstHeight,
+                                    dstDepth, border, srcImage->Format);
+         dstImage->DriverData = NULL;
+         dstImage->TexFormat = srcImage->TexFormat;
+         dstImage->FetchTexel = srcImage->FetchTexel;
+
+         ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0);
+
+         /* alloc new image buffer */
+         dstImage->Data = MALLOC(dstWidth * dstHeight * dstDepth
+                                 * bytesPerTexel);
+         if (!dstImage->Data) {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
+            return;
+         }
+
+         /*
+          * We use simple 2x2 averaging to compute the next mipmap level.
+          */
+         switch (texObj->Dimensions) {
+         case 1:
+            make_1d_mipmap(srcImage->TexFormat, border,
+               srcWidth, (const GLubyte *) srcImage->Data,
+               dstWidth, (GLubyte *) dstImage->Data);
+            break;
+         case 2:
+         case 6:
+            make_2d_mipmap(srcImage->TexFormat, border,
+               srcWidth, srcHeight, (const GLubyte *) srcImage->Data,
+               dstWidth, dstHeight, (GLubyte *) dstImage->Data);
+            break;
+         case 3:
+            make_3d_mipmap(srcImage->TexFormat, border,
+               srcWidth, srcHeight, srcDepth, (const GLubyte *) srcImage->Data,
+               dstWidth, dstHeight, dstDepth, (GLubyte *) dstImage->Data);
+            break;
+         default:
+            _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps");
+            return;
+         }
+      } /* loop over tex image targets */
+   } /* loop over tex levels */
+}
index ba8683416061059c5b1bce3ed1487dda310992dd..4d62a015f0311b8ae70372ddeb8474ee054e31d8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: texstore.h,v 1.7 2001/04/20 16:46:04 brianp Exp $ */
+/* $Id: texstore.h,v 1.8 2001/05/21 16:41:04 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -141,4 +141,9 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
                          GLint width, GLint height, GLint depth, GLint border);
 
 
+extern void
+_mesa_generate_mipmap(GLcontext *ctx,
+                      const struct gl_texture_unit *texUnit,
+                      struct gl_texture_object *texObj);
+
 #endif
index b7ca0abf3589ac172080fc34e54189bd0eb0c59b..e1adeded7fc98e028df81e79b1e28866ba501adf 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_texstore.c,v 1.4 2001/05/03 22:13:32 brianp Exp $ */
+/* $Id: s_texstore.c,v 1.5 2001/05/21 16:41:04 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -46,6 +46,7 @@
 #include "mem.h"
 #include "texformat.h"
 #include "teximage.h"
+#include "texstore.h"
 
 #include "s_context.h"
 #include "s_depth.h"
@@ -190,6 +191,11 @@ _swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level,
                                 &_mesa_native_packing, texObj, texImage);
       FREE(image);
    }
+
+   /* GL_SGIS_generate_mipmap */
+   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+      _mesa_generate_mipmap(ctx, texUnit, texObj);
+   }
 }
 
 
@@ -244,6 +250,11 @@ _swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level,
                                 &_mesa_native_packing, texObj, texImage);
       FREE(image);
    }
+
+   /* GL_SGIS_generate_mipmap */
+   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+      _mesa_generate_mipmap(ctx, texUnit, texObj);
+   }
 }
 
 
@@ -311,6 +322,11 @@ _swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
                                    &_mesa_native_packing, texObj, texImage);
       FREE(image);
    }
+
+   /* GL_SGIS_generate_mipmap */
+   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+      _mesa_generate_mipmap(ctx, texUnit, texObj);
+   }
 }
 
 
@@ -382,6 +398,11 @@ _swrast_copy_texsubimage2d( GLcontext *ctx,
                                    &_mesa_native_packing, texObj, texImage);
       FREE(image);
    }
+
+   /* GL_SGIS_generate_mipmap */
+   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+      _mesa_generate_mipmap(ctx, texUnit, texObj);
+   }
 }
 
 
@@ -452,4 +473,9 @@ _swrast_copy_texsubimage3d( GLcontext *ctx,
                                    &_mesa_native_packing, texObj, texImage);
       FREE(image);
    }
+
+   /* GL_SGIS_generate_mipmap */
+   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+      _mesa_generate_mipmap(ctx, texUnit, texObj);
+   }
 }