mesa: add #define FEATURE_ARB_pixel_buffer_object
[mesa.git] / src / mesa / main / texobj.c
index 24d8110b002ce638288c6fe88d194e9244125479..b63f747fe8d3936cd2b5e40e246ac77e524d3fcb 100644 (file)
  */
 
 
-#include "glheader.h"
+#include "mfeatures.h"
+#if FEATURE_colortable
 #include "colortab.h"
+#endif
 #include "context.h"
 #include "enums.h"
 #include "fbobject.h"
@@ -40,6 +42,8 @@
 #include "texstate.h"
 #include "texobj.h"
 #include "mtypes.h"
+#include "shader/prog_instruction.h"
+
 
 
 /**********************************************************************/
@@ -130,12 +134,43 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj,
    obj->BaseLevel = 0;
    obj->MaxLevel = 1000;
    obj->MaxAnisotropy = 1.0;
-   obj->CompareFlag = GL_FALSE;                      /* SGIX_shadow */
-   obj->CompareOperator = GL_TEXTURE_LEQUAL_R_SGIX;  /* SGIX_shadow */
    obj->CompareMode = GL_NONE;         /* ARB_shadow */
    obj->CompareFunc = GL_LEQUAL;       /* ARB_shadow */
+   obj->CompareFailValue = 0.0F;       /* ARB_shadow_ambient */
    obj->DepthMode = GL_LUMINANCE;      /* ARB_depth_texture */
-   obj->ShadowAmbient = 0.0F;          /* ARB/SGIX_shadow_ambient */
+   obj->Swizzle[0] = GL_RED;
+   obj->Swizzle[1] = GL_GREEN;
+   obj->Swizzle[2] = GL_BLUE;
+   obj->Swizzle[3] = GL_ALPHA;
+   obj->_Swizzle = SWIZZLE_NOOP;
+}
+
+
+/**
+ * Some texture initialization can't be finished until we know which
+ * target it's getting bound to (GL_TEXTURE_1D/2D/etc).
+ */
+static void
+finish_texture_init(GLcontext *ctx, GLenum target,
+                    struct gl_texture_object *obj)
+{
+   assert(obj->Target == 0);
+
+   if (target == GL_TEXTURE_RECTANGLE_NV) {
+      /* have to init wrap and filter state here - kind of klunky */
+      obj->WrapS = GL_CLAMP_TO_EDGE;
+      obj->WrapT = GL_CLAMP_TO_EDGE;
+      obj->WrapR = GL_CLAMP_TO_EDGE;
+      obj->MinFilter = GL_LINEAR;
+      if (ctx->Driver.TexParameter) {
+         static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};
+         static const GLfloat fparam_filter[1] = {(GLfloat) GL_LINEAR};
+         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_S, fparam_wrap);
+         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_T, fparam_wrap);
+         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_R, fparam_wrap);
+         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_MIN_FILTER, fparam_filter);
+      }
+   }
 }
 
 
@@ -145,7 +180,7 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj,
  * Called via ctx->Driver.DeleteTexture() if not overriden by a driver.
  *
  * \param shared the shared GL state to which the object belongs.
- * \param texOjb the texture object to delete.
+ * \param texObj the texture object to delete.
  */
 void
 _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
@@ -159,7 +194,9 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
     */
    texObj->Target = 0x99;
 
+#if FEATURE_colortable
    _mesa_free_colortable_data(&texObj->Palette);
+#endif
 
    /* free the texture images */
    for (face = 0; face < 6; face++) {
@@ -209,17 +246,17 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
    dest->BaseLevel = src->BaseLevel;
    dest->MaxLevel = src->MaxLevel;
    dest->MaxAnisotropy = src->MaxAnisotropy;
-   dest->CompareFlag = src->CompareFlag;
-   dest->CompareOperator = src->CompareOperator;
-   dest->ShadowAmbient = src->ShadowAmbient;
    dest->CompareMode = src->CompareMode;
    dest->CompareFunc = src->CompareFunc;
+   dest->CompareFailValue = src->CompareFailValue;
    dest->DepthMode = src->DepthMode;
    dest->_MaxLevel = src->_MaxLevel;
    dest->_MaxLambda = src->_MaxLambda;
    dest->GenerateMipmap = src->GenerateMipmap;
    dest->Palette = src->Palette;
    dest->_Complete = src->_Complete;
+   COPY_4V(dest->Swizzle, src->Swizzle);
+   dest->_Swizzle = src->_Swizzle;
 }
 
 
