Hi Aapo,

[...]

> You forgot to emit fog coords.
> demos/fogcoord seems to work if I invert fog coords.

Thanks, I have updated my patch with your changes and some other changes to 
fix exp and exp2 fog. The results look very similar to the output of fglrx, 
although I'm not sure if fglrx is correct. The linear fog mode of the 
fogcoord demo doesn't show fog using fglrx either.

bye,

Ewald
diff -ur Mesa.orig/src/mesa/drivers/dri/r300/r300_context.c Mesa/src/mesa/drivers/dri/r300/r300_context.c
--- Mesa.orig/src/mesa/drivers/dri/r300/r300_context.c	2006-04-23 11:16:42.000000000 +0200
+++ Mesa/src/mesa/drivers/dri/r300/r300_context.c	2006-04-24 20:09:38.000000000 +0200
@@ -77,7 +77,7 @@
 #define need_GL_ARB_vertex_buffer_object
 #define need_GL_ARB_vertex_program
 #define need_GL_EXT_blend_minmax
-//#define need_GL_EXT_fog_coord
+#define need_GL_EXT_fog_coord
 #define need_GL_EXT_secondary_color
 #define need_GL_EXT_blend_equation_separate
 #define need_GL_EXT_blend_func_separate
@@ -102,7 +102,7 @@
   {"GL_EXT_blend_func_separate",	GL_EXT_blend_func_separate_functions},
   {"GL_EXT_blend_minmax",		GL_EXT_blend_minmax_functions},
   {"GL_EXT_blend_subtract",		NULL},
-//  {"GL_EXT_fog_coord",			GL_EXT_fog_coord_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},
diff -ur Mesa.orig/src/mesa/drivers/dri/r300/r300_fragprog.c Mesa/src/mesa/drivers/dri/r300/r300_fragprog.c
--- Mesa.orig/src/mesa/drivers/dri/r300/r300_fragprog.c	2006-03-29 18:51:25.000000000 +0200
+++ Mesa/src/mesa/drivers/dri/r300/r300_fragprog.c	2006-04-24 20:09:38.000000000 +0200
@@ -1411,6 +1411,21 @@
 	if (InputsRead & FRAG_BIT_COL1) {
 		cs->inputs[FRAG_ATTRIB_COL1].refcount = 0;
 		cs->inputs[FRAG_ATTRIB_COL1].reg = get_hw_temp(rp);
+                /* Patch instructions to split the secondary color register */
+		for (fpi=mp->Base.Instructions;fpi->Opcode != OPCODE_END; fpi++) {
+			for (i=0;i<3;i++) {
+				if (fpi->SrcReg[i].Index == FRAG_ATTRIB_COL1) {
+					int ws[4];
+					for (j=0;j<4;j++) {
+						ws[j] = GET_SWZ(fpi->SrcReg[i].Swizzle, j);
+						if (ws[j] == SWIZZLE_W)
+							ws[j] = SWIZZLE_ZERO;
+					}
+					fpi->SrcReg[i].Swizzle = MAKE_SWIZZLE4(ws[0], ws[1], ws[2], ws[3]);
+				}
+			}
+                }
+
 	}
 	InputsRead &= ~FRAG_BIT_COL1;
 
diff -ur Mesa.orig/src/mesa/drivers/dri/r300/r300_maos.c Mesa/src/mesa/drivers/dri/r300/r300_maos.c
--- Mesa.orig/src/mesa/drivers/dri/r300/r300_maos.c	2006-04-23 11:16:42.000000000 +0200
+++ Mesa/src/mesa/drivers/dri/r300/r300_maos.c	2006-04-24 20:09:38.000000000 +0200
@@ -436,14 +436,12 @@
 						count);
 	}
 
-#if 0
 	if (RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_FOG )) {
-		CONFIGURE_AOS(	AOS_FORMAT_FLOAT,
-						VB->FogCoordPtr,
-						immd ? 4 : VB->FogCoordPtr->size,
+		CONFIGURE_AOS(i_fog, AOS_FORMAT_FLOAT,
+						VB->AttribPtr[VERT_ATTRIB_FOG],
+						immd ? 4 : VB->AttribPtr[VERT_ATTRIB_FOG].size,
 						count);
 	}
-#endif
 
 	r300->state.texture.tc_count = 0;
 	for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
@@ -581,8 +579,8 @@
 			r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT;
 		if(OutputsWritten & (1<<VERT_RESULT_BFC1))
 			r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT;*/
-		//if(OutputsWritten & (1<<VERT_RESULT_FOGC))
-
+		if(OutputsWritten & (1<<VERT_RESULT_FOGC))
+			r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
 		if(OutputsWritten & (1<<VERT_RESULT_PSIZ))
 			r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
 
@@ -596,6 +594,8 @@
 			r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT;
 		if(RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_COLOR1 ))
 			r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
