enable GL_EXT_fog_coord. Calculate fog factors and submit them instead of fog coords...
authorRoland Scheidegger <rscheidegger@gmx.ch>
Wed, 3 Nov 2004 17:29:39 +0000 (17:29 +0000)
committerRoland Scheidegger <rscheidegger@gmx.ch>
Wed, 3 Nov 2004 17:29:39 +0000 (17:29 +0000)
src/mesa/drivers/dri/r200/r200_context.c
src/mesa/drivers/dri/r200/r200_context.h
src/mesa/drivers/dri/r200/r200_maos_arrays.c
src/mesa/drivers/dri/r200/r200_state.c
src/mesa/drivers/dri/r200/r200_swtcl.c
src/mesa/drivers/dri/r200/r200_tcl.c
src/mesa/drivers/dri/r200/r200_tcl.h
src/mesa/drivers/dri/r200/r200_vtxfmt.c
src/mesa/drivers/dri/r200/r200_vtxfmt_c.c

index 0868febc34610de9c995f186676c42bb55f43e37..d5d2ce150a513b1ec68db8b65a55a5a54be5718b 100644 (file)
@@ -131,6 +131,7 @@ static const char * const card_extensions[] =
     "GL_ARB_vertex_buffer_object",
     "GL_EXT_blend_minmax",
     "GL_EXT_blend_subtract",
+    "GL_EXT_fog_coord",
     "GL_EXT_secondary_color",
     "GL_EXT_stencil_wrap",
     "GL_EXT_texture_edge_clamp",
@@ -252,6 +253,9 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
    rmesa = (r200ContextPtr) CALLOC( sizeof(*rmesa) );
    if ( !rmesa )
       return GL_FALSE;
+      
+   /* init exp fog table data */
+   r200InitStaticFogData();
 
    /* Parse configuration files.
     * Do this here so that initialMaxAnisotropy is set before we create
index af07653244c04a6a94f2f52521b0c1d0720c22e5..9af5c9390aa43fd33bcb5ac2fadea0a4c453bc62 100644 (file)
@@ -731,6 +731,8 @@ struct dfn_lists {
    struct dynfn MultiTexCoord2fvARB;
    struct dynfn MultiTexCoord1fARB;
    struct dynfn MultiTexCoord1fvARB;
+   struct dynfn FogCoordfEXT;
+   struct dynfn FogCoordfvEXT;
 };
 
 struct dfn_generators {
@@ -764,6 +766,8 @@ struct dfn_generators {
    struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, const int * );
    struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, const int * );
    struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, const int * );
+   struct dynfn *(*FogCoordfEXT)( GLcontext *, const int * );
+   struct dynfn *(*FogCoordfvEXT)( GLcontext *, const int * );
 };
 
 
@@ -797,6 +801,7 @@ struct r200_vbinfo {
 
    GLfloat *normalptr;
    GLfloat *floatcolorptr;
+   GLfloat *fogptr;
    r200_color_t *colorptr;
    GLfloat *floatspecptr;
    r200_color_t *specptr;
index 0f8ca3048ed772a9b9f9f7ba5186c48f7cb62ad7..12ea462a400abea13205df635bf151ff7dcf5c04 100644 (file)
@@ -49,6 +49,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r200_state.h"
 #include "r200_swtcl.h"
 #include "r200_maos.h"
+#include "r200_tcl.h"
 
 
 #if 0
@@ -175,7 +176,47 @@ do {                                               \
 #endif
 
 
+static void emit_vecfog( GLcontext *ctx,
+                        struct r200_dma_region *rvb,
+                        char *data,
+                        int stride,
+                        int count )
+{
+   int i;
+   GLfloat *out;
 
+   r200ContextPtr rmesa = R200_CONTEXT(ctx);
+   
+   if (R200_DEBUG & DEBUG_VERTS)
+      fprintf(stderr, "%s count %d stride %d\n",
+             __FUNCTION__, count, stride);
+
+   assert (!rvb->buf);
+
+   if (stride == 0) {
+      r200AllocDmaRegion( rmesa, rvb, 4, 4 );
+      count = 1;
+      rvb->aos_start = GET_START(rvb);
+      rvb->aos_stride = 0;
+      rvb->aos_size = 1;
+   }
+   else {
+      r200AllocDmaRegion( rmesa, rvb, count * 4, 4 );  /* alignment? */
+      rvb->aos_start = GET_START(rvb);
+      rvb->aos_stride = 1;
+      rvb->aos_size = 1;
+   }
+
+   /* Emit the data
+    */
+   out = (GLfloat *)(rvb->address + rvb->start);
+   for (i = 0; i < count; i++) {
+      out[0] = r200ComputeFogBlendFactor( ctx, *(GLfloat *)data );
+      out++;
+      data += stride;
+   }
+
+}
 
 
 static void emit_vec4( GLcontext *ctx,
@@ -378,6 +419,18 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs )
       component[nr++] = &rmesa->tcl.norm;
    }
 
