implement arb_vertex_program in hw for r200. Code contains still some hacks, generic...
[mesa.git] / src / mesa / drivers / glide / fxsetup.c
index 6ebdb717d0bc9f8e25a7283c1bb8a2abe4185466..240e5e0b5970dc2e77d0dcb8d56a15c2a45398fe 100644 (file)
 
 #include "fxdrv.h"
 #include "enums.h"
+#include "tnl.h"
 #include "tnl/t_context.h"
+#include "swrast.h"
+#include "texstore.h"
+
 
 static void
 fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj)
@@ -67,16 +71,9 @@ fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj)
 
 #if FX_RESCALE_BIG_TEXURES_HACK
 {
-   extern void _mesa_rescale_teximage2d( GLuint bytesPerPixel,
-                                         GLuint dstRowStride,
-                                         GLint srcWidth, GLint srcHeight,
-                                         GLint dstWidth, GLint dstHeight,
-                                         const GLvoid *srcImage, GLvoid *dstImage );
    fxMesaContext fxMesa = FX_CONTEXT(ctx);
    /* [dBorca]
-    * Ooooooook! Here's a(nother) long story.
-    * We get here because we need to handle a texture larger
-    * than hardware can support. Two cases:
+    * Fake textures larger than HW supports:
     * 1) we have mipmaps. Then we just push up to the first supported
     *    LOD. A possible drawback is that Mesa will ignore the skipped
     *    LODs on further texture handling.
@@ -86,13 +83,6 @@ fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj)
     *    once in TexImage2D to accomodate aspect ratio, and now we
     *    are rescaling again. The thing is, in TexImage2D we don't
     *    know whether we'll hit 1) or 2) by the time of validation.
-    * NB: we could handle mml->[wh]Scale nicely, using (biased) shifts.
-    *
-    * Which brings me to another issue. How can we handle NPOT textures?
-    * - rescaling NPOT to the next bigger POT (mml->[wh]Scale can't shift)
-    * - upping the max LOD to the next power-of-two, in fxTexGetInfo; then
-    *   choosing non-power-of-two values for ti->[st]Scale... Anyhow, we
-    *   still need to align mipmaps correctly in texture memory!
     */
    if ((tObj->MinFilter == GL_NEAREST) || (tObj->MinFilter == GL_LINEAR)) {
       /* no mipmaps! */
@@ -116,13 +106,14 @@ fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj)
                       &(mml->wScale), &(mml->hScale));
          _w *= mml->wScale;
          _h *= mml->hScale;
-         texImage->Data = MESA_PBUFFER_ALLOC(_w * _h * texelBytes);
+         texImage->Data = _mesa_malloc(_w * _h * texelBytes);
          _mesa_rescale_teximage2d(texelBytes,
+                                  mml->width,
                                   _w * texelBytes, /* dst stride */
                                   mml->width, mml->height, /* src */
                                   _w, _h, /* dst */
                                   texImage_Data /*src*/, texImage->Data /*dst*/ );
-         MESA_PBUFFER_FREE(texImage_Data);
+         _mesa_free(texImage_Data);
          mml->width = _w;
          mml->height = _h;
          /* (!) ... and set mml->wScale = _w / texImage->Width */
@@ -153,6 +144,16 @@ fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj)
    else
       FX_smallLodLog2(ti->info) = FX_largeLodLog2(ti->info);
 
+   /* [dBorca] this is necessary because of fxDDCompressedTexImage2D */
+   if (ti->padded) {
+      struct gl_texture_image *texImage = tObj->Image[0][minl];
+      tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
+      if (mml->wScale != 1 || mml->hScale != 1) {
+         ti->sScale /= mml->wScale;
+         ti->tScale /= mml->hScale;
+      }
+   }
+
    ti->baseLevelInternalFormat = tObj->Image[0][minl]->Format;
 
    ti->validated = GL_TRUE;
@@ -339,9 +340,7 @@ fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj)
       fprintf(stderr, "fxSetupSingleTMU_NoLock(%p (%d))\n", (void *)tObj, tObj->Name);
    }
 
