add GL_EXT_fog_coord support to radeon driver. No vtxfmt code (just uses fallback...
authorRoland Scheidegger <rscheidegger@gmx.ch>
Mon, 17 Oct 2005 00:54:12 +0000 (00:54 +0000)
committerRoland Scheidegger <rscheidegger@gmx.ch>
Mon, 17 Oct 2005 00:54:12 +0000 (00:54 +0000)
docs/VERSIONS
src/mesa/drivers/dri/radeon/radeon_context.c
src/mesa/drivers/dri/radeon/radeon_maos_arrays.c
src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h
src/mesa/drivers/dri/radeon/radeon_maos_verts.c
src/mesa/drivers/dri/radeon/radeon_state.c
src/mesa/drivers/dri/radeon/radeon_state_init.c
src/mesa/drivers/dri/radeon/radeon_tcl.c
src/mesa/drivers/dri/radeon/radeon_tcl.h
src/mesa/drivers/dri/radeon/radeon_vtxfmt.c

index 58ec9edff25549b56189e89e4479aa6cc82c4b61..7d14e022edf1e539ae4c589532bb013ecb801554 100644 (file)
@@ -1383,7 +1383,8 @@ Mesa Version History
        - GL_EXT_timer_query extension
        - r200: add support for GL_ATI_fragment_shader
        - added fast XOR-mode line drawing optimization
-       - radeon: add support for all 3 tmus and cube maps
+       - radeon: add support for all 3 tmus, GL_ARB_texture_cube_map
+         and GL_EXT_fog_coord
     Changes:
        - removed GL_HP_occlusion_test (use GL_ARB_occlusion_query instead)
     Bug fixes:
index a1e3582415c338816e2e715239f2265f8dddde0d..4b81b539807e96a59c383a3761cc5bf43cd3db76 100644 (file)
@@ -66,6 +66,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define need_GL_ARB_multisample
 #define need_GL_ARB_texture_compression
 #define need_GL_EXT_blend_minmax
+#define need_GL_EXT_fog_coord
 #define need_GL_EXT_secondary_color
 #include "extension_helper.h"
 
@@ -139,6 +140,7 @@ const struct dri_extension card_extensions[] =
     { "GL_ARB_texture_mirrored_repeat",    NULL },
     { "GL_EXT_blend_logic_op",             NULL },
     { "GL_EXT_blend_subtract",             GL_EXT_blend_minmax_functions },
+    { "GL_EXT_fog_coord",                  GL_EXT_fog_coord_functions },
     { "GL_EXT_secondary_color",            GL_EXT_secondary_color_functions },
     { "GL_EXT_stencil_wrap",               NULL },
     { "GL_EXT_texture_edge_clamp",         NULL },
@@ -238,6 +240,9 @@ radeonCreateContext( const __GLcontextModes *glVisual,
    if ( !rmesa )
       return GL_FALSE;
 
+   /* init exp fog table data */
+   radeonInitStaticFogData();
+   
    /* Parse configuration files.
     * Do this here so that initialMaxAnisotropy is set before we create
     * the default textures.
index 76ad1f3cd4bd45a96a962ad6359c451d1279b7cc..49d64148ca19bdad2696ef923fd4e788e62c6782 100644 (file)
@@ -48,6 +48,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "radeon_state.h"
 #include "radeon_swtcl.h"
 #include "radeon_maos.h"
+#include "radeon_tcl.h"
 
 #if 0
 /* Usage:
@@ -169,6 +170,46 @@ do {                                               \
 } while (0)
 #endif
 
+static void emit_vecfog( GLcontext *ctx,
+                        struct radeon_dma_region *rvb,
+                        char *data,
+                        int stride,
+                        int count )
+{
+   int i;
+   GLfloat *out;
+
+   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+   if (RADEON_DEBUG & DEBUG_VERTS)
+      fprintf(stderr, "%s count %d stride %d\n",
+             __FUNCTION__, count, stride);
+
+   assert (!rvb->buf);
+
+   if (stride == 0) {
+      radeonAllocDmaRegion( rmesa, rvb, 4, 4 );
+      count = 1;
+      rvb->aos_start = GET_START(rvb);
+      rvb->aos_stride = 0;
+      rvb->aos_size = 1;
+   }
+   else {
+      radeonAllocDmaRegion( 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] = radeonComputeFogBlendFactor( ctx, *(GLfloat *)data );
+      out++;
+      data += stride;
+   }
+}
 
 static void emit_vec4( GLcontext *ctx,
                       struct radeon_dma_region *rvb,
@@ -525,6 +566,20 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
       component[nr++] = &rmesa->tcl.spec;
    }
 
+
+   if (inputs & VERT_BIT_FOG) {
+      if (!rmesa->tcl.fog.buf)
+        emit_vecfog( ctx,
+                     &(rmesa->tcl.fog),
+                     (char *)VB->FogCoordPtr->data,
+                     VB->FogCoordPtr->stride,
+                     count);
+
+      vfmt |= RADEON_CP_VC_FRMT_FPFOG;
+      component[nr++] = &rmesa->tcl.fog;
+   }
+
+
    vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &
          ~(RADEON_TCL_VTX_Q0|RADEON_TCL_VTX_Q1|RADEON_TCL_VTX_Q2));
       
@@ -589,6 +644,9 @@ void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs )
 
    if (newinputs & VERT_BIT_COLOR1) 
       radeonReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ );
+      
+   if (newinputs & VERT_BIT_FOG)
+      radeonReleaseDmaRegion( rmesa, &rmesa->tcl.fog, __FUNCTION__ );
 
    for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
       if (newinputs & VERT_BIT_TEX(unit))
index 265d061b3691c692f1681a96566e55c545780944..034cda8a65b1d7a6cdb805f4dedd66c48f6be86e 100644 (file)
@@ -50,7 +50,6 @@ static void TAG(emit)( GLcontext *ctx,
    GLuint rqcoordsnoswap = 0;
    GLuint (*coord)[4];
    GLuint coord_stride; /* object coordinates */
-   GLubyte dummy[4];
    int i;
 
    union emit_union *v = (union emit_union *)dest;
@@ -133,7 +132,7 @@ static void TAG(emit)( GLcontext *ctx,
       }
    }
 
-   if (DO_SPEC) {
+   if (DO_SPEC_OR_FOG) {
       if (VB->SecondaryColorPtr[0]) {
         spec = VB->SecondaryColorPtr[0]->data;
         spec_stride = VB->SecondaryColorPtr[0]->stride;
@@ -143,12 +142,12 @@ static void TAG(emit)( GLcontext *ctx,
       }
    }
 
-   if (DO_FOG) {
+   if (DO_SPEC_OR_FOG) {
       if (VB->FogCoordPtr) {
         fog = VB->FogCoordPtr->data;
         fog_stride = VB->FogCoordPtr->stride;
       } else {
-        fog = (GLfloat (*)[4])&dummy; fog[0][0] = 0.0F;
+        fog = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_FOG];
         fog_stride = 0;
       }
    }
@@ -202,7 +201,7 @@ static void TAG(emit)( GLcontext *ctx,
            STRIDE_4F(col, col_stride);
            v++;
         }
-        if (DO_SPEC || DO_FOG) {
+        if (DO_SPEC_OR_FOG) {
            if (DO_SPEC) {
               UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.red, spec[0][0]);
               UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.green, spec[0][1]);
@@ -210,8 +209,8 @@ static void TAG(emit)( GLcontext *ctx,
               STRIDE_4F(spec, spec_stride);
            }
            if (DO_FOG) {
-              UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.alpha, fog[0][0]);
-              fog = (GLfloat (*)[4])((GLubyte *)fog + fog_stride);
+              UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.alpha, radeonComputeFogBlendFactor(ctx, fog[0][0]));
+              STRIDE_4F(fog, fog_stride);
            }
            if (TCL_DEBUG) fprintf(stderr, "%x ", v[0].ui);
            v++;
@@ -283,7 +282,7 @@ static void TAG(init)( void )
    if (DO_W) sz++;
    if (DO_NORM) sz += 3;
    if (DO_RGBA) sz++;
-   if (DO_SPEC || DO_FOG) sz++;
+   if (DO_SPEC_OR_FOG) sz++;
    if (DO_TEX0) sz += 2;
    if (DO_TEX0 && DO_PTEX) sz++;
    if (DO_TEX1) sz += 2;
index 24e681c8c09c5fb1702ba1c0448405db2befdb17..91a60bb9f15215a8f1cacc9b6fa88436e63922e3 100644 (file)
@@ -63,8 +63,11 @@ static struct {
 
 #define DO_W    (IND & RADEON_CP_VC_FRMT_W0)
 #define DO_RGBA (IND & RADEON_CP_VC_FRMT_PKCOLOR)
-#define DO_SPEC (IND & RADEON_CP_VC_FRMT_PKSPEC)
-#define DO_FOG  (IND & RADEON_CP_VC_FRMT_PKSPEC)
+#define DO_SPEC_OR_FOG (IND & RADEON_CP_VC_FRMT_PKSPEC)
+#define DO_SPEC ((IND & RADEON_CP_VC_FRMT_PKSPEC) && \
+                (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR))
+#define DO_FOG  ((IND & RADEON_CP_VC_FRMT_PKSPEC) && ctx->Fog.Enabled && \
+                (ctx->Fog.FogCoordinateSource == GL_FOG_COORD))
 #define DO_TEX0 (IND & RADEON_CP_VC_FRMT_ST0)
 #define DO_TEX1 (IND & RADEON_CP_VC_FRMT_ST1)
 #define DO_TEX2 (IND & RADEON_CP_VC_FRMT_ST2)
@@ -337,7 +340,7 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
       req |= RADEON_CP_VC_FRMT_PKCOLOR;
    }
 