+		if(RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_FOG ))
+			r300->hw.vof.cmd[R300_VOF_CNTL_0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT;
 
 		for(i=0;i < ctx->Const.MaxTextureUnits;i++)
 			if(RENDERINPUTS_TEST( inputs_bitset, _TNL_ATTRIB_TEX(i) ))
diff -ur Mesa.orig/src/mesa/drivers/dri/r300/r300_state.c Mesa/src/mesa/drivers/dri/r300/r300_state.c
--- Mesa.orig/src/mesa/drivers/dri/r300/r300_state.c	2006-04-20 23:01:42.000000000 +0200
+++ Mesa/src/mesa/drivers/dri/r300/r300_state.c	2006-04-24 20:09:38.000000000 +0200
@@ -419,18 +419,19 @@
 
 	case GL_FOG:
 		R300_STATECHANGE(r300, fogs);
+		R300_STATECHANGE(r300, fogp);
 		if (state) {
-			r300->hw.fogs.cmd[R300_FOGS_STATE] |=
-			    R300_FOG_ENABLE;
+			r300->hw.fogs.cmd[R300_FOGS_STATE] =
+				R300_FOG_ENABLE | R300_FOG_MODE_LINEAR;
+			r300->hw.fogp.cmd[R300_FOGP_SCALE] = r300PackFloat32(-1.0);
+			r300->hw.fogp.cmd[R300_FOGP_START] = r300PackFloat32(1.0);
 			
 			ctx->Driver.Fogfv( ctx, GL_FOG_MODE, NULL );
-			ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
-			ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
-			ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
 			ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
 		} else {
-			r300->hw.fogs.cmd[R300_FOGS_STATE] &=
-			    ~R300_FOG_ENABLE;
+			r300->hw.fogs.cmd[R300_FOGS_STATE] = 0;
+			r300->hw.fogp.cmd[R300_FOGP_SCALE] = 0;
+			r300->hw.fogp.cmd[R300_FOGP_START] = 0;
 		}
 		
 		break;
@@ -663,93 +664,19 @@
 static void r300Fogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
 {
 	r300ContextPtr r300 = R300_CONTEXT(ctx);
-	union { int i; float f; } fogScale, fogStart;
 	
 	(void) param;
-	
-	fogScale.i = r300->hw.fogp.cmd[R300_FOGP_SCALE];
-	fogStart.i = r300->hw.fogp.cmd[R300_FOGP_START];
 
 	switch (pname) {
-	case GL_FOG_MODE:
-		if (!ctx->Fog.Enabled)
-			return;
-		switch (ctx->Fog.Mode) {
-		case GL_LINEAR:
-			R300_STATECHANGE(r300, fogs);
-			r300->hw.fogs.cmd[R300_FOGS_STATE] =
-				(r300->hw.fogs.cmd[R300_FOGS_STATE] & ~R300_FOG_MODE_MASK) | R300_FOG_MODE_LINEAR;
-
-			if (ctx->Fog.Start == ctx->Fog.End) {
-				fogScale.f = -1.0;
-				fogStart.f = 1.0;
-			}
-			else {
-				fogScale.f = 1.0 / (ctx->Fog.End-ctx->Fog.Start);
-				fogStart.f = -ctx->Fog.Start / (ctx->Fog.End-ctx->Fog.Start);
-			}
-			break;
-		case GL_EXP:
-			R300_STATECHANGE(r300, fogs);
-			r300->hw.fogs.cmd[R300_FOGS_STATE] =
-				(r300->hw.fogs.cmd[R300_FOGS_STATE] & ~R300_FOG_MODE_MASK) | R300_FOG_MODE_EXP;
-			fogScale.f = 0.0933*ctx->Fog.Density;
-			fogStart.f = 0.0;
-			break;
-		case GL_EXP2:
-			R300_STATECHANGE(r300, fogs);
-			r300->hw.fogs.cmd[R300_FOGS_STATE] =
-				(r300->hw.fogs.cmd[R300_FOGS_STATE] & ~R300_FOG_MODE_MASK) | R300_FOG_MODE_EXP2;
-			fogScale.f = 0.3*ctx->Fog.Density;
-			fogStart.f = 0.0;
-		default:
-			return;
-		}
-		break;
-	case GL_FOG_DENSITY:
-		switch (ctx->Fog.Mode) {
-		case GL_EXP:
-			fogScale.f = 0.0933*ctx->Fog.Density;
-			fogStart.f = 0.0;
-			break;
-		case GL_EXP2:
-			fogScale.f = 0.3*ctx->Fog.Density;
-			fogStart.f = 0.0;
-		default:
-			break;
-		}
-		break;
-	case GL_FOG_START:
-	case GL_FOG_END:
-		if (ctx->Fog.Mode == GL_LINEAR) {
-			if (ctx->Fog.Start == ctx->Fog.End) {
-				fogScale.f = -1.0;
-				fogStart.f = 1.0;
-			}
-			else {
-				fogScale.f = 1.0 / (ctx->Fog.End-ctx->Fog.Start);
-				fogStart.f = -ctx->Fog.Start / (ctx->Fog.End-ctx->Fog.Start);
-			}
-		}
-		break;
 	case GL_FOG_COLOR:
 		R300_STATECHANGE(r300, fogc);
 		r300->hw.fogc.cmd[R300_FOGC_R] = (GLuint) (ctx->Fog.Color[0]*1023.0F) & 0x3FF;
 		r300->hw.fogc.cmd[R300_FOGC_G] = (GLuint) (ctx->Fog.Color[1]*1023.0F) & 0x3FF;
 		r300->hw.fogc.cmd[R300_FOGC_B] = (GLuint) (ctx->Fog.Color[2]*1023.0F) & 0x3FF;
 		break;
-	case GL_FOG_COORD_SRC:
-		break;
 	default:
 		return;
 	}
-
-	if (fogScale.i != r300->hw.fogp.cmd[R300_FOGP_SCALE] ||
-	    fogStart.i != r300->hw.fogp.cmd[R300_FOGP_START]) {
-		R300_STATECHANGE(r300, fogp);
-		r300->hw.fogp.cmd[R300_FOGP_SCALE] = fogScale.i;
-		r300->hw.fogp.cmd[R300_FOGP_START] = fogStart.i;
-	}
 }
 
 /* =============================================================
@@ -1376,6 +1303,13 @@
 		if (high_rr < 1) high_rr = 1;
 		col_interp_nr++;
 	}
+	else if (ctx->Fog.Enabled) {
+		r300->hw.rr.cmd[R300_RR_ROUTE_1] |= R300_RS_ROUTE_1_UNKNOWN11
+				| R300_RS_ROUTE_1_COLOR1
+				| (fp_reg++ << R300_RS_ROUTE_1_COLOR1_DEST_SHIFT);
+		if (high_rr < 1) high_rr = 1;
+		col_interp_nr++;
+	}
 	
 	/* Need at least one. This might still lock as the values are undefined... */
 	if (in_texcoords == 0 && col_interp_nr == 0) {
@@ -1994,7 +1928,7 @@
 							| R300_GB_TILE_PIPE_COUNT_RV300
 							| R300_GB_TILE_SIZE_16;
 	/* set to 0 when fog is disabled? */
-	r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = R300_GB_FOG_SELECT_1_1_W;
+	r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = R300_GB_FOG_SELECT_C1A;
 	r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = 0x00000000; /* No antialiasing */
 
 	//r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
@@ -2072,11 +2006,7 @@
 #endif
 	r300Enable(ctx, GL_FOG, ctx->Fog.Enabled);
 	ctx->Driver.Fogfv( ctx, GL_FOG_MODE, NULL );
-	ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
-	ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
-	ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
 	ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
-	ctx->Driver.Fogfv( ctx, GL_FOG_COORDINATE_SOURCE_EXT, NULL );
 
 	r300->hw.at.cmd[R300_AT_UNKNOWN] = 0;
 	r300->hw.unk4BD8.cmd[1] = 0;
diff -ur Mesa.orig/src/mesa/drivers/dri/r300/r300_vertexprog.c Mesa/src/mesa/drivers/dri/r300/r300_vertexprog.c
--- Mesa.orig/src/mesa/drivers/dri/r300/r300_vertexprog.c	2006-04-24 20:07:15.000000000 +0200
+++ Mesa/src/mesa/drivers/dri/r300/r300_vertexprog.c	2006-04-24 20:09:38.000000000 +0200
@@ -538,6 +538,32 @@
 	
 	if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_COL1))
 		vp->outputs[VERT_RESULT_COL1] = cur_reg++;