-#if 1 /* [dBorca] Good... bad... I'm the guy with the gun! */
    ti->lastTimeUsed = fxMesa->texBindNumber;
-#endif
 
    /* Make sure we're not loaded incorrectly */
    if (ti->isInTM) {
@@ -382,15 +381,6 @@ fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj)
         }
         grTexDownloadTable(ti->paltype, &(ti->palette));
       }
-#if FX_TC_NCC
-      if ((ti->info.format == GR_TEXFMT_AYIQ_8422) ||
-          (ti->info.format == GR_TEXFMT_YIQ_422)) {
-        if (TDFX_DEBUG & VERBOSE_DRIVER) {
-           fprintf(stderr, "fxSetupSingleTMU_NoLock: uploading NCC table\n");
-        }
-        grTexDownloadTable(GR_TEXTABLE_NCC0, &(ti->palette));
-      }
-#endif
 
       grTexClampMode(GR_TMU0, ti->sClamp, ti->tClamp);
       grTexClampMode(GR_TMU1, ti->sClamp, ti->tClamp);
@@ -418,15 +408,6 @@ fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj)
         }
         fxMesa->Glide.grTexDownloadTableExt(tmu, ti->paltype, &(ti->palette));
       }
-#if FX_TC_NCC
-      if ((ti->info.format == GR_TEXFMT_AYIQ_8422) ||
-          (ti->info.format == GR_TEXFMT_YIQ_422)) {
-        if (TDFX_DEBUG & VERBOSE_DRIVER) {
-           fprintf(stderr, "fxSetupSingleTMU_NoLock: uploading NCC table\n");
-        }
-        fxMesa->Glide.grTexDownloadTableExt(tmu, GR_TEXTABLE_NCC0, &(ti->palette));
-      }
-#endif
 
       /* KW: The alternative is to do the download to the other tmu.  If
        * we get to this point, I think it means we are thrashing the
@@ -491,10 +472,7 @@ fxSelectSingleTMUSrc_NoLock(fxMesaContext fxMesa, GLint tmu, FxBool LODblend)
          tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
          tex1.FactorAlpha   = GR_COMBINE_FACTOR_NONE;
 
-        /* [dBorca] Hack alert:
-          * don't use GR_COMBINE_FUNCTION_SCALE_OTHER
-          * such that Glide recognizes TMU0 in passthrough mode
-          */
+        /* correct values to set TMU0 in passthrough mode */
          tex0.FunctionRGB   = GR_COMBINE_FUNCTION_BLEND;
          tex0.FactorRGB     = GR_COMBINE_FACTOR_ONE;
          tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND;
@@ -635,16 +613,25 @@ fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset)
          colorComb.Factor   = GR_COMBINE_FACTOR_NONE;
          colorComb.Other    = GR_COMBINE_OTHER_NONE;
       } else {
-         /* [dBorca] Hack alert:
-          * only Voodoo^2 can GL_BLEND (GR_COMBINE_FACTOR_TEXTURE_RGB)
-          */
          if (fxMesa->type >= GR_SSTTYPE_Voodoo2) {
             colorComb.Function = GR_COMBINE_FUNCTION_BLEND;
             colorComb.Factor   = GR_COMBINE_FACTOR_TEXTURE_RGB;
             colorComb.Other    = GR_COMBINE_OTHER_CONSTANT;
+         } else if (ifmt == GL_INTENSITY) {
+            /* just a hack: RGB == ALPHA */
+            colorComb.Function = GR_COMBINE_FUNCTION_BLEND;
+            colorComb.Factor   = GR_COMBINE_FACTOR_TEXTURE_ALPHA;
+            colorComb.Other    = GR_COMBINE_OTHER_CONSTANT;
          } else {
+            /* Only Voodoo^2 can GL_BLEND (GR_COMBINE_FACTOR_TEXTURE_RGB)
+             * These settings assume that the TexEnv color is black and
+             * incoming fragment color is white.
+             */
+            colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+            colorComb.Factor   = GR_COMBINE_FACTOR_ONE;
+            colorComb.Other    = GR_COMBINE_OTHER_TEXTURE;
+            colorComb.Invert   = FXTRUE;
             _mesa_problem(NULL, "can't GL_BLEND with SST1");
-            return;
          }
       }
 