-   if (inputs & VERT_BIT_COLOR1) {
+   if (inputs & (VERT_BIT_COLOR1|VERT_BIT_FOG)) {
       req |= RADEON_CP_VC_FRMT_PKSPEC;
    }
 
index 28033881c5ee3d98347601c677e285ed9642509d..681de914e83c0185ffd089d2126ff71c28b2b5b6 100644 (file)
@@ -55,6 +55,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "radeon_vtxfmt.h"
 #include "drirenderbuffer.h"
 
+static void radeonUpdateSpecular( GLcontext *ctx );
+
 /* =============================================================
  * Alpha blending
  */
@@ -329,9 +331,6 @@ static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
    union { int i; float f; } c, d;
    GLchan col[4];
 
-   c.i = rmesa->hw.fog.cmd[FOG_C];
-   d.i = rmesa->hw.fog.cmd[FOG_D];
-
    switch (pname) {
    case GL_FOG_MODE:
       if (!ctx->Fog.Enabled)
@@ -341,30 +340,24 @@ static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
       switch (ctx->Fog.Mode) {
       case GL_LINEAR:
         rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR;
-        if (ctx->Fog.Start == ctx->Fog.End) {
-           c.f = 1.0F;
-           d.f = 1.0F;
-        }
-        else {
-           c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
-           d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start);
-        }
         break;
       case GL_EXP:
         rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP;
-        c.f = 0.0;
-        d.f = ctx->Fog.Density;
         break;
       case GL_EXP2:
         rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2;
-        c.f = 0.0;
-        d.f = -(ctx->Fog.Density * ctx->Fog.Density);
         break;
       default:
         return;
       }
-      break;
+   /* fallthrough */
    case GL_FOG_DENSITY:
+   case GL_FOG_START:
+   case GL_FOG_END:
+      if (!ctx->Fog.Enabled)
+        return;
+      c.i = rmesa->hw.fog.cmd[FOG_C];
+      d.i = rmesa->hw.fog.cmd[FOG_D];
       switch (ctx->Fog.Mode) {
       case GL_EXP:
         c.f = 0.0;
@@ -374,13 +367,7 @@ static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
         c.f = 0.0;
         d.f = -(ctx->Fog.Density * ctx->Fog.Density);
         break;
-      default:
-        break;
-      }
-      break;
-   case GL_FOG_START:
-   case GL_FOG_END:
-      if (ctx->Fog.Mode == GL_LINEAR) {
+      case GL_LINEAR:
         if (ctx->Fog.Start == ctx->Fog.End) {
            c.f = 1.0F;
            d.f = 1.0F;
@@ -388,27 +375,29 @@ static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
            c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
            d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start);
         }
+        break;
+      default:
+        break;
+      }
+      if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
+        RADEON_STATECHANGE( rmesa, fog );
+        rmesa->hw.fog.cmd[FOG_C] = c.i;
+        rmesa->hw.fog.cmd[FOG_D] = d.i;
       }
       break;
    case GL_FOG_COLOR: 
       RADEON_STATECHANGE( rmesa, ctx );
       UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color );