+
+	if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) {
+		/* Fogcoord is stored in the alpha component of the secondary
+		 * color. According to the OpenGL Vertex Program specification,
+		 * the alpha component of the secondary color is generally
+		 * treated as zero, making it available to other downstream
+		 * extentions (fogcoord in our case).
+		 */
+		vp->outputs[VERT_RESULT_FOGC] =
+			(vp->outputs[VERT_RESULT_COL1] != -1)
+			? vp->outputs[VERT_RESULT_COL1] : cur_reg++;
+		/* Patch instructions to split the secondary color register */
+		for(vpi=mesa_vp->Base.Instructions; vpi->Opcode != OPCODE_END; vpi++, o_inst++){
+			if (vpi->DstReg.File == PROGRAM_OUTPUT) {
+				switch (vpi->DstReg.Index) {
+				case VERT_RESULT_COL1:
+					vpi->DstReg.WriteMask &= ~WRITEMASK_W;
+					break;
+				case VERT_RESULT_FOGC:
+					vpi->DstReg.WriteMask = (vpi->DstReg.WriteMask & WRITEMASK_X)
+								? WRITEMASK_W : 0;
+					break;
+				}
+			}
+		}
+	}
 	
 #if 0 /* Not supported yet */
 	if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC0))
@@ -545,11 +571,7 @@
 	
 	if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC1))
 		vp->outputs[VERT_RESULT_BFC1] = cur_reg++;