@@ -692,7 +679,7 @@ fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset)
       }
       else {
          /* sum of texel and fragment alpha */
-         alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
+         alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
          alphaComb.Factor   = GR_COMBINE_FACTOR_ONE;
          alphaComb.Other    = GR_COMBINE_OTHER_TEXTURE;
       }
@@ -705,7 +692,7 @@ fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset)
       }
       else {
          /* sum of texel and fragment rgb */
-         colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
+         colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL;
          colorComb.Factor   = GR_COMBINE_FACTOR_ONE;
          colorComb.Other    = GR_COMBINE_OTHER_TEXTURE;
       }
@@ -869,23 +856,6 @@ fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa,
         fxMesa->Glide.grTexDownloadTableExt(ti0->whichTMU, ti0->paltype, &(ti0->palette));
       }
    }
-#if FX_TC_NCC
-   /* pointcast */
-   if ((ti1->info.format == GR_TEXFMT_AYIQ_8422) ||
-       (ti1->info.format == GR_TEXFMT_YIQ_422)) {
-      if (TDFX_DEBUG & VERBOSE_DRIVER) {
-         fprintf(stderr, "fxSetupDoubleTMU_NoLock: uploading NCC0 table for TMU1\n");
-      }
-      fxMesa->Glide.grTexDownloadTableExt(ti1->whichTMU, GR_TEXTABLE_NCC0, &(ti1->palette));
-   }
-   if ((ti0->info.format == GR_TEXFMT_AYIQ_8422) ||
-       (ti0->info.format == GR_TEXFMT_YIQ_422)) {
-      if (TDFX_DEBUG & VERBOSE_DRIVER) {
-         fprintf(stderr, "fxSetupDoubleTMU_NoLock: uploading NCC0 table for TMU0\n");
-      }
-      fxMesa->Glide.grTexDownloadTableExt(ti0->whichTMU, GR_TEXTABLE_NCC0, &(ti0->palette));
-   }
-#endif
 
    grTexSource(tmu0, ti0->tm[tmu0]->startAddr,
                         GR_MIPMAPLEVELMASK_BOTH, &(ti0->info));
@@ -1176,6 +1146,40 @@ fxSetupTextureDoubleTMU_NoLock(GLcontext * ctx)
          alphaComb.Other    = GR_COMBINE_OTHER_TEXTURE;
         break;
       }
+
+   case (FX_UM_E0_MODULATE | FX_UM_E1_REPLACE): /* Homeworld2 */
+      {
+         tex1.FunctionRGB   = GR_COMBINE_FUNCTION_ZERO;
+         tex1.FactorRGB     = GR_COMBINE_FACTOR_NONE;
+         tex1.FunctionAlpha = GR_COMBINE_FUNCTION_ZERO;
+         tex1.FactorAlpha   = GR_COMBINE_FACTOR_NONE;
+
+         tex0.FunctionRGB   = GR_COMBINE_FUNCTION_LOCAL;
+         tex0.FactorRGB     = GR_COMBINE_FACTOR_NONE;
+         tex0.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
+         tex0.FactorAlpha   = GR_COMBINE_FACTOR_NONE;
+
+         if (ifmt & (FX_UM_E0_RGB | FX_UM_E0_LUMINANCE)) {
+            alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
+            alphaComb.Factor   = GR_COMBINE_FACTOR_NONE;
+            alphaComb.Other    = GR_COMBINE_OTHER_NONE;
+         } else {
+            alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+            alphaComb.Factor   = GR_COMBINE_FACTOR_ONE;
+            alphaComb.Other    = GR_COMBINE_OTHER_TEXTURE;
+         }
+
+         if (ifmt & FX_UM_E0_ALPHA) {
+            colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
+            colorComb.Factor   = GR_COMBINE_FACTOR_NONE;
+            colorComb.Other    = GR_COMBINE_OTHER_NONE;
+         } else {
+            colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+            colorComb.Factor   = GR_COMBINE_FACTOR_ONE;
+            colorComb.Other    = GR_COMBINE_OTHER_TEXTURE;
+         }
+         break;
+      }
    default:
       fprintf(stderr, "fxSetupTextureDoubleTMU_NoLock: Unexpected dual texture mode encountered\n");
       return;