+   if (inputs & VERT_BIT_FOG) {
+      if (!rmesa->tcl.fog.buf)
+        emit_vecfog( ctx, 
+                     &(rmesa->tcl.fog), 
+                     (char *)VB->FogCoordPtr->data,
+                     VB->FogCoordPtr->stride,
+                     count);
+
+      vfmt0 |= R200_VTX_DISCRETE_FOG;
+      component[nr++] = &rmesa->tcl.fog;
+   }
    if (inputs & VERT_BIT_COLOR0) {
       int emitsize;
 
@@ -460,6 +513,9 @@ void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs )
 
    if (newinputs & VERT_BIT_NORMAL) 
       r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ );
+      
+   if (newinputs & VERT_BIT_FOG) 
+      r200ReleaseDmaRegion( rmesa, &rmesa->tcl.fog, __FUNCTION__ );
 
    if (newinputs & VERT_BIT_COLOR0) 
       r200ReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ );
index 825c036e272c5bb1cd38f35a553d022172eb253b..7701256edf21f9949c8db945d734c762e36969ab 100644 (file)
@@ -468,10 +468,37 @@ static void r200Fogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
       rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_COLOR_MASK;
       rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= i;
       break;
-   case GL_FOG_COORDINATE_SOURCE_EXT: 
-      /* What to do?
-       */
+   case GL_FOG_COORD_SRC: {
+      GLuint fmt_0 = rmesa->hw.vtx.cmd[VTX_VTXFMT_0];
+      GLuint out_0 = rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0];
+      GLuint fog   = rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR];
+
+      fog &= ~R200_FOG_USE_MASK;
+      if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) {
+        fog   |= R200_FOG_USE_VTX_FOG;
+        fmt_0 |= R200_VTX_DISCRETE_FOG;
+        out_0 |= R200_VTX_DISCRETE_FOG;
+      }
+      else {
+        fog   |=  R200_FOG_USE_SPEC_ALPHA;
+        fmt_0 &= ~R200_VTX_DISCRETE_FOG;
+        out_0 &= ~R200_VTX_DISCRETE_FOG;
+      }
+
+      if ( fog != rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] ) {
+        R200_STATECHANGE( rmesa, ctx );
+        rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = fog;
+      }
+
+      if ( (fmt_0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0])
+          || (out_0 != rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0])) {
+        R200_STATECHANGE( rmesa, vtx );
+        rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = fmt_0;
+        rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] = out_0;     
+      }
+
       break;
+   }
    default:
       return;
    }
index 4c6f19da4f0023f5129c032d81873104a842a4d0..7fb91a0730bc6eb7d3be20e51fd9be2e5cbe6c39 100644 (file)
@@ -172,7 +172,12 @@ static void r200SetVertexFormat( GLcontext *ctx )
       }
    }
 