@@ -351,11 +388,21 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
 
    t->_Complete = GL_TRUE;  /* be optimistic */
 
+   /* Detect cases where the application set the base level to an invalid
+    * value.
+    */
+   if ((baseLevel < 0) || (baseLevel > MAX_TEXTURE_LEVELS)) {
+      char s[100];
+      _mesa_sprintf(s, "base level = %d is invalid", baseLevel);
+      incomplete(t, s);
+      t->_Complete = GL_FALSE;
+      return;
+   }
+
    /* Always need the base level image */
    if (!t->Image[0][baseLevel]) {
       char s[100];
-      _mesa_sprintf(s, "obj %p (%d) Image[baseLevel=%d] == NULL",
-              (void *) t, t->Name, baseLevel);
+      _mesa_sprintf(s, "Image[baseLevel=%d] == NULL", baseLevel);
       incomplete(t, s);
       t->_Complete = GL_FALSE;
       return;
@@ -712,30 +759,17 @@ unbind_texobj_from_fbo(GLcontext *ctx, struct gl_texture_object *texObj)
 static void
 unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj)
 {
-   GLuint u;
+   GLuint u, tex;
 
    for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
       struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
-      if (texObj == unit->Current1D) {
-         _mesa_reference_texobj(&unit->Current1D, ctx->Shared->Default1D);
-      }
-      else if (texObj == unit->Current2D) {
-         _mesa_reference_texobj(&unit->Current2D, ctx->Shared->Default2D);
-      }
-      else if (texObj == unit->Current3D) {
-         _mesa_reference_texobj(&unit->Current3D, ctx->Shared->Default3D);
-      }
-      else if (texObj == unit->CurrentCubeMap) {
-         _mesa_reference_texobj(&unit->CurrentCubeMap, ctx->Shared->DefaultCubeMap);
-      }
-      else if (texObj == unit->CurrentRect) {
-         _mesa_reference_texobj(&unit->CurrentRect, ctx->Shared->DefaultRect);
-      }
-      else if (texObj == unit->Current1DArray) {
-         _mesa_reference_texobj(&unit->Current1DArray, ctx->Shared->Default1DArray);
-      }
-      else if (texObj == unit->Current2DArray) {
-         _mesa_reference_texobj(&unit->Current2DArray, ctx->Shared->Default2DArray);
+      for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
+         if (texObj == unit->CurrentTex[tex]) {
+            _mesa_reference_texobj(&unit->CurrentTex[tex],
+                                   ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]);
+            ASSERT(unit->CurrentTex[tex]);
+            break;
+         }
       }
    }
 }
@@ -805,6 +839,35 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
 }
 
 
