Implemented GL_ARB_texture_env_crossbar.
authorBrian Paul <brian.paul@tungstengraphics.com>
Thu, 2 May 2002 00:59:20 +0000 (00:59 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Thu, 2 May 2002 00:59:20 +0000 (00:59 +0000)
Simplification of some of the texture application code.

src/mesa/main/extensions.c
src/mesa/main/mtypes.h
src/mesa/main/texstate.c
src/mesa/swrast/s_context.c
src/mesa/swrast/s_context.h
src/mesa/swrast/s_pixeltex.c
src/mesa/swrast/s_span.c
src/mesa/swrast/s_texture.c
src/mesa/swrast/s_texture.h

index fe43e66..9698435 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: extensions.c,v 1.72 2002/04/02 16:15:17 brianp Exp $ */
+/* $Id: extensions.c,v 1.73 2002/05/02 00:59:20 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -68,6 +68,7 @@ static struct {
    { OFF, "GL_ARB_texture_cube_map",           F(ARB_texture_cube_map) },
    { OFF, "GL_ARB_texture_env_add",            F(EXT_texture_env_add) },
    { OFF, "GL_ARB_texture_env_combine",        F(ARB_texture_env_combine) },
+   { OFF, "GL_ARB_texture_env_crossbar",       F(ARB_texture_env_crossbar) },
    { OFF, "GL_ARB_texture_env_dot3",           F(ARB_texture_env_dot3) },
    { OFF, "GL_ARB_texture_mirrored_repeat",    F(ARB_texture_mirrored_repeat)},
    { ON,  "GL_ARB_transpose_matrix",           0 },
@@ -150,6 +151,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
       "GL_ARB_texture_cube_map",
       "GL_ARB_texture_env_add",
       "GL_ARB_texture_env_combine",
+      "GL_ARB_texture_env_crossbar",
       "GL_ARB_texture_env_dot3",
       "GL_ARB_texture_mirrored_repeat",
       "GL_EXT_blend_color",
index 28a1921..41ba77b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mtypes.h,v 1.73 2002/04/21 20:37:04 brianp Exp $ */
+/* $Id: mtypes.h,v 1.74 2002/05/02 00:59:20 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -1389,6 +1389,7 @@ struct gl_extensions {
    GLboolean ARB_texture_compression;
    GLboolean ARB_texture_cube_map;
    GLboolean ARB_texture_env_combine;
+   GLboolean ARB_texture_env_crossbar;
    GLboolean ARB_texture_env_dot3;
    GLboolean ARB_texture_mirrored_repeat;
    GLboolean ARB_window_pos;
index 88618c6..67cb402 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: texstate.c,v 1.70 2002/04/26 13:40:11 brianp Exp $ */
+/* $Id: texstate.c,v 1.71 2002/05/02 00:59:20 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -77,51 +77,42 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
 
    if (target==GL_TEXTURE_ENV) {
       switch (pname) {
-      case GL_TEXTURE_ENV_MODE: {
-        GLenum mode = (GLenum) (GLint) *param;
-
-        switch (mode) {
-        case GL_ADD:
-           if (!ctx->Extensions.EXT_texture_env_add) {
-              TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
-              return;
-           }
-           break;
-        case GL_COMBINE_EXT:
-           if (!ctx->Extensions.EXT_texture_env_combine &&
-                !ctx->Extensions.ARB_texture_env_combine) {
-              TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
-              return;
-           }
-           break;
-        case GL_MODULATE:
-        case GL_BLEND:
-        case GL_DECAL:
-        case GL_REPLACE:
-           break;
-        default:
-            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
-           return;
-        }
-
-        if (texUnit->EnvMode == mode)
-           return;
-        FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-        texUnit->EnvMode = mode;
-        break;
-      }
-      case GL_TEXTURE_ENV_COLOR: {
-        GLfloat tmp[4];
-        tmp[0] = CLAMP( param[0], 0.0F, 1.0F );
-        tmp[1] = CLAMP( param[1], 0.0F, 1.0F );
-        tmp[2] = CLAMP( param[2], 0.0F, 1.0F );
-        tmp[3] = CLAMP( param[3], 0.0F, 1.0F );
-        if (TEST_EQ_4V(tmp, texUnit->EnvColor))
-           return;
-        FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-        COPY_4FV(texUnit->EnvColor, tmp);
-        break;
-      }
+      case GL_TEXTURE_ENV_MODE:
+         {
+            const GLenum mode = (GLenum) (GLint) *param;
+            if (mode == GL_MODULATE ||
+                mode == GL_BLEND ||
+                mode == GL_DECAL ||
+                mode == GL_REPLACE ||
+                (mode == GL_ADD && ctx->Extensions.EXT_texture_env_add) ||
+                (mode == GL_COMBINE_EXT &&
+                 (ctx->Extensions.EXT_texture_env_combine ||
+                  ctx->Extensions.ARB_texture_env_combine))) {
+               /* legal */
+               if (texUnit->EnvMode == mode)
+                  return;
+               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+               texUnit->EnvMode = mode;
+            }
+            else {
+               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+               return;
+            }
+         }
+         break;
+      case GL_TEXTURE_ENV_COLOR:
+         {
+            GLfloat tmp[4];
+            tmp[0] = CLAMP( param[0], 0.0F, 1.0F );
+            tmp[1] = CLAMP( param[1], 0.0F, 1.0F );
+            tmp[2] = CLAMP( param[2], 0.0F, 1.0F );
+            tmp[3] = CLAMP( param[3], 0.0F, 1.0F );
+            if (TEST_EQ_4V(tmp, texUnit->EnvColor))
+               return;
+            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+            COPY_4FV(texUnit->EnvColor, tmp);
+         }
+         break;
       case GL_COMBINE_RGB_EXT:
         if (ctx->Extensions.EXT_texture_env_combine ||
              ctx->Extensions.ARB_texture_env_combine) {
@@ -172,28 +163,23 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
         if (ctx->Extensions.EXT_texture_env_combine ||
              ctx->Extensions.ARB_texture_env_combine) {
            const GLenum mode = (GLenum) (GLint) *param;
-           switch (mode) {
-           case GL_REPLACE:
-           case GL_MODULATE:
-           case GL_ADD:
-           case GL_ADD_SIGNED_EXT:
-           case GL_INTERPOLATE_EXT:
-               /* OK */
-              break;
-            case GL_SUBTRACT_ARB:
-               if (!ctx->Extensions.ARB_texture_env_combine) {
-                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+            if (mode == GL_REPLACE ||
+                mode == GL_MODULATE ||
+                mode == GL_ADD ||
+                mode == GL_ADD_SIGNED_EXT ||
+                mode == GL_INTERPOLATE_EXT ||
+                (mode == GL_SUBTRACT_ARB &&
+                 ctx->Extensions.ARB_texture_env_combine)) {
+               /* legal */
+               if (texUnit->CombineModeA == mode)
                   return;
-               }
-               break;
-           default:
+               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+               texUnit->CombineModeA = mode;
+            }
+            else {
                TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
               return;
            }
-            if (texUnit->CombineModeA == mode)
-               return;
-            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
-            texUnit->CombineModeA = mode;
         }
         else {
             TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
@@ -205,19 +191,22 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
       case GL_SOURCE2_RGB_EXT:
         if (ctx->Extensions.EXT_texture_env_combine ||
             ctx->Extensions.ARB_texture_env_combine) {
-           GLenum source = (GLenum) (GLint) *param;
-           GLuint s = pname - GL_SOURCE0_RGB_EXT;
-           switch (source) {
-           case GL_TEXTURE:
-           case GL_CONSTANT_EXT:
-           case GL_PRIMARY_COLOR_EXT:
-           case GL_PREVIOUS_EXT:
-              if (texUnit->CombineSourceRGB[s] == source)
-                 return;
+           const GLenum source = (GLenum) (GLint) *param;
+           const GLuint s = pname - GL_SOURCE0_RGB_EXT;
+            if (source == GL_TEXTURE ||
+                source == GL_CONSTANT_EXT ||
+                source == GL_PRIMARY_COLOR_EXT ||
+                source == GL_PREVIOUS_EXT ||
+                (ctx->Extensions.ARB_texture_env_crossbar &&
+                 source >= GL_TEXTURE0_ARB &&
+                 source < GL_TEXTURE0_ARB + ctx->Const.MaxTextureUnits)) {
+               /* legal */
+               if (texUnit->CombineSourceRGB[s] == source)
+                  return;
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
               texUnit->CombineSourceRGB[s] = source;
-              break;
-           default:
+            }
+            else {
                TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
               return;
            }
@@ -232,18 +221,22 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
       case GL_SOURCE2_ALPHA_EXT:
         if (ctx->Extensions.EXT_texture_env_combine ||
              ctx->Extensions.ARB_texture_env_combine) {
-           GLenum source = (GLenum) (GLint) *param;
-           GLuint s = pname - GL_SOURCE0_ALPHA_EXT;
-           switch (source) {
-           case GL_TEXTURE:
-           case GL_CONSTANT_EXT:
-           case GL_PRIMARY_COLOR_EXT:
-           case GL_PREVIOUS_EXT:
-              if (texUnit->CombineSourceA[s] == source) return;
+           const GLenum source = (GLenum) (GLint) *param;
+           const GLuint s = pname - GL_SOURCE0_ALPHA_EXT;
+            if (source == GL_TEXTURE ||
+                source == GL_CONSTANT_EXT ||
+                source == GL_PRIMARY_COLOR_EXT ||
+                source == GL_PREVIOUS_EXT ||
+                (ctx->Extensions.ARB_texture_env_crossbar &&
+                 source >= GL_TEXTURE0_ARB &&
+                 source < GL_TEXTURE0_ARB + ctx->Const.MaxTextureUnits)) {
+               /* legal */
+              if (texUnit->CombineSourceA[s] == source)
+                  return;
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
               texUnit->CombineSourceA[s] = source;
-              break;
-           default:
+            }
+            else {
                TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
               return;
            }
@@ -257,8 +250,8 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
       case GL_OPERAND1_RGB_EXT:
         if (ctx->Extensions.EXT_texture_env_combine ||
             ctx->Extensions.ARB_texture_env_combine) {
-           GLenum operand = (GLenum) (GLint) *param;
-           GLuint s = pname - GL_OPERAND0_RGB_EXT;
+           const GLenum operand = (GLenum) (GLint) *param;
+           const GLuint s = pname - GL_OPERAND0_RGB_EXT;
            switch (operand) {
            case GL_SRC_COLOR:
            case GL_ONE_MINUS_SRC_COLOR:
@@ -283,7 +276,7 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
       case GL_OPERAND1_ALPHA_EXT:
         if (ctx->Extensions.EXT_texture_env_combine ||
              ctx->Extensions.ARB_texture_env_combine) {
-           GLenum operand = (GLenum) (GLint) *param;
+           const GLenum operand = (GLenum) (GLint) *param;
            switch (operand) {
            case GL_SRC_ALPHA:
            case GL_ONE_MINUS_SRC_ALPHA:
@@ -306,7 +299,7 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
       case GL_OPERAND2_RGB_EXT:
         if (ctx->Extensions.EXT_texture_env_combine ||
              ctx->Extensions.ARB_texture_env_combine) {
-           GLenum operand = (GLenum) (GLint) *param;
+           const GLenum operand = (GLenum) (GLint) *param;
            switch (operand) {
            case GL_SRC_COLOR:           /* ARB combine only */
            case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */
@@ -329,7 +322,7 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
       case GL_OPERAND2_ALPHA_EXT:
         if (ctx->Extensions.EXT_texture_env_combine ||
              ctx->Extensions.ARB_texture_env_combine) {
-           GLenum operand = (GLenum) (GLint) *param;
+           const GLenum operand = (GLenum) (GLint) *param;
            switch (operand) {
            case GL_SRC_ALPHA:
            case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
@@ -1261,6 +1254,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
    GLint maxLevels;
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
+   /* this will catch bad target values */
    dimensions = tex_image_dimensions(ctx, target);  /* 1, 2 or 3 */
    if (dimensions == 0) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
index 96572aa..809ee68 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_context.c,v 1.31 2002/04/19 14:05:50 brianp Exp $ */
+/* $Id: s_context.c,v 1.32 2002/05/02 00:59:20 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -40,9 +40,6 @@
 #include "s_texture.h"
 
 
-
-
-
 /*
  * Recompute the value of swrast->_RasterMask, etc. according to
  * the current context.
@@ -145,6 +142,26 @@ _swrast_update_hint( GLcontext *ctx )
                               swrast->AllowPixelFog));
 }
 
+
+/*
+ * Update the swrast->_AnyTextureCombine flag.
+ */
+static void
+_swrast_update_texture_env( GLcontext *ctx )
+{
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   GLuint i;
+   swrast->_AnyTextureCombine = GL_FALSE;
+   for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+      if (ctx->Texture.Unit[i].EnvMode == GL_COMBINE_EXT ||
+          ctx->Texture.Unit[i].EnvMode == GL_COMBINE4_NV) {
+         swrast->_AnyTextureCombine = GL_TRUE;
+         return;
+      }
+   }
+}
+
+
 #define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK |  \
                             _NEW_TEXTURE |             \
                             _NEW_HINT |                \
@@ -183,6 +200,8 @@ _swrast_update_hint( GLcontext *ctx )
 
 #define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE
 
+#define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE
+
 #define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR
 
 
@@ -315,7 +334,6 @@ _swrast_invalidate_state( GLcontext *ctx, GLuint new_state )
       for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
         swrast->TextureSample[i] = _swrast_validate_texture_sample;
 
-
    if (ctx->Visual.rgbMode) {
       ASSERT(swrast->Driver.WriteRGBASpan);
       ASSERT(swrast->Driver.WriteRGBSpan);
@@ -334,18 +352,15 @@ _swrast_invalidate_state( GLcontext *ctx, GLuint new_state )
       ASSERT(swrast->Driver.ReadCI32Span);
       ASSERT(swrast->Driver.ReadCI32Pixels);
    }
-
 }
 
 
-
 void
 _swrast_validate_derived( GLcontext *ctx )
 {
    SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
-   if (swrast->NewState)
-   {
+   if (swrast->NewState) {
       if (swrast->NewState & _SWRAST_NEW_RASTERMASK)
         _swrast_update_rasterflags( ctx );
 
@@ -355,6 +370,9 @@ _swrast_validate_derived( GLcontext *ctx )
       if (swrast->NewState & _NEW_HINT)
         _swrast_update_hint( ctx );
 
+      if (swrast->NewState & _SWRAST_NEW_TEXTURE_ENV_MODE)
+        _swrast_update_texture_env( ctx );
+
       swrast->NewState = 0;
       swrast->StateChanges = 0;
       swrast->InvalidateState = _swrast_invalidate_state;
@@ -490,7 +508,6 @@ _swrast_CreateContext( GLcontext *ctx )
    swrast->_IntegerAccumMode = GL_TRUE;
    swrast->_IntegerAccumScaler = 0.0;
 
-
    for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
       swrast->TextureSample[i] = _swrast_validate_texture_sample;
 
@@ -499,7 +516,18 @@ _swrast_CreateContext( GLcontext *ctx )
      FREE(swrast);
      return GL_FALSE;
    }
-   
+
+   assert(ctx->Const.MaxTextureUnits > 0);
+   assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_UNITS);
+
+   swrast->TexelBuffer = (GLchan *) MALLOC(ctx->Const.MaxTextureUnits *
+                                           MAX_WIDTH * 4 * sizeof(GLchan));
+   if (!swrast->TexelBuffer) {
+      FREE(swrast->span);
+      FREE(swrast);
+      return GL_FALSE;
+   }
+
    ctx->swrast_context = swrast;
 
    return GL_TRUE;
@@ -515,7 +543,7 @@ _swrast_DestroyContext( GLcontext *ctx )
    }
 
    FREE( swrast->span );
-   
+   FREE( swrast->TexelBuffer );
    FREE( swrast );
 
    ctx->swrast_context = 0;
index b0ca5bf..900c190 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_context.h,v 1.17 2002/04/19 14:05:50 brianp Exp $ */
+/* $Id: s_context.h,v 1.18 2002/05/02 00:59:20 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -124,6 +124,7 @@ typedef struct
    GLfloat _MinMagThresh[MAX_TEXTURE_UNITS];
    GLfloat _backface_sign;
    GLboolean _PreferPixelFog;
+   GLboolean _AnyTextureCombine;
 
    /* Accum buffer temporaries.
     */
@@ -176,6 +177,11 @@ typedef struct
    blend_func BlendFunc;
    TextureSampleFunc TextureSample[MAX_TEXTURE_UNITS];
 
+   /** Buffer for saving the sampled texture colors.
+    * Needed for GL_ARB_texture_env_crossbar implementation.
+    */
+   GLchan *TexelBuffer;
+
 } SWcontext;
 
 
index c2b597a..3afda84 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_pixeltex.c,v 1.8 2002/04/12 15:39:59 brianp Exp $ */
+/* $Id: s_pixeltex.c,v 1.9 2002/05/02 00:59:20 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -85,47 +85,34 @@ pixeltexgen(GLcontext *ctx, GLuint n, const GLchan rgba[][4],
 
 
 /*
- * Used byglDraw/CopyPixels: the incoming image colors are treated
+ * Used by glDraw/CopyPixels: the incoming image colors are treated
  * as texture coordinates.  Use those coords to texture the image.
  * This is for GL_SGIS_pixel_texture / GL_SGIX_pixel_texture.
  */
 void
 _swrast_pixel_texture(GLcontext *ctx, struct sw_span *span)
 {
-   if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) {
-      /* multitexture! */
-      GLchan primary_rgba[MAX_WIDTH][4];
-      GLuint unit;
-
-      ASSERT(!(span->arrayMask & SPAN_TEXTURE));
-      span->arrayMask |= SPAN_TEXTURE;
-
-      MEMCPY(primary_rgba, span->color.rgba, 4 * span->end * sizeof(GLchan));
-      
-      for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
-         if (ctx->Texture.Unit[unit]._ReallyEnabled) {
-            pixeltexgen(ctx, span->end,
-                        (const GLchan (*)[4]) span->color.rgba,
-                        span->texcoords[unit]);
-            _swrast_texture_fragments(ctx, unit, span,
-                                      (CONST GLchan (*)[4]) primary_rgba);
-         }
+   GLuint unit;
+
+   ASSERT(!(span->arrayMask & SPAN_TEXTURE));
+   span->arrayMask |= SPAN_TEXTURE;
+
+   /* convert colors into texture coordinates */
+   pixeltexgen( ctx, span->end,
+                (const GLchan (*)[4]) span->color.rgba,
+                span->texcoords[0] );
+
+   /* copy the new texture units for all enabled units */
+   for (unit = 1; unit < ctx->Const.MaxTextureUnits; unit++) {
+      if (ctx->Texture.Unit[unit]._ReallyEnabled) {
+         MEMCPY( span->texcoords[unit], span->texcoords[0],
+                 span->end * 4 * sizeof(GLfloat) );
       }
-      /* this is a work-around to be fixed by initializing again span */
-      span->arrayMask &= ~SPAN_TEXTURE;
-   }
-   else {
-      /* single texture, unit 0 */
-      ASSERT(ctx->Texture._ReallyEnabled & TEXTURE0_ANY);
-      ASSERT(!(span->arrayMask & SPAN_TEXTURE));
-      span->arrayMask |= SPAN_TEXTURE;
-
-      pixeltexgen(ctx, span->end,
-                  (const GLchan (*)[4]) span->color.rgba,
-                  span->texcoords[0]);
-      _swrast_texture_fragments(ctx, 0, span,
-                                (CONST GLchan (*)[4]) span->color.rgba);
-      /* this is a work-around to be fixed */
-      span->arrayMask &= ~SPAN_TEXTURE;
    }
+
+   /* apply texture mapping */
+   _swrast_texture_span( ctx, span );
+
+   /* this is a work-around to be fixed by initializing again span */
+   span->arrayMask &= ~SPAN_TEXTURE;
 }
index 9712efb..1e3c710 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_span.c,v 1.41 2002/04/20 17:54:55 brianp Exp $ */
+/* $Id: s_span.c,v 1.42 2002/05/02 00:59:20 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -1171,7 +1171,7 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span)
       /* Texturing without alpha is done after depth-testing which
        * gives a potential speed-up.
        */
-      _swrast_multitexture_fragments( ctx, span );
+      _swrast_texture_span( ctx, span );
 
       /* Do the alpha test */
       if (!_mesa_alpha_test(ctx, span)) {
@@ -1220,7 +1220,7 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span)
       if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
          interpolate_colors(ctx, span);
 
-      _swrast_multitexture_fragments( ctx, span );
+      _swrast_texture_span( ctx, span );
    }
 
    ASSERT(span->arrayMask & SPAN_RGBA);
index 44738ac..97a8447 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_texture.c,v 1.61 2002/04/19 00:38:27 brianp Exp $ */
+/* $Id: s_texture.c,v 1.62 2002/05/02 00:59:20 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -2394,6 +2394,9 @@ sample_depth_texture2(const GLcontext *ctx,
 #endif
 
 
+/**
+ * We use this function when a texture object is in an "incomplete" state.
+ */
 static void
 null_sample_func( GLcontext *ctx, GLuint texUnit,
                  const struct gl_texture_object *tObj, GLuint n,
@@ -2404,12 +2407,7 @@ null_sample_func( GLcontext *ctx, GLuint texUnit,
 
 
 
-/**********************************************************************/
-/*                       Texture Sampling Setup                       */
-/**********************************************************************/
-
-
-/*
+/**
  * Setup the texture sampling function for this texture object.
  */
 void
@@ -2516,17 +2514,27 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit,
 #define PROD(A,B)   ( (GLuint)(A) * ((GLuint)(B)+1) )
 #define S_PROD(A,B) ( (GLint)(A) * ((GLint)(B)+1) )
 
+
+/**
+ * Do texture application for GL_ARB/EXT_texture_env_combine.
+ * Input:
+ *     ctx - rendering context
+ *     textureUnit - the texture unit to apply
+ *     n - number of fragments to process (span width)
+ *     primary_rgba - incoming fragment color array
+ *     texelBuffer - pointer to texel colors for all texture units
+ * Input/Output:
+ *     rgba - incoming colors, which get modified here
+ */
 static INLINE void
-texture_combine(const GLcontext *ctx,
-                const struct gl_texture_unit *textureUnit,
-                GLuint n,
-                CONST GLchan (*primary_rgba)[4],
-                CONST GLchan (*texel)[4],
-                GLchan (*rgba)[4])
+texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
+                 CONST GLchan (*primary_rgba)[4],
+                 CONST GLchan *texelBuffer,
+                 GLchan (*rgba)[4] )
 {
+   const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]);
    const GLchan (*argRGB [3])[4];
    const GLchan (*argA [3])[4];
-   GLuint i, j;
    const GLuint RGBshift = textureUnit->CombineScaleShiftRGB;
    const GLuint Ashift   = textureUnit->CombineScaleShiftA;
 #if CHAN_TYPE == GL_FLOAT
@@ -2535,12 +2543,16 @@ texture_combine(const GLcontext *ctx,
 #else
    const GLint half = (CHAN_MAX + 1) / 2;
 #endif
+   GLuint i, j;
 
+   /* GLchan ccolor[3][4]; */
    DEFMNARRAY(GLchan, ccolor, 3, 3 * MAX_WIDTH, 4);  /* mac 32k limitation */
    CHECKARRAY(ccolor, return);  /* mac 32k limitation */
 
    ASSERT(ctx->Extensions.EXT_texture_env_combine ||
           ctx->Extensions.ARB_texture_env_combine);
+   ASSERT(SWRAST_CONTEXT(ctx)->_AnyTextureCombine);
+
 
    /*
    printf("modeRGB 0x%x  modeA 0x%x  srcRGB1 0x%x  srcA1 0x%x  srcRGB2 0x%x  srcA2 0x%x\n",
@@ -2556,9 +2568,13 @@ texture_combine(const GLcontext *ctx,
     * Do operand setup for up to 3 operands.  Loop over the terms.
     */
    for (j = 0; j < 3; j++) {
-      switch (textureUnit->CombineSourceA[j]) {
+      const GLenum srcA = textureUnit->CombineSourceA[j];
+      const GLenum srcRGB = textureUnit->CombineSourceRGB[j];
+
+      switch (srcA) {
          case GL_TEXTURE:
-            argA[j] = texel;
+            argA[j] = (const GLchan (*)[4])
+               (texelBuffer + unit * (n * 4 * sizeof(GLchan)));
             break;
          case GL_PRIMARY_COLOR_EXT:
             argA[j] = primary_rgba;
@@ -2576,12 +2592,21 @@ texture_combine(const GLcontext *ctx,
             }
             break;
          default:
-            _mesa_problem(ctx, "invalid combine source");
+            /* ARB_texture_env_crossbar source */
+            {
+               const GLuint srcUnit = srcA - GL_TEXTURE0_ARB;
+               ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
+               if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
+                  return;
+               argA[j] = (const GLchan (*)[4])
+                  (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan)));
+            }
       }
 
-      switch (textureUnit->CombineSourceRGB[j]) {
+      switch (srcRGB) {
          case GL_TEXTURE:
-            argRGB[j] = texel;
+            argRGB[j] = (const GLchan (*)[4])
+               (texelBuffer + unit * (n * 4 * sizeof(GLchan)));
             break;
          case GL_PRIMARY_COLOR_EXT:
             argRGB[j] = primary_rgba;
@@ -2607,7 +2632,16 @@ texture_combine(const GLcontext *ctx,
             }
             break;
          default:
-            _mesa_problem(ctx, "invalid combine source");
+            /* ARB_texture_env_crossbar source */
+            {
+               const GLuint srcUnit = srcRGB - GL_TEXTURE0_ARB;
+               ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
+               if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
+                  return;
+               argRGB[j] = (const GLchan (*)[4])
+                  (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan)));
+               printf("unit %d from unit %d\n", unit, srcUnit);
+            }
       }
 
       if (textureUnit->CombineOperandRGB[j] != GL_SRC_COLOR) {
@@ -2991,14 +3025,23 @@ texture_combine(const GLcontext *ctx,
 #undef PROD
 
 
+/**
+ * Implement NVIDIA's GL_NV_texture_env_combine4 extension when
+ * texUnit->EnvMode == GL_COMBINE4_NV.
+ */
+static INLINE void
+texture_combine4( const GLcontext *ctx, GLuint unit, GLuint n,
+                  CONST GLchan (*primary_rgba)[4],
+                  CONST GLchan *texelBuffer,
+                  GLchan (*rgba)[4] )
+{
+}
 
-/**********************************************************************/
-/*                      Texture Application                           */
-/**********************************************************************/
 
 
-/*
- * Combine incoming fragment color with texel color to produce output color.
+/**
+ * Apply a conventional OpenGL texture env mode (REPLACE, ADD, BLEND,
+ * MODULATE, or DECAL) to an array of fragments.
  * Input:  textureUnit - pointer to texture unit to apply
  *         format - base internal texture format
  *         n - number of fragments
@@ -3008,7 +3051,7 @@ texture_combine(const GLcontext *ctx,
  *                according to the texture environment mode.
  */
 static void
-apply_texture( const GLcontext *ctx,
+texture_apply( const GLcontext *ctx,
                const struct gl_texture_unit *texUnit,
                GLuint n,
                CONST GLchan primary_rgba[][4], CONST GLchan texel[][4],
@@ -3087,7 +3130,7 @@ apply_texture( const GLcontext *ctx,
               }
               break;
             default:
-               _mesa_problem(ctx, "Bad format (GL_REPLACE) in apply_texture");
+               _mesa_problem(ctx, "Bad format (GL_REPLACE) in texture_apply");
                return;
         }
         break;
@@ -3153,7 +3196,7 @@ apply_texture( const GLcontext *ctx,
               }
               break;
             default:
-               _mesa_problem(ctx, "Bad format (GL_MODULATE) in apply_texture");
+               _mesa_problem(ctx, "Bad format (GL_MODULATE) in texture_apply");
                return;
         }
         break;
@@ -3186,7 +3229,7 @@ apply_texture( const GLcontext *ctx,
               }
               break;
             default:
-               _mesa_problem(ctx, "Bad format (GL_DECAL) in apply_texture");
+               _mesa_problem(ctx, "Bad format (GL_DECAL) in texture_apply");
                return;
         }
         break;
@@ -3256,7 +3299,7 @@ apply_texture( const GLcontext *ctx,
               }
               break;
             default:
-               _mesa_problem(ctx, "Bad format (GL_BLEND) in apply_texture");
+               _mesa_problem(ctx, "Bad format (GL_BLEND) in texture_apply");
                return;
         }
         break;
@@ -3333,63 +3376,57 @@ apply_texture( const GLcontext *ctx,
                }
                break;
             default:
-               _mesa_problem(ctx, "Bad format (GL_ADD) in apply_texture");
+               _mesa_problem(ctx, "Bad format (GL_ADD) in texture_apply");
                return;
         }
         break;
 
-      case GL_COMBINE_EXT:
-         texture_combine(ctx, texUnit, n, primary_rgba, texel, rgba);
-         break;
-
       default:
-         _mesa_problem(ctx, "Bad env mode in apply_texture");
+         _mesa_problem(ctx, "Bad env mode in texture_apply");
          return;
    }
 }
 
 
 
-/*
- * Apply a unit of texture mapping to the incoming fragments.
+/**
+ * Apply texture mapping to a span of fragments.
  */
 void
-_swrast_texture_fragments( GLcontext *ctx, GLuint texUnit,
-                          struct sw_span *span,
-                          CONST GLchan primary_rgba[][4])
+_swrast_texture_span( GLcontext *ctx, struct sw_span *span )
 {
-   const GLuint mask = TEXTURE0_ANY << (texUnit * 4);
-   GLfloat (*texcoords)[4] = span->texcoords[texUnit];
-   GLfloat *lambda = span->lambda[texUnit];
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
+   GLchan primary_rgba[MAX_WIDTH][4];
+   GLuint unit;
 
+   ASSERT(span->end < MAX_WIDTH);
+   ASSERT(span->arrayMask & SPAN_TEXTURE);
 
-   if (ctx->Texture._ReallyEnabled & mask) {
-      const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit];
+   /*
+    * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR)
+    */
+   if (swrast->_AnyTextureCombine)
+      MEMCPY(primary_rgba, span->color.rgba, 4 * span->end * sizeof(GLchan));
 
-      ASSERT(span->arrayMask & SPAN_TEXTURE);
-      
-      if (textureUnit->_Current) {   /* XXX need this? */
-         const struct gl_texture_object *curObj = textureUnit->_Current;
-         GLchan texel[MAX_WIDTH][4];
-         
+   /*
+    * Must do all texture sampling before combining in order to
+    * accomodate GL_ARB_texture_env_crossbar.
+    */
+   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
+      if (ctx->Texture.Unit[unit]._ReallyEnabled) {
+         const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+         const struct gl_texture_object *curObj = texUnit->_Current;
+         GLfloat *lambda = span->lambda[unit];
+         GLchan (*texels)[4] = (GLchan (*)[4])
+            (swrast->TexelBuffer + unit * (span->end * 4 * sizeof(GLchan)));
+
+         /* adjust texture lod (lambda) */
          if (span->arrayMask | SPAN_LAMBDA) {
-#if 0
-            float min, max;
-            int i;
-            min = max = lambda[0];
-            for (i = 1; i < span->end; i++) {
-               if (lambda[i] > max)
-                  max = lambda[i];
-               if (lambda[i] < min)
-                  min = lambda[i];
-            }
-            printf("min/max %g / %g\n", min, max);
-#endif
-            if (textureUnit->LodBias != 0.0F) {
+            if (texUnit->LodBias != 0.0F) {
                /* apply LOD bias, but don't clamp yet */
                GLuint i;
-               for (i=0;i<span->end;i++) {
-                  lambda[i] += textureUnit->LodBias;
+               for (i = 0; i < span->end; i++) {
+                  lambda[i] += texUnit->LodBias;
                }
             }
 
@@ -3398,60 +3435,50 @@ _swrast_texture_fragments( GLcontext *ctx, GLuint texUnit,
                const GLfloat min = curObj->MinLod;
                const GLfloat max = curObj->MaxLod;
                GLuint i;
-               for (i=0;i<span->end;i++) {
+               for (i = 0; i < span->end; i++) {
                   GLfloat l = lambda[i];
                   lambda[i] = CLAMP(l, min, max);
                }
             }
          }
 
-         /* Sample the texture for n fragments */
-         SWRAST_CONTEXT(ctx)->TextureSample[texUnit]( ctx, texUnit,
-                                                      textureUnit->_Current,
-                                                      span->end, texcoords,
-                                                      lambda, texel );
-
-         apply_texture( ctx, textureUnit, span->end, primary_rgba,
-                        (const GLchan (*)[4]) texel, span->color.rgba );
+         /* Sample the texture (span->end fragments) */
+         swrast->TextureSample[unit]( ctx, unit, texUnit->_Current,
+                                      span->end, span->texcoords[unit],
+                                      lambda, texels );
       }
    }
-}
-
 
-/*
- * Apply multiple texture stages (or just unit 0) to the span.
- * At some point in the future we'll probably modify this so that
- * texels from any texture unit are available in any combiner unit.
- * That'll require doing all the texture sampling first, and then
- * all the application (blending) afterward.
- */
-void
-_swrast_multitexture_fragments( GLcontext *ctx, struct sw_span *span )
-{
-   if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) {
-      /* multitexture */
-      GLchan primary_rgba[MAX_WIDTH][4];
-      GLuint unit;
-
-      ASSERT(span->end < MAX_WIDTH);
-      ASSERT(span->arrayMask & SPAN_TEXTURE);
-
-      /* save copy of the span colors (the GL_PRIMARY_COLOR) */
-      MEMCPY(primary_rgba, span->color.rgba, 4 * span->end * sizeof(GLchan));
-
-      /* loop over texture units, modifying the span->color.rgba values */
-      for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
-         if (ctx->Texture.Unit[unit]._ReallyEnabled) {
-            _swrast_texture_fragments( ctx, unit, span,
-                                      (CONST GLchan (*)[4]) primary_rgba);
+   /*
+    * OK, now apply the texture (aka texture combine/blend).
+    * We modify the span->color.rgba values.
+    */
+   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
+      if (ctx->Texture.Unit[unit]._ReallyEnabled) {
+         const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+         if (texUnit->EnvMode == GL_COMBINE_EXT) {
+            /* GL_ARB/EXT_texture_env_combine */
+            texture_combine( ctx, unit, span->end,
+                             (CONST GLchan (*)[4]) primary_rgba,
+                             swrast->TexelBuffer,
+                             span->color.rgba );
+         }
+         else if (texUnit->EnvMode == GL_COMBINE4_NV) {
+            /* GL_NV_texture_env_combine4 */
+            texture_combine4( ctx, unit, span->end,
+                              (CONST GLchan (*)[4]) primary_rgba,
+                              swrast->TexelBuffer,
+                              span->color.rgba );
+         }
+         else {
+            /* conventional texture blend */
+            const GLchan (*texels)[4] = (const GLchan (*)[4])
+               (swrast->TexelBuffer + unit *
+                (span->end * 4 * sizeof(GLchan)));
+            texture_apply( ctx, texUnit, span->end,
+                           (CONST GLchan (*)[4]) primary_rgba, texels,
+                           span->color.rgba );
          }
       }
    }
-   else {
-      /* Just unit 0 enabled */
-      ASSERT(ctx->Texture._ReallyEnabled & TEXTURE0_ANY);
-
-      _swrast_texture_fragments( ctx, 0, span,
-                                (CONST GLchan (*)[4]) span->color.rgba);
-   }
 }
index 91f147a..a920c0f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: s_texture.h,v 1.12 2002/04/12 15:39:59 brianp Exp $ */
+/* $Id: s_texture.h,v 1.13 2002/05/02 00:59:20 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -40,12 +40,6 @@ _swrast_choose_texture_sample_func( GLcontext *ctx,
 
 
 extern void
-_swrast_texture_fragments( GLcontext *ctx, GLuint texUnit,
-                          struct sw_span *span,
-                          CONST GLchan primary_rgba[][4]);
-
-
-extern void
-_swrast_multitexture_fragments( GLcontext *ctx, struct sw_span *span );
+_swrast_texture_span( GLcontext *ctx, struct sw_span *span );
 
 #endif