-
+   if ( (rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] & R200_FOG_USE_MASK)
+      != R200_FOG_USE_SPEC_ALPHA ) {
+      R200_STATECHANGE( rmesa, ctx );
+      rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_USE_MASK;
+      rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= R200_FOG_USE_SPEC_ALPHA;
+   }
 
    if ( rmesa->tnl_index != index ||
        (rmesa->hw.vtx.cmd[VTX_VTXFMT_0] != fmt_0) ||
index 78d16ed0f3b5ecd4114b49ab792a618149c6b033..d2dfc5fda17070fcb45d63222b19c57e4bf7f222 100644 (file)
@@ -268,6 +268,90 @@ void r200TclPrimitive( GLcontext *ctx,
 }
 
 
+/**********************************************************************/
+/*             Fog blend factor computation for hw tcl                */
+/*             same calculation used as in t_vb_fog.c                 */
+/**********************************************************************/
+
+#define FOG_EXP_TABLE_SIZE 256
+#define FOG_MAX (10.0)
+#define EXP_FOG_MAX .0006595
+#define FOG_INCR (FOG_MAX/FOG_EXP_TABLE_SIZE)
+static GLfloat exp_table[FOG_EXP_TABLE_SIZE];
+
+#if 1
+#define NEG_EXP( result, narg )                                                \
+do {                                                                   \
+   GLfloat f = (GLfloat) (narg * (1.0/FOG_INCR));                      \
+   GLint k = (GLint) f;                                                        \
+   if (k > FOG_EXP_TABLE_SIZE-2)                                       \
+      result = (GLfloat) EXP_FOG_MAX;                                  \
+   else                                                                        \
+      result = exp_table[k] + (f-k)*(exp_table[k+1]-exp_table[k]);     \
+} while (0)
+#else
+#define NEG_EXP( result, narg )                                        \
+do {                                                           \
+   result = exp(-narg);                                                \
+} while (0)
+#endif
+
+
+/**
+ * Initialize the exp_table[] lookup table for approximating exp().
+ */
+void
+r200InitStaticFogData( void )
+{
+   GLfloat f = 0.0F;
+   GLint i = 0;
+   for ( ; i < FOG_EXP_TABLE_SIZE ; i++, f += FOG_INCR) {
+      exp_table[i] = (GLfloat) exp(-f);
+   }
+}
+
+
+/**
+ * Compute per-vertex fog blend factors from fog coordinates by
+ * evaluating the GL_LINEAR, GL_EXP or GL_EXP2 fog function.
+ * Fog coordinates are distances from the eye (typically between the
+ * near and far clip plane distances).
+ * Note the fog (eye Z) coords may be negative so we use ABS(z) below.
+ * Fog blend factors are in the range [0,1].
+ */
+float
+r200ComputeFogBlendFactor( GLcontext *ctx, GLfloat fogcoord )
+{
+   GLfloat end  = ctx->Fog.End;
+   GLfloat d, temp;
+   const GLfloat z = FABSF(fogcoord);
+
+   switch (ctx->Fog.Mode) {
+   case GL_LINEAR:
+      if (ctx->Fog.Start == ctx->Fog.End)
+         d = 1.0F;
+      else
+         d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
+      temp = (end - z) * d;
+      return CLAMP(temp, 0.0F, 1.0F);
+      break;
+   case GL_EXP:
+      d = ctx->Fog.Density;
+      NEG_EXP( temp, d * z );
+      return temp;
+      break;
+   case GL_EXP2:
+      d = ctx->Fog.Density*ctx->Fog.Density;
+      NEG_EXP( temp, d * z * z );
+      return temp;
+      break;
+   default:
+      _mesa_problem(ctx, "Bad fog mode in make_fog_coord");
+      return 0;
+   }
+}
+
+
 /**********************************************************************/
 /*                          Render pipeline stage                     */
 /**********************************************************************/
@@ -349,6 +433,10 @@ static void r200_check_tcl_render( GLcontext *ctx,
         }
       }
 
+      if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) {
+        inputs |= VERT_BIT_FOG;
+      }
+
       for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
         if (ctx->Texture.Unit[unit]._ReallyEnabled) {
            if (rmesa->TexGenNeedNormals[unit]) {
@@ -457,6 +545,14 @@ static void transition_to_hwtnl( GLcontext *ctx )
    rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_TCL_ENABLE;
    rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_FORCE_W_TO_ONE;
 
+   if ( ((rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] & R200_FOG_USE_MASK)
+      == R200_FOG_USE_SPEC_ALPHA) &&
+      (ctx->Fog.FogCoordinateSource == GL_FOG_COORD )) {
+      R200_STATECHANGE( rmesa, ctx );
+      rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_USE_MASK;
+      rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= R200_FOG_USE_VTX_FOG;
+   }
+   
    R200_STATECHANGE( rmesa, vte );
    rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VTX_XY_FMT|R200_VTX_Z_FMT);
 
index b6ec8e28f8b71dc9a61179631aeb393c0a884129..7dd43bf7facceb9c3900a50af290808362f3f66a 100644 (file)
@@ -47,6 +47,10 @@ extern void r200EmitPrimitive( GLcontext *ctx, GLuint first, GLuint last,
                                 GLuint flags );
 
 extern void r200TclFallback( GLcontext *ctx, GLuint bit, GLboolean mode );
+
+extern void r200InitStaticFogData( void );
+
+extern float r200ComputeFogBlendFactor( GLcontext *ctx, GLfloat fogcoord );
                                              
 #define R200_TCL_FALLBACK_RASTER            0x1 /* rasterization */
 #define R200_TCL_FALLBACK_UNFILLED          0x2 /* unfilled tris */
