summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/r200/r200_tcl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/r200/r200_tcl.c')
-rw-r--r--src/mesa/drivers/dri/r200/r200_tcl.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c
index 78d16ed0f3..d2dfc5fda1 100644
--- a/src/mesa/drivers/dri/r200/r200_tcl.c
+++ b/src/mesa/drivers/dri/r200/r200_tcl.c
@@ -269,6 +269,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);