mesa: don't include m_xform.h where not needed
[mesa.git] / src / mesa / main / texstate.c
index 3bdb55257f81f1c0fd2df16bba813473e9f408a9..6586a486464d6876abe7083c0d856a7e4585430f 100644 (file)
@@ -42,7 +42,6 @@
 #include "texstate.h"
 #include "texenvprogram.h"
 #include "mtypes.h"
-#include "math/m_xform.h"
 
 
 
  */
 static const struct gl_tex_env_combine_state default_combine_state = {
    GL_MODULATE, GL_MODULATE,
-   { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT },
-   { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT },
-   { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA },
-   { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
+   { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT },
+   { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT },
+   { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA, GL_SRC_ALPHA },
+   { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
    0, 0,
    2, 2
 };
@@ -81,7 +80,7 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
    dst->Texture.SharedPalette = src->Texture.SharedPalette;
 
    /* per-unit state */
-   for (i = 0; i < src->Const.MaxTextureUnits; i++) {
+   for (i = 0; i < src->Const.MaxTextureImageUnits; i++) {
       dst->Texture.Unit[i].Enabled = src->Texture.Unit[i].Enabled;
       dst->Texture.Unit[i].EnvMode = src->Texture.Unit[i].EnvMode;
       COPY_4V(dst->Texture.Unit[i].EnvColor, src->Texture.Unit[i].EnvColor);
@@ -118,20 +117,20 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
       /* copy texture object bindings, not contents of texture objects */
       _mesa_lock_context_textures(dst);
 
-       _mesa_reference_texobj(&dst->Texture.Unit[i].Current1D,
-                              src->Texture.Unit[i].Current1D);
-       _mesa_reference_texobj(&dst->Texture.Unit[i].Current2D,
-                              src->Texture.Unit[i].Current2D);
-       _mesa_reference_texobj(&dst->Texture.Unit[i].Current3D,
-                              src->Texture.Unit[i].Current3D);
-       _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentCubeMap,
-                              src->Texture.Unit[i].CurrentCubeMap);
-       _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentRect,
-                              src->Texture.Unit[i].CurrentRect);
-       _mesa_reference_texobj(&dst->Texture.Unit[i].Current1DArray,
-                              src->Texture.Unit[i].Current1DArray);
-       _mesa_reference_texobj(&dst->Texture.Unit[i].Current2DArray,
-                              src->Texture.Unit[i].Current2DArray);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].Current1D,
+                             src->Texture.Unit[i].Current1D);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].Current2D,
+                             src->Texture.Unit[i].Current2D);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].Current3D,
+                             src->Texture.Unit[i].Current3D);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentCubeMap,
+                             src->Texture.Unit[i].CurrentCubeMap);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentRect,
+                             src->Texture.Unit[i].CurrentRect);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].Current1DArray,
+                             src->Texture.Unit[i].Current1DArray);
+      _mesa_reference_texobj(&dst->Texture.Unit[i].Current2DArray,
+                             src->Texture.Unit[i].Current2DArray);
 
       _mesa_unlock_context_textures(dst);
    }
@@ -307,8 +306,7 @@ _mesa_ActiveTextureARB(GLenum texture)
       _mesa_debug(ctx, "glActiveTexture %s\n",
                   _mesa_lookup_enum_by_nr(texture));
 
-   /* XXX error-check against max(coordunits, imageunits) */
-   if (texUnit >= ctx->Const.MaxTextureUnits) {
+   if (texUnit >= ctx->Const.MaxTextureImageUnits) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture)");
       return;
    }
@@ -369,7 +367,7 @@ update_texture_matrices( GLcontext *ctx )
 
    ctx->Texture._TexMatEnabled = 0;
 