index 7a2fa35d44f368d550335069d91f00d533fd5f2b..fde214102627cb6bd77e34c4b29b98de6112cb15 100644 (file)
@@ -100,6 +100,8 @@ static void count_funcs( r200ContextPtr rmesa )
    count_func( "MultiTexCoord2fvARB", &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
    count_func( "MultiTexCoord1fARB", &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
    count_func( "MultiTexCoord1fvARB", &rmesa->vb.dfn_cache.MultiTexCoord1fvARB );
+/*   count_func( "FogCoordfEXT", &rmesa->vb.dfn_cache.FogCoordfEXT );
+   count_func( "FogCoordfvEXT", &rmesa->vb.dfn_cache.FogCoordfvEXT );*/
 }
 
 
@@ -119,6 +121,10 @@ void r200_copy_to_current( GLcontext *ctx )
       ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2] = rmesa->vb.normalptr[2];
    }
 
+   if (rmesa->vb.vtxfmt_0 & R200_VTX_DISCRETE_FOG) {
+      ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = rmesa->vb.fogptr[0];
+   }
+
    switch( VTX_COLOR(rmesa->vb.vtxfmt_0, 0) ) {
    case R200_VTX_PK_RGBA:
       ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->red );
@@ -474,6 +480,11 @@ void VFMT_FALLBACK( const char *caller )
         offset += 3;
       }
 
+      if (ind0 & R200_VTX_DISCRETE_FOG) {
+        GL_CALL(FogCoordfvEXT)( &tmp[i][offset] ); 
+        offset++;
+      }
+
       if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) {
         GL_CALL(Color4ubv)( (GLubyte *)&tmp[i][offset] ); 
         offset++;
@@ -504,7 +515,10 @@ void VFMT_FALLBACK( const char *caller )
    /* Replay current vertex
     */
    if (ind0 & R200_VTX_N0) 
-       GL_CALL(Normal3fv)( rmesa->vb.normalptr );
+      GL_CALL(Normal3fv)( rmesa->vb.normalptr );
+   if (ind0 & R200_VTX_DISCRETE_FOG) {
+      GL_CALL(FogCoordfvEXT)( rmesa->vb.fogptr ); 
+   }
 
    if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) {
       GL_CALL(Color4ub)( rmesa->vb.colorptr->red,
@@ -672,6 +686,10 @@ static GLboolean check_vtx_fmt( GLcontext *ctx )
       }
    }
 
+   if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) {
+      ind0 |= R200_VTX_DISCRETE_FOG;
+   }
+
    for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) {
       count[i] = 0;
 
@@ -711,6 +729,7 @@ static GLboolean check_vtx_fmt( GLcontext *ctx )
    rmesa->vb.normalptr = ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
    rmesa->vb.colorptr = NULL;
    rmesa->vb.floatcolorptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
+   rmesa->vb.fogptr = ctx->Current.Attrib[VERT_ATTRIB_FOG];
    rmesa->vb.specptr = NULL;
    rmesa->vb.floatspecptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
    rmesa->vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
@@ -733,6 +752,12 @@ static GLboolean check_vtx_fmt( GLcontext *ctx )
       rmesa->vb.normalptr[2] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2];
    }
 
+   if (ind0 & R200_VTX_DISCRETE_FOG) {
+      rmesa->vb.fogptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f;
+      rmesa->vb.vertex_size += 1;
+      rmesa->vb.fogptr[0] = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
+   }
+
    if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) {
       rmesa->vb.colorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color;
       rmesa->vb.vertex_size += 1;
@@ -1060,8 +1085,6 @@ void r200VtxfmtInit( GLcontext *ctx, GLboolean useCodegen )
 
    /* Not active in supported states; just keep ctx->Current uptodate:
     */
-   vfmt->FogCoordfvEXT = _mesa_noop_FogCoordfvEXT;
-   vfmt->FogCoordfEXT = _mesa_noop_FogCoordfEXT;
    vfmt->EdgeFlag = _mesa_noop_EdgeFlag;
    vfmt->EdgeFlagv = _mesa_noop_EdgeFlagv;
    vfmt->Indexf = _mesa_noop_Indexf;
@@ -1094,7 +1117,9 @@ void r200VtxfmtInit( GLcontext *ctx, GLboolean useCodegen )
    vfmt->VertexAttrib3fvNV = r200_fallback_VertexAttrib3fvNV;
    vfmt->VertexAttrib4fNV  = r200_fallback_VertexAttrib4fNV;
    vfmt->VertexAttrib4fvNV = r200_fallback_VertexAttrib4fvNV;
-
+   vfmt->FogCoordfEXT = r200_fallback_FogCoordfEXT;
+   vfmt->FogCoordfvEXT = r200_fallback_FogCoordfvEXT;
+   
    (void)r200_fallback_vtxfmt;
 
    TNL_CONTEXT(ctx)->Driver.NotifyBegin = r200NotifyBegin;
@@ -1133,6 +1158,8 @@ void r200VtxfmtInit( GLcontext *ctx, GLboolean useCodegen )
    make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
    make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
    make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB );
