Hi Aapo,

Sorry for the late response ...

[...]

> What about vertex fog?
> Could there be a way to route interpolated fog coords to the fog hardware
> somehow? I dont mind about doing it with fragment programs but that might

I've tried to implement this, but it remains a bit buggy. The problem seems to 
be related to secondary color handling, which is broken even without using 
fog.

Attached is the result of my findings. It uses the alpha component of the 
secondary color for fog, which I assume to be similar to what fglrx does from 
examining the command stream packets using 'check_maps()'.

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-23 22:40:40.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-23 22:41:11.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-23 22:40:40.000000000 +0200
@@ -581,8 +581,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 +596,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-23 22:40:55.000000000 +0200
@@ -679,15 +679,8 @@
 			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);
-			}
+			fogScale.f = -1.0;
+			fogStart.f = 1.0;
 			break;
 		case GL_EXP:
 			R300_STATECHANGE(r300, fogs);
@@ -722,14 +715,8 @@
 	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);
-			}
+			fogScale.f = -1.0;
+			fogStart.f = 1.0;
 		}
 		break;
 	case GL_FOG_COLOR:
@@ -1376,6 +1363,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 +1988,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;
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-03-23 13:37:03.000000000 +0100
+++ Mesa/src/mesa/drivers/dri/r300/r300_vertexprog.c	2006-04-23 22:40:40.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++;
@@ -991,5 +1013,5 @@
 	for(i=0; i < vp->program.length; i++)
 		fprintf(stderr, "%08x\n", vp->program.body.d[i]);
 #endif
+	_mesa_print_program(&mesa_vp->Base);
 }
-
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-23 22:40:40.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);
@@ -1138,6 +1142,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