-      rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] =
+      rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~RADEON_FOG_COLOR_MASK;
+      rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |=
         radeonPackColor( 4, col[0], col[1], col[2], 0 );
       break;
-   case GL_FOG_COORDINATE_SOURCE_EXT: 
-      /* What to do?
-       */
+   case GL_FOG_COORD_SRC:
+      radeonUpdateSpecular( ctx );
       break;
    default:
       return;
    }
-
-   if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
-      RADEON_STATECHANGE( rmesa, fog );
-      rmesa->hw.fog.cmd[FOG_C] = c.i;
-      rmesa->hw.fog.cmd[FOG_D] = d.i;
-   }
 }
 
 
@@ -692,6 +681,7 @@ static void radeonUpdateSpecular( GLcontext *ctx )
 {
    radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
    u_int32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
+   GLuint flag = 0;
 
    RADEON_STATECHANGE( rmesa, tcl );
 
@@ -730,13 +720,22 @@ static void radeonUpdateSpecular( GLcontext *ctx )
    }
 
    if (ctx->Fog.Enabled) {
-      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
-
-      /* Bizzare: have to leave lighting enabled to get fog.
-       */
-      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
+      if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH) {
+        rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
+      /* Bizzare: have to leave lighting enabled to get fog. */
+        rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
+      }
+      else {
+      /* cannot do tcl fog factor calculation with fog coord source
+       * (send precomputed factors). Cannot use precomputed fog
+       * factors together with tcl spec light (need tcl fallback) */
+        flag = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &
+           RADEON_TCL_COMPUTE_SPECULAR) != 0;
+      }
    }