+/*   make_empty_list( &rmesa->vb.dfn_cache.FogCoordfEXT );
+   make_empty_list( &rmesa->vb.dfn_cache.FogCoordfvEXT );*/
 
    r200InitCodegen( &rmesa->vb.codegen, useCodegen );
 }
@@ -1192,5 +1219,7 @@ void r200VtxfmtDestroy( GLcontext *ctx )
    free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB );
    free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fARB );
    free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB );
+/*   free_funcs( &rmesa->vb.dfn_cache.FogCoordfEXT );
+   free_funcs( &rmesa->vb.dfn_cache.FogCoordfvEXT );*/
 }
 
index 70301afb04e33126c432a1f113a98b71b1d61a8d..670a2fb05a5077149ef79133437e9d6810f79b88 100644 (file)
@@ -42,6 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "vtxfmt.h"
 
 #include "r200_vtxfmt.h"
+#include "r200_tcl.h"
 
 /* Fallback versions of all the entrypoints for situations where
  * codegen isn't available.  This is still a lot faster than the
@@ -512,6 +513,27 @@ static void r200_Normal3fv( const GLfloat *v )
 }
 
 
+/* FogCoord
+ */
+static void r200_FogCoordfEXT( GLfloat f )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   r200ContextPtr rmesa = R200_CONTEXT(ctx);
+   GLfloat *dest = rmesa->vb.fogptr;
+   dest[0] = r200ComputeFogBlendFactor( ctx, f );
+/*   ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = f;*/
+}
+
+static void r200_FogCoordfvEXT( const GLfloat *v )
+{
+   GET_CURRENT_CONTEXT(ctx);
+   r200ContextPtr rmesa = R200_CONTEXT(ctx);
+   GLfloat *dest = rmesa->vb.fogptr;
+   dest[0] = r200ComputeFogBlendFactor( ctx, v[0] );
+/*   ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = v[0];*/
+}
+
+
 /* TexCoord
  */
 
@@ -778,7 +800,8 @@ static void choose_##FN ARGS1                                               \
  */
 #define MASK_XYZW  (R200_VTX_W0|R200_VTX_Z0)
 #define MASK_NORM  (MASK_XYZW|R200_VTX_N0)
-#define MASK_COLOR (MASK_NORM |(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_0_SHIFT))
+#define MASK_FOG   (MASK_NORM |R200_VTX_DISCRETE_FOG)
+#define MASK_COLOR (MASK_FOG |(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_0_SHIFT))
 #define MASK_SPEC  (MASK_COLOR|(R200_VTX_COLOR_MASK<<R200_VTX_COLOR_1_SHIFT))
 
 /* VTXFMT_1
@@ -871,6 +894,10 @@ CHOOSE(Vertex2f, p2f, ~0, ~0,
 CHOOSE(Vertex2fv, pfv, ~0, ~0, 
        (const GLfloat *v), (v))
 
+CHOOSE(FogCoordfEXT, p1f, MASK_FOG, ~0, 
+       (GLfloat f), (f))
+CHOOSE(FogCoordfvEXT, pfv, MASK_FOG, ~0, 
+       (const GLfloat *f), (f))
 
 
 
@@ -901,6 +928,8 @@ void r200VtxfmtInitChoosers( GLvertexformat *vfmt )
    vfmt->Vertex2fv = choose_Vertex2fv;
    vfmt->Vertex3f = choose_Vertex3f;
    vfmt->Vertex3fv = choose_Vertex3fv;
+/*   vfmt->FogCoordfEXT = choose_FogCoordfEXT;
+   vfmt->FogCoordfvEXT = choose_FogCoordfvEXT;*/
 
    /* TODO: restore ubyte colors to vtxfmt.
     */
@@ -943,6 +972,8 @@ void r200InitCodegen( struct dfn_generators *gen, GLboolean useCodegen )
    gen->MultiTexCoord2fvARB = codegen_noop;
    gen->MultiTexCoord1fARB = codegen_noop;
    gen->MultiTexCoord1fvARB = codegen_noop;
+/*   gen->FogCoordfEXT = codegen_noop;
+   gen->FogCoordfvEXT = codegen_noop;*/
 
    gen->Vertex2f = codegen_noop;
    gen->Vertex2fv = codegen_noop;