@@ -1318,7 +1322,7 @@ fxDDBlendFuncSeparate(GLcontext * ctx, GLenum sfactor, GLenum dfactor, GLenum as
    GLboolean haveAlpha = fxMesa->haveHwAlpha;
    GrAlphaBlendFnc_t sfact, dfact, asfact, adfact;
 
-   /* [dBorca] Hack alert:
+   /*
     * 15/16 BPP alpha channel alpha blending modes
     *   0x0    AZERO           Zero
     *   0x4    AONE            One
@@ -1501,7 +1505,6 @@ fxDDBlendEquationSeparate(GLcontext * ctx, GLenum modeRGB, GLenum modeA)
  tfxUnitsState *us = &fxMesa->unitsState;
  GrAlphaBlendOp_t q;
 
- assert( modeRGB == modeA );
  switch (modeRGB) {
         case GL_FUNC_ADD:
              q = GR_BLEND_OP_ADD;
@@ -1513,11 +1516,28 @@ fxDDBlendEquationSeparate(GLcontext * ctx, GLenum modeRGB, GLenum modeA)
              q = GR_BLEND_OP_REVSUB;
              break;
         default:
-             return;
+             q = us->blendEqRGB;
+ }
+ if (q != us->blendEqRGB) {
+    us->blendEqRGB = q;
+    fxMesa->new_state |= FX_NEW_BLEND;
  }
 
- if ((q != us->blendEq) && fxMesa->HavePixExt) {
-    us->blendEq = q;
+ switch (modeA) {
+        case GL_FUNC_ADD:
+             q = GR_BLEND_OP_ADD;
+             break;
+        case GL_FUNC_SUBTRACT:
+             q = GR_BLEND_OP_SUB;
+             break;
+        case GL_FUNC_REVERSE_SUBTRACT:
+             q = GR_BLEND_OP_REVSUB;
+             break;
+        default:
+             q = us->blendEqAlpha;
+ }
+ if (q != us->blendEqAlpha) {
+    us->blendEqAlpha = q;
     fxMesa->new_state |= FX_NEW_BLEND;
  }
 }
@@ -1531,9 +1551,9 @@ fxSetupBlend(GLcontext * ctx)
  if (fxMesa->HavePixExt) {
     if (us->blendEnabled) {
        fxMesa->Glide.grAlphaBlendFunctionExt(us->blendSrcFuncRGB, us->blendDstFuncRGB,
-                                             us->blendEq,
+                                             us->blendEqRGB,
                                              us->blendSrcFuncAlpha, us->blendDstFuncAlpha,
-                                             us->blendEq);
+                                             us->blendEqAlpha);
     } else {
        fxMesa->Glide.grAlphaBlendFunctionExt(GR_BLEND_ONE, GR_BLEND_ZERO,
                                              GR_BLEND_OP_ADD,
@@ -1661,11 +1681,16 @@ static GrStencil_t convertGLStencilOp( GLenum op )
 }
 
 void
-fxDDStencilFunc (GLcontext *ctx, GLenum func, GLint ref, GLuint mask)
+fxDDStencilFuncSeparate (GLcontext *ctx, GLenum face, GLenum func,
+                         GLint ref, GLuint mask)
 {
    fxMesaContext fxMesa = FX_CONTEXT(ctx);
    tfxUnitsState *us = &fxMesa->unitsState;
 
+   if (ctx->Stencil.ActiveFace) {
+      return;
+   }
+
    if (
        (us->stencilFunction != func)
        ||
@@ -1681,11 +1706,15 @@ fxDDStencilFunc (GLcontext *ctx, GLenum func, GLint ref, GLuint mask)
 }
 
 void
-fxDDStencilMask (GLcontext *ctx, GLuint mask)
+fxDDStencilMaskSeparate (GLcontext *ctx, GLenum face, GLuint mask)
 {
    fxMesaContext fxMesa = FX_CONTEXT(ctx);
    tfxUnitsState *us = &fxMesa->unitsState;
 
+   if (ctx->Stencil.ActiveFace) {
+      return;
+   }
+
    if (us->stencilWriteMask != mask) {
       us->stencilWriteMask = mask;
       fxMesa->new_state |= FX_NEW_STENCIL;
@@ -1693,11 +1722,16 @@ fxDDStencilMask (GLcontext *ctx, GLuint mask)
 }
 
 void
-fxDDStencilOp (GLcontext *ctx, GLenum sfail, GLenum zfail, GLenum zpass)
+fxDDStencilOpSeparate (GLcontext *ctx, GLenum face, GLenum sfail,
+                       GLenum zfail, GLenum zpass)
 {
    fxMesaContext fxMesa = FX_CONTEXT(ctx);
    tfxUnitsState *us = &fxMesa->unitsState;
 
+   if (ctx->Stencil.ActiveFace) {
+      return;
+   }
+
    if (
        (us->stencilFailFunc != sfail)
        ||
@@ -1712,17 +1746,25 @@ fxDDStencilOp (GLcontext *ctx, GLenum sfail, GLenum zfail, GLenum zpass)
    }
 }
 
-static void
+void
 fxSetupStencil (GLcontext * ctx)
 {
    fxMesaContext fxMesa = FX_CONTEXT(ctx);
    tfxUnitsState *us = &fxMesa->unitsState;
 
    if (us->stencilEnabled) {
+      GrCmpFnc_t stencilFailFunc = GR_STENCILOP_KEEP;
+      GrCmpFnc_t stencilZFailFunc = GR_STENCILOP_KEEP;
+      GrCmpFnc_t stencilZPassFunc = GR_STENCILOP_KEEP;
+      if (!fxMesa->multipass) {
+         stencilFailFunc = convertGLStencilOp(us->stencilFailFunc);
+         stencilZFailFunc = convertGLStencilOp(us->stencilZFailFunc);
+         stencilZPassFunc = convertGLStencilOp(us->stencilZPassFunc);
+      }
       grEnable(GR_STENCIL_MODE_EXT);
-      fxMesa->Glide.grStencilOpExt(convertGLStencilOp(us->stencilFailFunc),
-                                   convertGLStencilOp(us->stencilZFailFunc),
-                                   convertGLStencilOp(us->stencilZPassFunc));
+      fxMesa->Glide.grStencilOpExt(stencilFailFunc,
+                                   stencilZFailFunc,
+                                   stencilZPassFunc);
       fxMesa->Glide.grStencilFuncExt(us->stencilFunction - GL_NEVER + GR_CMP_NEVER,
                                      us->stencilRefValue,
                                      us->stencilValueMask);
@@ -1732,6 +1774,34 @@ fxSetupStencil (GLcontext * ctx)
    }
 }
 
+void
+fxSetupStencilFace (GLcontext * ctx, GLint face)
+{
+   fxMesaContext fxMesa = FX_CONTEXT(ctx);
+   tfxUnitsState *us = &fxMesa->unitsState;
+
+   if (us->stencilEnabled) {
+      GrCmpFnc_t stencilFailFunc = GR_STENCILOP_KEEP;
+      GrCmpFnc_t stencilZFailFunc = GR_STENCILOP_KEEP;
+      GrCmpFnc_t stencilZPassFunc = GR_STENCILOP_KEEP;
+      if (!fxMesa->multipass) {
+         stencilFailFunc = convertGLStencilOp(ctx->Stencil.FailFunc[face]);
+         stencilZFailFunc = convertGLStencilOp(ctx->Stencil.ZFailFunc[face]);
+         stencilZPassFunc = convertGLStencilOp(ctx->Stencil.ZPassFunc[face]);
+      }
+      grEnable(GR_STENCIL_MODE_EXT);
+      fxMesa->Glide.grStencilOpExt(stencilFailFunc,
+                                   stencilZFailFunc,
+                                   stencilZPassFunc);
+      fxMesa->Glide.grStencilFuncExt(ctx->Stencil.Function[face] - GL_NEVER + GR_CMP_NEVER,
+                                     ctx->Stencil.Ref[face],
+                                     ctx->Stencil.ValueMask[face]);
+      fxMesa->Glide.grStencilMaskExt(ctx->Stencil.WriteMask[face]);
+   } else {
+      grDisable(GR_STENCIL_MODE_EXT);
+   }
+}
+
 /************************************************************************/
 /**************************** Color Mask SetUp **************************/
 /************************************************************************/
@@ -1753,15 +1823,15 @@ fxSetupColorMask(GLcontext * ctx)
 {
    fxMesaContext fxMesa = FX_CONTEXT(ctx);
 
-   if (fxMesa->colDepth != 16) {
-      /* 32bpp mode or 15bpp mode */
+   if (fxMesa->colDepth == 32) {
+      /* 32bpp mode */
       fxMesa->Glide.grColorMaskExt(ctx->Color.ColorMask[RCOMP],
                                    ctx->Color.ColorMask[GCOMP],
                                    ctx->Color.ColorMask[BCOMP],
                                    ctx->Color.ColorMask[ACOMP] && fxMesa->haveHwAlpha);
    }
    else {
-      /* 16 bpp mode */
+      /* 15/16 bpp mode */
       grColorMask(ctx->Color.ColorMask[RCOMP] |
                   ctx->Color.ColorMask[GCOMP] |
                   ctx->Color.ColorMask[BCOMP],
@@ -1802,6 +1872,14 @@ fxSetupFog(GLcontext * ctx)
         case GL_LINEAR:
            guFogGenerateLinear(fxMesa->fogTable, ctx->Fog.Start,
                                ctx->Fog.End);
+           if (fxMesa->fogTable[0] > 63) {
+              /* [dBorca] Hack alert:
+               * As per Glide3 Programming Guide:
+               * The difference between consecutive fog values
+               * must be less than 64.
+               */
+              fxMesa->fogTable[0] = 63;
+           }
            break;
         case GL_EXP:
            guFogGenerateExp(fxMesa->fogTable, ctx->Fog.Density);
@@ -1819,7 +1897,15 @@ fxSetupFog(GLcontext * ctx)
       }
 
       grFogTable(fxMesa->fogTable);
-      grFogMode(GR_FOG_WITH_TABLE_ON_Q);
+      if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) {
+         grVertexLayout(GR_PARAM_FOG_EXT, GR_VERTEX_FOG_OFFSET << 2,
+                                          GR_PARAM_ENABLE);
+         grFogMode(GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT);
+      } else {
+         grVertexLayout(GR_PARAM_FOG_EXT, GR_VERTEX_FOG_OFFSET << 2,
+                                          GR_PARAM_DISABLE);
+         grFogMode(GR_FOG_WITH_TABLE_ON_Q);
+      }
    }
    else {
       grFogMode(GR_FOG_DISABLE);
@@ -1830,6 +1916,25 @@ void
 fxDDFogfv(GLcontext * ctx, GLenum pname, const GLfloat * params)
 {
    FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG;
+   switch (pname) {
+      case GL_FOG_COORDINATE_SOURCE_EXT: {
+         GLenum p = (GLenum)*params;
+         if (p == GL_FOG_COORDINATE_EXT) {
+            _swrast_allow_vertex_fog(ctx, GL_TRUE);
+            _swrast_allow_pixel_fog(ctx, GL_FALSE);
+            _tnl_allow_vertex_fog( ctx, GL_TRUE);
+            _tnl_allow_pixel_fog( ctx, GL_FALSE);
+         } else {
+            _swrast_allow_vertex_fog(ctx, GL_FALSE);
+            _swrast_allow_pixel_fog(ctx, GL_TRUE);
+            _tnl_allow_vertex_fog( ctx, GL_FALSE);
+            _tnl_allow_pixel_fog( ctx, GL_TRUE);
+         }
+         break;
+      }
+      default:
+         ;
+   }
 }
 
 /************************************************************************/