+   TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_FOGCOORDSPEC, flag);
 
    if (NEED_SECONDARY_COLOR(ctx)) {
       assert( (p & RADEON_SPECULAR_ENABLE) != 0 );
@@ -1809,8 +1808,6 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state )
         rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
       }
       radeonUpdateSpecular( ctx ); /* for PK_SPEC */
-      if (rmesa->TclFallback) 
-        radeonChooseVertexState( ctx );
       _mesa_allow_light_in_model( ctx, !state );
       break;
 
index 6e538a29732fc7ef7009a353e7db96ef4ec6333a..6c0298a6f7b86488edb5858cb5a2c330d6e2542a 100644 (file)
@@ -345,6 +345,7 @@ void radeonInitState( radeonContextPtr rmesa )
                                     RADEON_RIGHT_HAND_CUBE_OGL */);
 
    rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = (RADEON_FOG_VERTEX |
+                                         /* this bit unused for vertex fog */
                                          RADEON_FOG_USE_DEPTH);
 
    rmesa->hw.ctx.cmd[CTX_RE_SOLID_COLOR] = 0x00000000;
index fb0f10a862f3a8ac4b7c11f34d4b7b28cbfbab4f..90383d40916b64709ec90c2e050c68d895f012c7 100644 (file)
@@ -279,6 +279,88 @@ void radeonTclPrimitive( 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
+radeonInitStaticFogData( 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
+radeonComputeFogBlendFactor( 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                     */
@@ -314,7 +396,7 @@ static GLboolean radeon_run_tcl_render( GLcontext *ctx,
       }
    }
 
-   if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) {
+   if ( (ctx->Fog.FogCoordinateSource == GL_FOG_COORD) && ctx->Fog.Enabled ) {
       inputs |= VERT_BIT_FOG;
    }
 
@@ -445,7 +527,8 @@ static char *fallbackStrings[] = {
    "Texgen unit 0",
    "Texgen unit 1",
    "Texgen unit 2",
-   "User disable"
+   "User disable",
+   "Fogcoord with separate specular lighting"
 };
 
 
index 062c9fbb54344da53d851de680b10757cf4fb9e4..168ab958a2804fe3dfc8d2dbceade837c3d95842 100644 (file)
@@ -46,7 +46,10 @@ extern void radeonEmitPrimitive( GLcontext *ctx, GLuint first, GLuint last,
                                 GLuint flags );
 
 extern void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode );
-                                             
+
+extern void radeonInitStaticFogData( void );
+extern float radeonComputeFogBlendFactor( GLcontext *ctx, GLfloat fogcoord );
+
 #define RADEON_TCL_FALLBACK_RASTER            0x1 /* rasterization */
 #define RADEON_TCL_FALLBACK_UNFILLED          0x2 /* unfilled tris */
 #define RADEON_TCL_FALLBACK_LIGHT_TWOSIDE     0x4 /* twoside tris */
@@ -55,6 +58,7 @@ extern void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode );
 #define RADEON_TCL_FALLBACK_TEXGEN_1          0x20 /* texgen, unit 1 */
 #define RADEON_TCL_FALLBACK_TEXGEN_2          0x40 /* texgen, unit 2 */
 #define RADEON_TCL_FALLBACK_TCL_DISABLE       0x80 /* user disable */