-   for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
+   for (i=0; i < ctx->Const.MaxTextureCoordUnits; i++) {
       if (_math_matrix_is_dirty(ctx->TextureMatrixStack[i].Top)) {
         _math_matrix_analyse( ctx->TextureMatrixStack[i].Top );
 
@@ -405,16 +403,6 @@ update_texture_compare_function(GLcontext *ctx,
        */
       tObj->_Function = GL_NONE;
    }
-   else if (tObj->CompareFlag) {
-      /* GL_SGIX_shadow */
-      if (tObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
-         tObj->_Function = GL_LEQUAL;
-      }
-      else {
-         ASSERT(tObj->CompareOperator == GL_TEXTURE_GEQUAL_R_SGIX);
-         tObj->_Function = GL_GEQUAL;
-      }
-   }
    else if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
       /* GL_ARB_shadow */
       tObj->_Function = tObj->CompareFunc;
@@ -447,6 +435,96 @@ texture_override(GLcontext *ctx,
 }
 
 
+/**
+ * Examine texture unit's combine/env state to update derived state.
+ */
+static void
+update_tex_combine(GLcontext *ctx, struct gl_texture_unit *texUnit)
+{
+   /* Set the texUnit->_CurrentCombine field to point to the user's combiner
+    * state, or the combiner state which is derived from traditional texenv
+    * mode.
+    */
+   if (texUnit->EnvMode == GL_COMBINE ||
+       texUnit->EnvMode == GL_COMBINE4_NV) {
+      texUnit->_CurrentCombine = & texUnit->Combine;
+   }
+   else {
+      const struct gl_texture_object *texObj = texUnit->_Current;
+      GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
+      if (format == GL_COLOR_INDEX) {
+         format = GL_RGBA;  /* a bit of a hack */
+      }
+      else if (format == GL_DEPTH_COMPONENT ||
+               format == GL_DEPTH_STENCIL_EXT) {
+         format = texObj->DepthMode;
+      }
+      calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format);
+      texUnit->_CurrentCombine = & texUnit->_EnvMode;
+   }
+
+   /* Determine number of source RGB terms in the combiner function */
+   switch (texUnit->_CurrentCombine->ModeRGB) {
+   case GL_REPLACE:
+      texUnit->_CurrentCombine->_NumArgsRGB = 1;
+      break;
+   case GL_ADD:
+   case GL_ADD_SIGNED:
+      if (texUnit->EnvMode == GL_COMBINE4_NV)
+         texUnit->_CurrentCombine->_NumArgsRGB = 4;
+      else
+         texUnit->_CurrentCombine->_NumArgsRGB = 2;
+      break;
+   case GL_MODULATE:
+   case GL_SUBTRACT:
+   case GL_DOT3_RGB:
+   case GL_DOT3_RGBA:
+   case GL_DOT3_RGB_EXT:
+   case GL_DOT3_RGBA_EXT:
+      texUnit->_CurrentCombine->_NumArgsRGB = 2;
+      break;
+   case GL_INTERPOLATE:
+   case GL_MODULATE_ADD_ATI:
+   case GL_MODULATE_SIGNED_ADD_ATI:
+   case GL_MODULATE_SUBTRACT_ATI:
+      texUnit->_CurrentCombine->_NumArgsRGB = 3;
+      break;
+   default:
+      texUnit->_CurrentCombine->_NumArgsRGB = 0;
+      _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
+      return;
+   }
+
+   /* Determine number of source Alpha terms in the combiner function */
+   switch (texUnit->_CurrentCombine->ModeA) {
+   case GL_REPLACE:
+      texUnit->_CurrentCombine->_NumArgsA = 1;
+      break;
+   case GL_ADD:
+   case GL_ADD_SIGNED:
+      if (texUnit->EnvMode == GL_COMBINE4_NV)
+         texUnit->_CurrentCombine->_NumArgsA = 4;
+      else
+         texUnit->_CurrentCombine->_NumArgsA = 2;
+      break;
+   case GL_MODULATE:
+   case GL_SUBTRACT:
+      texUnit->_CurrentCombine->_NumArgsA = 2;
+      break;
+   case GL_INTERPOLATE:
+   case GL_MODULATE_ADD_ATI:
+   case GL_MODULATE_SIGNED_ADD_ATI:
+   case GL_MODULATE_SUBTRACT_ATI:
+      texUnit->_CurrentCombine->_NumArgsA = 3;
+      break;
+   default:
+      texUnit->_CurrentCombine->_NumArgsA = 0;
+      _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state");
+      break;
+   }
+}
+
+
 /**
  * \note This routine refers to derived texture matrix values to
  * compute the ENABLE_TEXMAT flags, but is only called on
@@ -479,9 +557,8 @@ update_texture_state( GLcontext *ctx )
       }
    }
 
-   ctx->NewState |= _NEW_TEXTURE; /* TODO: only set this if there are 
-                                  * actual changes. 
-                                  */
+   /* TODO: only set this if there are actual changes */
+   ctx->NewState |= _NEW_TEXTURE;
 
    ctx->Texture._EnabledUnits = 0;
    ctx->Texture._GenFlags = 0;
@@ -491,7 +568,7 @@ update_texture_state( GLcontext *ctx )
    /*
     * Update texture unit state.
     */
-   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
+   for (unit = 0; unit < ctx->Const.MaxTextureImageUnits; unit++) {
       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
       GLbitfield enableBits;
 
@@ -499,25 +576,35 @@ update_texture_state( GLcontext *ctx )
       texUnit->_ReallyEnabled = 0;
       texUnit->_GenFlags = 0;
 
-      /* Get the bitmask of texture enables.
+      /* Get the bitmask of texture target enables.
        * enableBits will be a mask of the TEXTURE_*_BIT flags indicating
        * which texture targets are enabled (fixed function) or referenced
        * by a fragment shader/program.  When multiple flags are set, we'll
        * settle on the one with highest priority (see texture_override below).
        */
-      if (fprog || vprog) {
-         enableBits = 0x0;
-         if (fprog)
-            enableBits |= fprog->Base.TexturesUsed[unit];
-         if (vprog)
-            enableBits |= vprog->Base.TexturesUsed[unit];
+      enableBits = 0x0;
+      if (vprog) {
+         enableBits |= vprog->Base.TexturesUsed[unit];
+      }
+      if (fprog) {
+         enableBits |= fprog->Base.TexturesUsed[unit];
       }
       else {
-         if (!texUnit->Enabled)
-            continue;
-         enableBits = texUnit->Enabled;
+         /* fixed-function fragment program */
+         enableBits |= texUnit->Enabled;
       }
 
+      if (enableBits == 0x0)
+         continue;
+
+      ASSERT(texUnit->Current1D);
+      ASSERT(texUnit->Current2D);
+      ASSERT(texUnit->Current3D);
+      ASSERT(texUnit->CurrentCubeMap);
+      ASSERT(texUnit->CurrentRect);
+      ASSERT(texUnit->Current1DArray);
+      ASSERT(texUnit->Current2DArray);
+
       /* Look for the highest-priority texture target that's enabled and
        * complete.  That's the one we'll use for texturing.  If we're using
        * a fragment program we're guaranteed that bitcount(enabledBits) <= 1.
@@ -541,73 +628,30 @@ update_texture_state( GLcontext *ctx )
          continue;
       }
 
-      if (texUnit->_ReallyEnabled)
-         ctx->Texture._EnabledUnits |= (1 << unit);
+      /* if we get here, we know this texture unit is enabled */
 
-      if (texUnit->EnvMode == GL_COMBINE) {
-        texUnit->_CurrentCombine = & texUnit->Combine;
-      }
-      else {
-         const struct gl_texture_object *texObj = texUnit->_Current;
-         GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
-         if (format == GL_COLOR_INDEX) {
-            format = GL_RGBA;  /* a bit of a hack */
-         }
-         else if (format == GL_DEPTH_COMPONENT
-                  || format == GL_DEPTH_STENCIL_EXT) {
-            format = texObj->DepthMode;
-         }
-        calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format);
-        texUnit->_CurrentCombine = & texUnit->_EnvMode;
-      }
+      ctx->Texture._EnabledUnits |= (1 << unit);
 
-      switch (texUnit->_CurrentCombine->ModeRGB) {
-      case GL_REPLACE:
-        texUnit->_CurrentCombine->_NumArgsRGB = 1;
-        break;
-      case GL_MODULATE:
-      case GL_ADD:
-      case GL_ADD_SIGNED:
-      case GL_SUBTRACT:
-      case GL_DOT3_RGB:
-      case GL_DOT3_RGBA:
-      case GL_DOT3_RGB_EXT:
-      case GL_DOT3_RGBA_EXT:
-        texUnit->_CurrentCombine->_NumArgsRGB = 2;
-        break;
-      case GL_INTERPOLATE:
-      case GL_MODULATE_ADD_ATI:
-      case GL_MODULATE_SIGNED_ADD_ATI:
-      case GL_MODULATE_SUBTRACT_ATI:
-        texUnit->_CurrentCombine->_NumArgsRGB = 3;
-        break;
-      default:
-        texUnit->_CurrentCombine->_NumArgsRGB = 0;
-         _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
-         return;
-      }
+      update_tex_combine(ctx, texUnit);
+   }
 
-      switch (texUnit->_CurrentCombine->ModeA) {
-      case GL_REPLACE:
-        texUnit->_CurrentCombine->_NumArgsA = 1;
-        break;
-      case GL_MODULATE:
-      case GL_ADD:
-      case GL_ADD_SIGNED:
-      case GL_SUBTRACT:
-        texUnit->_CurrentCombine->_NumArgsA = 2;
-        break;
-      case GL_INTERPOLATE:
-      case GL_MODULATE_ADD_ATI:
-      case GL_MODULATE_SIGNED_ADD_ATI:
-      case GL_MODULATE_SUBTRACT_ATI:
-        texUnit->_CurrentCombine->_NumArgsA = 3;
-        break;
-      default:
-        texUnit->_CurrentCombine->_NumArgsA = 0;
-         _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state");
-        break;
-      }
+
+   /* Determine which texture coordinate sets are actually needed */
+   if (fprog) {
+      const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
+      ctx->Texture._EnabledCoordUnits
+         = (fprog->Base.InputsRead >> FRAG_ATTRIB_TEX0) & coordMask;
+   }
+   else {
+      ctx->Texture._EnabledCoordUnits = ctx->Texture._EnabledUnits;
+   }
+
+   /* Setup texgen for those texture coordinate sets that are in use */
+   for (unit = 0; unit < ctx->Const.MaxTextureCoordUnits; unit++) {
+      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+
+      if (!(ctx->Texture._EnabledCoordUnits & (1 << unit)))
+        continue;
 
       if (texUnit->TexGenEnabled) {
         if (texUnit->TexGenEnabled & S_BIT) {
@@ -630,16 +674,6 @@ update_texture_state( GLcontext *ctx )
       if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
         ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
    }
-
-   /* Determine which texture coordinate sets are actually needed */
-   if (fprog) {
-      const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
-      ctx->Texture._EnabledCoordUnits
-         = (fprog->Base.InputsRead >> FRAG_ATTRIB_TEX0) & coordMask;
-   }
-   else {
-      ctx->Texture._EnabledCoordUnits = ctx->Texture._EnabledUnits;
-   }
 }
 
 
@@ -674,54 +708,32 @@ _mesa_update_texture( GLcontext *ctx, GLuint new_state )
 static GLboolean
 alloc_proxy_textures( GLcontext *ctx )
 {
-   ctx->Texture.Proxy1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
-   if (!ctx->Texture.Proxy1D)
-      goto cleanup;
-
-   ctx->Texture.Proxy2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
-   if (!ctx->Texture.Proxy2D)
-      goto cleanup;
-
-   ctx->Texture.Proxy3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
-   if (!ctx->Texture.Proxy3D)
-      goto cleanup;
-
-   ctx->Texture.ProxyCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
-   if (!ctx->Texture.ProxyCubeMap)
-      goto cleanup;
-
-   ctx->Texture.ProxyRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
-   if (!ctx->Texture.ProxyRect)
-      goto cleanup;
-
-   ctx->Texture.Proxy1DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D_ARRAY_EXT);
-   if (!ctx->Texture.Proxy1DArray)
-      goto cleanup;
-
-   ctx->Texture.Proxy2DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D_ARRAY_EXT);
-   if (!ctx->Texture.Proxy2DArray)
-      goto cleanup;
-
-   assert(ctx->Texture.Proxy1D->RefCount == 1);
+   static const GLenum targets[] = {
+      GL_TEXTURE_1D,
+      GL_TEXTURE_2D,
+      GL_TEXTURE_3D,
+      GL_TEXTURE_CUBE_MAP_ARB,
+      GL_TEXTURE_RECTANGLE_NV,
+      GL_TEXTURE_1D_ARRAY_EXT,
+      GL_TEXTURE_2D_ARRAY_EXT
+   };
+   GLint tgt;
+
+   ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS);
+
+   for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
+      if (!(ctx->Texture.ProxyTex[tgt]
+            = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) {
+         /* out of memory, free what we did allocate */
+         while (--tgt >= 0) {
+            ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
+         }
+         return GL_FALSE;
+      }
+   }
 
