fixed pointer arithmetic error in glCopyPixels
[mesa.git] / src / mesa / main / texobj.c
index 9ebbb1415be02f46255ff076341d4ba2076fde4c..39f65940b5d608b927c7205a2294a01f897987d7 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: texobj.c,v 1.46 2001/03/28 21:31:54 brianp Exp $ */
+/* $Id: texobj.c,v 1.52 2002/02/15 16:32:06 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  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"),
@@ -80,9 +80,12 @@ _mesa_alloc_texture_object( struct gl_shared_state *shared,
       obj->BaseLevel = 0;
       obj->MaxLevel = 1000;
       obj->MaxAnisotropy = 1.0;
-      obj->CompareFlag = GL_FALSE;
-      obj->CompareOperator = GL_TEXTURE_LEQUAL_R_SGIX;
-      obj->ShadowAmbient = 0;
+      obj->CompareFlag = GL_FALSE;                      /* SGIX_shadow */
+      obj->CompareOperator = GL_TEXTURE_LEQUAL_R_SGIX;  /* SGIX_shadow */
+      obj->CompareMode = GL_LUMINANCE;    /* ARB_shadow */
+      obj->CompareFunc = GL_LEQUAL;       /* ARB_shadow */
+      obj->DepthMode = GL_LUMINANCE;      /* ARB_depth_texture */
+      obj->ShadowAmbient = 0;             /* ARB/SGIX_shadow_ambient */
       _mesa_init_colortable(&obj->Palette);
 
       /* insert into linked list */