+#define RADEON_TCL_FALLBACK_FOGCOORDSPEC      0x100 /* fogcoord, sep. spec light */
 
 /* max maos_verts vertex format has a size of 18 floats */
 #define RADEON_MAX_TCL_VERTSIZE (18*4)
index e554aeb330093622282a1fb53249faf31ffc653b..c734ab8d5ab100d9795c3b1ef1eb340e739ea567 100644 (file)
@@ -549,7 +549,8 @@ static GLboolean check_vtx_fmt( GLcontext *ctx )
    GLuint ind = RADEON_CP_VC_FRMT_Z;
    GLuint unit;
 
-   if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag)
+   if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag ||
+      (ctx->Fog.Enabled && (ctx->Fog.FogCoordinateSource == GL_FOG_COORD)))
       return GL_FALSE;
 
    if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) 
@@ -582,6 +583,10 @@ static GLboolean check_vtx_fmt( GLcontext *ctx )
       }
    }
 
+   if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) {
+      ind |= RADEON_CP_VC_FRMT_PKSPEC;
+   }
+
    for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
       if (ctx->Texture.Unit[unit]._ReallyEnabled) {
         if (ctx->Texture.Unit[unit].TexGenEnabled) {
@@ -657,6 +662,9 @@ static GLboolean check_vtx_fmt( GLcontext *ctx )
       UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->red,   ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] );
       UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] );
       UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->blue,  ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] );
+      /* fog ??? */
+/*      UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->alpha,
+                              radeonComputeFogFactor(ctx->Current.Attrib[VERT_ATTRIB_FOG][0]) ); */
    }
 
    for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
@@ -948,8 +956,6 @@ void radeonVtxfmtInit( 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;
@@ -986,6 +992,8 @@ void radeonVtxfmtInit( GLcontext *ctx, GLboolean useCodegen )
    vfmt->VertexAttrib3fvNV = radeon_fallback_VertexAttrib3fvNV;
    vfmt->VertexAttrib4fNV  = radeon_fallback_VertexAttrib4fNV;
    vfmt->VertexAttrib4fvNV = radeon_fallback_VertexAttrib4fvNV;
+   vfmt->FogCoordfEXT = radeon_fallback_FogCoordfEXT;
+   vfmt->FogCoordfvEXT = radeon_fallback_FogCoordfvEXT;
 
    (void)radeon_fallback_vtxfmt;