+   assert(ctx->Texture.ProxyTex[0]->RefCount == 1); /* sanity check */
    return GL_TRUE;
-
- cleanup:
-   if (ctx->Texture.Proxy1D)
-      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D);
-   if (ctx->Texture.Proxy2D)
-      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D);
-   if (ctx->Texture.Proxy3D)
-      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D);
-   if (ctx->Texture.ProxyCubeMap)
-      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap);
-   if (ctx->Texture.ProxyRect)
-      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect);
-   if (ctx->Texture.Proxy1DArray)
-      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1DArray);
-   if (ctx->Texture.Proxy2DArray)
-      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2DArray);
-   return GL_FALSE;
 }
 
 
@@ -815,7 +827,7 @@ _mesa_init_texture(GLcontext *ctx)
 void
 _mesa_free_texture_data(GLcontext *ctx)
 {
-   GLuint u;
+   GLuint u, tgt;
 
    /* unreference current textures */
    for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
@@ -830,14 +842,8 @@ _mesa_free_texture_data(GLcontext *ctx)
    }
 
    /* Free proxy texture objects */
-   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy1D );
-   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy2D );
-   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy3D );
-   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.ProxyCubeMap );
-   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.ProxyRect );
-   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy1DArray );
-   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy2DArray );
-
+   for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++)
+      ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
 
 #if FEATURE_colortable
    {
@@ -847,3 +853,27 @@ _mesa_free_texture_data(GLcontext *ctx)
    }
 #endif
 }
+
+
+/**
+ * Update the default texture objects in the given context to reference those
+ * specified in the shared state and release those referencing the old 
+ * shared state.
+ */
+void
+_mesa_update_default_objects_texture(GLcontext *ctx)
+{
+   GLuint i;
+
+   for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
+      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
+
+      _mesa_reference_texobj(&texUnit->Current1D, ctx->Shared->Default1D);
+      _mesa_reference_texobj(&texUnit->Current2D, ctx->Shared->Default2D);
+      _mesa_reference_texobj(&texUnit->Current3D, ctx->Shared->Default3D);
+      _mesa_reference_texobj(&texUnit->CurrentCubeMap, ctx->Shared->DefaultCubeMap);
+      _mesa_reference_texobj(&texUnit->CurrentRect, ctx->Shared->DefaultRect);
+      _mesa_reference_texobj(&texUnit->Current1DArray, ctx->Shared->Default1DArray);
+      _mesa_reference_texobj(&texUnit->Current2DArray, ctx->Shared->Default2DArray);
+   }
+}