@@ -181,7 +184,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
                                 struct gl_texture_object *t )
 {
    const GLint baseLevel = t->BaseLevel;
-   GLint maxLog2 = 0;
+   GLint maxLog2 = 0, maxLevels = 0;
 
    t->Complete = GL_TRUE;  /* be optimistic */
 
@@ -195,20 +198,30 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
    /* Compute _MaxLevel */
    if (t->Dimensions == 1) {
       maxLog2 = t->Image[baseLevel]->WidthLog2;
+      maxLevels = ctx->Const.MaxTextureLevels;
    }
    else if (t->Dimensions == 2 || t->Dimensions == 6) {
       maxLog2 = MAX2(t->Image[baseLevel]->WidthLog2,
                      t->Image[baseLevel]->HeightLog2);
+      maxLevels = (t->Dimensions == 2) ?
+         ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels;
    }
    else if (t->Dimensions == 3) {
       GLint max = MAX2(t->Image[baseLevel]->WidthLog2,
                        t->Image[baseLevel]->HeightLog2);
       maxLog2 = MAX2(max, (GLint)(t->Image[baseLevel]->DepthLog2));
+      maxLevels = ctx->Const.Max3DTextureLevels;
+   }
+   else {
+      _mesa_problem(ctx, "Bad t->Dimension in _mesa_test_texobj_completeness");
+      return;
    }
 
+   ASSERT(maxLevels > 0);
+
    t->_MaxLevel = baseLevel + maxLog2;
    t->_MaxLevel = MIN2(t->_MaxLevel, t->MaxLevel);
-   t->_MaxLevel = MIN2(t->_MaxLevel, ctx->Const.MaxTextureLevels - 1);
+   t->_MaxLevel = MIN2(t->_MaxLevel, maxLevels - 1);
 
    /* Compute _MaxLambda = q - b (see the 1.2 spec) used during mipmapping */
    t->_MaxLambda = (GLfloat) (t->_MaxLevel - t->BaseLevel);
@@ -272,7 +285,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
       if (t->Dimensions == 1) {
          /* Test 1-D mipmaps */
          GLuint width = t->Image[baseLevel]->Width2;
-         for (i = baseLevel + 1; i < ctx->Const.MaxTextureLevels; i++) {
+         for (i = baseLevel + 1; i < maxLevels; i++) {
             if (width > 1) {
                width /= 2;
             }
@@ -297,7 +310,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
          /* Test 2-D mipmaps */
          GLuint width = t->Image[baseLevel]->Width2;
          GLuint height = t->Image[baseLevel]->Height2;
-         for (i = baseLevel + 1; i < ctx->Const.MaxTextureLevels; i++) {
+         for (i = baseLevel + 1; i < maxLevels; i++) {
             if (width > 1) {
                width /= 2;
             }
@@ -331,7 +344,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
          GLuint width = t->Image[baseLevel]->Width2;
          GLuint height = t->Image[baseLevel]->Height2;
          GLuint depth = t->Image[baseLevel]->Depth2;
-        for (i = baseLevel + 1; i < ctx->Const.MaxTextureLevels; i++) {
+        for (i = baseLevel + 1; i < maxLevels; i++) {
             if (width > 1) {
                width /= 2;
             }
@@ -347,6 +360,11 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
                   t->Complete = GL_FALSE;
                   return;
                }
+               if (t->Image[i]->Format == GL_DEPTH_COMPONENT) {
+                  t->Complete = GL_FALSE;
+                  incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
+                  return;
+               }
                if (t->Image[i]->Width2 != width) {
                   t->Complete = GL_FALSE;
                   incomplete(t, "3D Image[i] bad width");
@@ -372,7 +390,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
          /* make sure 6 cube faces are consistant */
          GLuint width = t->Image[baseLevel]->Width2;
          GLuint height = t->Image[baseLevel]->Height2;
-        for (i = baseLevel + 1; i < ctx->Const.MaxTextureLevels; i++) {
+        for (i = baseLevel + 1; i < maxLevels; i++) {
             if (width > 1) {
                width /= 2;
             }
@@ -380,6 +398,12 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
                height /= 2;
             }
             if (i >= minLevel && i <= maxLevel) {
+               /* Don't support GL_DEPTH_COMPONENT for cube maps */
+               if (t->Image[i]->Format == GL_DEPTH_COMPONENT) {
+                  t->Complete = GL_FALSE;
+                  incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
+                  return;
+               }
                /* check that we have images defined */
                if (!t->Image[i] || !t->NegX[i] ||
                    !t->PosY[i]  || !t->NegY[i] ||
@@ -485,26 +509,36 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *texName)
                if (delObj == unit->Current1D) {
                   unit->Current1D = ctx->Shared->Default1D;
                   ctx->Shared->Default1D->RefCount++;
+                  if (delObj == unit->_Current)
+                     unit->_Current = unit->Current1D;
                }
                else if (delObj == unit->Current2D) {
                   unit->Current2D = ctx->Shared->Default2D;
                   ctx->Shared->Default2D->RefCount++;
+                  if (delObj == unit->_Current)
+                     unit->_Current = unit->Current2D;
                }
                else if (delObj == unit->Current3D) {
                   unit->Current3D = ctx->Shared->Default3D;
                   ctx->Shared->Default3D->RefCount++;
+                  if (delObj == unit->_Current)
+                     unit->_Current = unit->Current3D;
                }
                else if (delObj == unit->CurrentCubeMap) {
                   unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
                   ctx->Shared->DefaultCubeMap->RefCount++;
+                  if (delObj == unit->_Current)
+                     unit->_Current = unit->CurrentCubeMap;
                }
             }
             ctx->NewState |= _NEW_TEXTURE;
 
             /* Decrement reference count and delete if zero */
             delObj->RefCount--;
-            ASSERT( delObj->RefCount >= 0 );
+            ASSERT(delObj->RefCount >= 0);
+
             if (delObj->RefCount == 0) {
+               ASSERT(delObj->Name != 0);
                if (ctx->Driver.DeleteTexture)
                   (*ctx->Driver.DeleteTexture)( ctx, delObj );
                _mesa_free_texture_object(ctx->Shared, delObj);
@@ -592,7 +626,8 @@ _mesa_BindTexture( GLenum target, GLuint texName )
          /* error checking */
          if (newTexObj->Dimensions > 0 && newTexObj->Dimensions != targetDim) {
             /* the named texture object's dimensions don't match the target */
-            _mesa_error( ctx, GL_INVALID_OPERATION, "glBindTexture" );
+            _mesa_error( ctx, GL_INVALID_OPERATION,
+                         "glBindTexture(wrong dimensionality)" );
             return;
          }
       }
@@ -610,7 +645,6 @@ _mesa_BindTexture( GLenum target, GLuint texName )
 
    newTexObj->RefCount++;
 
-
    /* do the actual binding, but first flush outstanding vertices:
     */
    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
@@ -636,15 +670,14 @@ _mesa_BindTexture( GLenum target, GLuint texName )
    if (ctx->Driver.BindTexture)
       (*ctx->Driver.BindTexture)( ctx, target, newTexObj );
 
-   if (oldTexObj->Name > 0) {
-      /* never delete default (id=0) texture objects */
-      oldTexObj->RefCount--;
-      if (oldTexObj->RefCount <= 0) {
-         if (ctx->Driver.DeleteTexture) {
-           (*ctx->Driver.DeleteTexture)( ctx, oldTexObj );
-        }
-         _mesa_free_texture_object(ctx->Shared, oldTexObj);
+   oldTexObj->RefCount--;
+   assert(oldTexObj->RefCount >= 0);
+   if (oldTexObj->RefCount == 0) {
+      assert(oldTexObj->Name != 0);
+      if (ctx->Driver.DeleteTexture) {
+         (*ctx->Driver.DeleteTexture)( ctx, oldTexObj );
       }
+      _mesa_free_texture_object(ctx->Shared, oldTexObj);
    }
 }