+/**
+ * Convert a GL texture target enum such as GL_TEXTURE_2D or GL_TEXTURE_3D
+ * into the corresponding Mesa texture target index.
+ * Return -1 if target is invalid.
+ */
+static GLint
+target_enum_to_index(GLenum target)
+{
+   switch (target) {
+   case GL_TEXTURE_1D:
+      return TEXTURE_1D_INDEX;
+   case GL_TEXTURE_2D:
+      return TEXTURE_2D_INDEX;
+   case GL_TEXTURE_3D:
+      return TEXTURE_3D_INDEX;
+   case GL_TEXTURE_CUBE_MAP_ARB:
+      return TEXTURE_CUBE_INDEX;
+   case GL_TEXTURE_RECTANGLE_NV:
+      return TEXTURE_RECT_INDEX;
+   case GL_TEXTURE_1D_ARRAY_EXT:
+      return TEXTURE_1D_ARRAY_INDEX;
+   case GL_TEXTURE_2D_ARRAY_EXT:
+      return TEXTURE_2D_ARRAY_INDEX;
+   default:
+      return -1;
+   }
+}
+
+
 /**
  * Bind a named texture to a texturing target.
  * 
@@ -826,44 +889,27 @@ _mesa_BindTexture( GLenum target, GLuint texName )
    GET_CURRENT_CONTEXT(ctx);
    const GLuint unit = ctx->Texture.CurrentUnit;
    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
-   struct gl_texture_object *newTexObj = NULL;
+   struct gl_texture_object *newTexObj = NULL, *defaultTexObj = NULL;
+   GLint targetIndex;
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
       _mesa_debug(ctx, "glBindTexture %s %d\n",
                   _mesa_lookup_enum_by_nr(target), (GLint) texName);
 
+   targetIndex = target_enum_to_index(target);
+   if (targetIndex < 0) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glBindTexture(target)");
+      return;
+   }
+   assert(targetIndex < NUM_TEXTURE_TARGETS);
+   defaultTexObj = ctx->Shared->DefaultTex[targetIndex];
+
    /*
     * Get pointer to new texture object (newTexObj)
     */
    if (texName == 0) {
-      /* newTexObj = a default texture object */
-      switch (target) {
-         case GL_TEXTURE_1D:
-            newTexObj = ctx->Shared->Default1D;
-            break;
-         case GL_TEXTURE_2D:
-            newTexObj = ctx->Shared->Default2D;
-            break;
-         case GL_TEXTURE_3D:
-            newTexObj = ctx->Shared->Default3D;
-            break;
-         case GL_TEXTURE_CUBE_MAP_ARB:
-            newTexObj = ctx->Shared->DefaultCubeMap;
-            break;
-         case GL_TEXTURE_RECTANGLE_NV:
-            newTexObj = ctx->Shared->DefaultRect;
-            break;
-         case GL_TEXTURE_1D_ARRAY_EXT:
-            newTexObj = ctx->Shared->Default1DArray;
-            break;
-         case GL_TEXTURE_2D_ARRAY_EXT:
-            newTexObj = ctx->Shared->Default2DArray;
-            break;
-         default:
-            _mesa_error(ctx, GL_INVALID_ENUM, "glBindTexture(target)");
-            return;
-      }
+      newTexObj = defaultTexObj;
    }
    else {
       /* non-default texture object */
@@ -871,25 +917,13 @@ _mesa_BindTexture( GLenum target, GLuint texName )
       if (newTexObj) {
          /* error checking */
          if (newTexObj->Target != 0 && newTexObj->Target != target) {
-            /* the named texture object's dimensions don't match the target */
+            /* the named texture object's target doesn't match the given target */
             _mesa_error( ctx, GL_INVALID_OPERATION,
-                         "glBindTexture(wrong dimensionality)" );
+                         "glBindTexture(target mismatch)" );
             return;
          }
-         if (newTexObj->Target == 0 && target == GL_TEXTURE_RECTANGLE_NV) {
-            /* have to init wrap and filter state here - kind of klunky */
-            newTexObj->WrapS = GL_CLAMP_TO_EDGE;
-            newTexObj->WrapT = GL_CLAMP_TO_EDGE;
-            newTexObj->WrapR = GL_CLAMP_TO_EDGE;
-            newTexObj->MinFilter = GL_LINEAR;
-            if (ctx->Driver.TexParameter) {
-               static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};
-               static const GLfloat fparam_filter[1] = {(GLfloat) GL_LINEAR};
-               (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_WRAP_S, fparam_wrap );
-               (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_WRAP_T, fparam_wrap );
-               (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_WRAP_R, fparam_wrap );
-               (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_MIN_FILTER, fparam_filter );
-            }
+         if (newTexObj->Target == 0) {
+            finish_texture_init(ctx, target, newTexObj);
          }
       }
       else {
@@ -917,33 +951,8 @@ _mesa_BindTexture( GLenum target, GLuint texName )
     * texture object will be decremented.  It'll be deleted if the
     * count hits zero.
     */
-   switch (target) {
-      case GL_TEXTURE_1D:
-         _mesa_reference_texobj(&texUnit->Current1D, newTexObj);
-         break;
-      case GL_TEXTURE_2D:
-         _mesa_reference_texobj(&texUnit->Current2D, newTexObj);
-         break;
-      case GL_TEXTURE_3D:
-         _mesa_reference_texobj(&texUnit->Current3D, newTexObj);
-         break;
-      case GL_TEXTURE_CUBE_MAP_ARB:
-         _mesa_reference_texobj(&texUnit->CurrentCubeMap, newTexObj);
-         break;
-      case GL_TEXTURE_RECTANGLE_NV:
-         _mesa_reference_texobj(&texUnit->CurrentRect, newTexObj);
-         break;
-      case GL_TEXTURE_1D_ARRAY_EXT:
-         texUnit->Current1DArray = newTexObj;
-         break;
-      case GL_TEXTURE_2D_ARRAY_EXT:
-         texUnit->Current2DArray = newTexObj;
-         break;
-      default:
-         /* Bad target should be caught above */
-         _mesa_problem(ctx, "bad target in BindTexture");
-         return;
-   }
+   _mesa_reference_texobj(&texUnit->CurrentTex[targetIndex], newTexObj);
+   ASSERT(texUnit->CurrentTex[targetIndex]);
 
    /* Pass BindTexture call to device driver */
    if (ctx->Driver.BindTexture)