-	
-	if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC))
-		vp->outputs[VERT_RESULT_FOGC] = cur_reg++;
 #endif
-	
 	for(i=VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++)
 		if(mesa_vp->Base.OutputsWritten & (1 << i))
 			vp->outputs[i] = cur_reg++;
diff -ur Mesa.orig/src/mesa/tnl/t_vp_build.c Mesa/src/mesa/tnl/t_vp_build.c
--- Mesa.orig/src/mesa/tnl/t_vp_build.c	2006-04-14 11:10:50.000000000 +0200
+++ Mesa/src/mesa/tnl/t_vp_build.c	2006-04-24 20:10:54.000000000 +0200
@@ -1096,7 +1096,11 @@
    struct ureg input;
    
    if (p->state->fog_source_is_depth) {
-      input = swizzle1(get_eye_position(p), Z);
+      struct ureg pos = register_input( p, VERT_ATTRIB_POS );
+      struct ureg mvp = register_param6( p, STATE_MATRIX, STATE_MVP, 0, 2, 2, STATE_MATRIX );
+
+      input = get_temp(p);
+      emit_op2(p, OPCODE_DP4, input, WRITEMASK_XYZW, pos, mvp);
    }
    else {
       input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X);
@@ -1118,14 +1122,12 @@
       case FOG_EXP:
 	 emit_op1(p, OPCODE_ABS, tmp, 0, input); 
 	 emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,X)); 
-	 emit_op2(p, OPCODE_POW, fog, WRITEMASK_X, 
-		  register_const1f(p, M_E), negate(tmp)); 
+	 emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp));
 	 break;
       case FOG_EXP2:
 	 emit_op2(p, OPCODE_MUL, tmp, 0, input, swizzle1(params,X)); 
 	 emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); 
-	 emit_op2(p, OPCODE_POW, fog, WRITEMASK_X, 
-		  register_const1f(p, M_E), negate(tmp)); 
+	 emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp));
 	 break;
       }
       
@@ -1138,6 +1140,10 @@
        */
       emit_op1(p, OPCODE_MOV, fog, WRITEMASK_X, input);
    }
+
+   if (p->state->fog_source_is_depth) {
+      release_temp(p, input);
+   }
 }
  
 static void build_reflect_texgen( struct tnl_program *p,

Reply via email to