Tommy Schultz Lassen wrote:
I have made another attempt at supporting FOGC in vertex and fragment
shaders.

This patch is tested on Radeon X700 in World of Worcraft.

It makes it possible for me to play the game with shanders enabled.



I assume this fixes pixel shaders in d3d mode, as opengl(vertex/pixel) and d3d vertex shaders runs fine here on my RV370. I've tried your patch, and it's still unplayable here (lot of textures are empty). It also doesn't fix progs/tests/fogcoord and progs/redbook/fog.

I was also working on fogc support based on [1], see my current working code attached. progs fogcoord and fog work, wow with pixel shaders is playable. But fog fails in combination with vertex programs, because i don't patch the vp to support fog. Your approach looks more elegant, but I'm not sure if it's possible to properly support fogcoord by placing it into a texcoord.

From r500 spec v1.3 6.5.1 (it's in r300 context):
Note that Fog does not have an associated vector, it can be placed in any of color 0-3 alpha channel. There is a GB_SELECT.FOG_SELECT setting in the raster to control where fog comes from.

So I think putting it into alpha component is the way to go. But this fog stuff is still a bit confusing for me, so I may be wrong.

Markus

[1] http://www.mail-archive.com/[email protected]/msg00698.html
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 31cc00a..1ade0a3 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -83,7 +83,7 @@ int hw_tcl_on = 1;
 #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_multi_draw_arrays
 #define need_GL_EXT_secondary_color
 #define need_GL_EXT_blend_equation_separate
@@ -112,7 +112,7 @@ const struct dri_extension card_extensions[] = {
   {"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_multi_draw_arrays",		GL_EXT_multi_draw_arrays_functions},
   {"GL_EXT_gpu_program_parameters",     GL_EXT_gpu_program_parameters_functions},
   {"GL_EXT_secondary_color", 		GL_EXT_secondary_color_functions},
diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c
index 2ea17ad..5009759 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.c
+++ b/src/mesa/drivers/dri/r300/r300_emit.c
@@ -314,10 +314,6 @@ GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten)
 		    R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT |
 		    R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT;
 
-#if 0
-	if (OutputsWritten & (1 << VERT_RESULT_FOGC)) ;
-#endif
-
 	if (OutputsWritten & (1 << VERT_RESULT_PSIZ))
 		ret |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
 
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c
index a28841d..107ace1 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog.c
@@ -2149,9 +2149,31 @@ static void init_program(r300ContextPtr r300, struct r300_fragment_program *fp)
 	if (InputsRead & FRAG_BIT_COL1) {
 		cs->inputs[FRAG_ATTRIB_COL1].refcount = 0;
 		cs->inputs[FRAG_ATTRIB_COL1].reg = get_hw_temp(fp, 0);
+                /* 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;
 
+	if (InputsRead & FRAG_BIT_FOGC) {
+		cs->inputs[FRAG_ATTRIB_COL1].refcount = 0;
+		cs->inputs[FRAG_ATTRIB_COL1].reg = get_hw_temp(fp, 0);
+	}
+	InputsRead &= ~FRAG_BIT_FOGC;
+
 	/* Anything else */
 	if (InputsRead) {
 		WARN_ONCE("Don't know how to handle inputs 0x%x\n", InputsRead);
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index cb39ce0..5262f94 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -698,88 +698,9 @@ static void r300ColorMask(GLcontext * ctx,
 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_FG_FOG_BLEND_FN_MASK) |
-			    R300_FG_FOG_BLEND_FN_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_FG_FOG_BLEND_FN_MASK) |
-			    R300_FG_FOG_BLEND_FN_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_FG_FOG_BLEND_FN_MASK) |
-			    R300_FG_FOG_BLEND_FN_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] =
@@ -789,18 +710,9 @@ static void r300Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param)
 		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;
-	}
 }
 
 static void r300SetFogState(GLcontext * ctx, GLboolean state)
@@ -808,17 +720,20 @@ static void r300SetFogState(GLcontext * ctx, GLboolean state)
 	r300ContextPtr r300 = R300_CONTEXT(ctx);
 
 	R300_STATECHANGE(r300, fogs);
-	if (state) {
-		r300->hw.fogs.cmd[R300_FOGS_STATE] |= R300_FG_FOG_BLEND_ENABLE;
-
-		r300Fogfv(ctx, GL_FOG_MODE, NULL);
-		r300Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density);
-		r300Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start);
-		r300Fogfv(ctx, GL_FOG_END, &ctx->Fog.End);
-		r300Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color);
-	} else {
-		r300->hw.fogs.cmd[R300_FOGS_STATE] &= ~R300_FG_FOG_BLEND_ENABLE;
-	}
+ 	R300_STATECHANGE(r300, fogp);
+  	if (state) {
+ 		r300->hw.fogs.cmd[R300_FOGS_STATE] =
+ 			R300_FG_FOG_BLEND_ENABLE | R300_FG_FOG_BLEND_FN_LINEAR;
+ 		r300->hw.fogp.cmd[R300_FOGP_SCALE] = r300PackFloat32(-1.0);
+ 		r300->hw.fogp.cmd[R300_FOGP_START] = r300PackFloat32(1.0);
+  
+  		r300Fogfv(ctx, GL_FOG_MODE, NULL);
+  		r300Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color);
+  	} else {
+ 		r300->hw.fogs.cmd[R300_FOGS_STATE] = 0;
+ 		r300->hw.fogp.cmd[R300_FOGP_SCALE] = 0;
+ 		r300->hw.fogp.cmd[R300_FOGP_START] = 0;
+  	}
 }
 
 /* =============================================================
@@ -2226,7 +2141,7 @@ static void r300ResetHwState(r300ContextPtr r300)
 	}
 
 	/* XXX: 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;
 
 	/* XXX: Enable anti-aliasing? */
 	r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = GB_AA_CONFIG_AA_DISABLE;
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
index 861f042..fd26033 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
@@ -993,11 +993,12 @@ static void t_inputs_outputs(struct r300_vertex_program *vp)
 		    vp->outputs[VERT_RESULT_COL0] + 3;
 		cur_reg = vp->outputs[VERT_RESULT_BFC1] + 1;
 	}
-#if 0
-	if (vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC)) {
-		vp->outputs[VERT_RESULT_FOGC] = cur_reg++;
-	}
-#endif
+ 	
+ 	if (vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC)) {
+		vp->outputs[VERT_RESULT_FOGC] =
+			(vp->outputs[VERT_RESULT_COL1] != -1)
+			? vp->outputs[VERT_RESULT_COL1] : cur_reg++;
+ 	}
 
 	for (i = VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++) {
 		if (vp->key.OutputsWritten & (1 << i)) {
@@ -1007,7 +1008,7 @@ static void t_inputs_outputs(struct r300_vertex_program *vp)
 }
 
 static void r300TranslateVertexShader(struct r300_vertex_program *vp,
-				      struct prog_instruction *vpi)
+				      struct prog_instruction *vpi, GLint fog_mode)
 {
 	int i;
 	GLuint *inst;
@@ -1197,11 +1198,17 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp,
 	   of the fragment program. Blank the outputs here. */
 	for (i = 0; i < VERT_RESULT_MAX; i++) {
 		if (vp->key.OutputsAdded & (1 << i)) {
+			int dst_mask = VSF_FLAG_ALL;
+			if (i == VERT_RESULT_COL1)
+				dst_mask = VSF_FLAG_XYZ;
+			if (i == VERT_RESULT_FOGC){
+				dst_mask = VSF_FLAG_W;
+			}
 			inst[0] = PVS_OP_DST_OPERAND(VE_ADD,
 						     GL_FALSE,
 						     GL_FALSE,
 						     vp->outputs[i],
-						     VSF_FLAG_ALL,
+						     dst_mask,
 						     PVS_DST_REG_OUT);
 			inst[1] = __CONST(0, SWIZZLE_ZERO);
 			inst[2] = __CONST(0, SWIZZLE_ZERO);
@@ -1209,7 +1216,20 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp,
 			inst += 4;
 		}
 	}
-
+/*
+	if(fog_mode){
+			inst[0] = PVS_OP_DST_OPERAND(VE_ADD,
+						     GL_FALSE,
+						     GL_FALSE,
+						     vp->outputs[VERT_RESULT_COL0],
+						     VSF_FLAG_Y | VSF_FLAG_Z,
+						     PVS_DST_REG_OUT);
+			inst[1] = __CONST(0, SWIZZLE_ZERO);
+			inst[2] = __CONST(0, SWIZZLE_ZERO);
+			inst[3] = __CONST(0, SWIZZLE_ZERO);
+			inst += 4;
+	}
+*/	
 	vp->program.length = (inst - vp->program.body.i);
 	if (vp->program.length >= VSF_MAX_FRAGMENT_LENGTH) {
 		vp->program.length = 0;
@@ -1383,7 +1403,7 @@ static void pos_as_texcoord(struct r300_vertex_program *vp,
 
 static struct r300_vertex_program *build_program(struct r300_vertex_program_key
 						 *wanted_key, struct gl_vertex_program
-						 *mesa_vp, GLint wpos_idx)
+						 *mesa_vp, GLint wpos_idx, GLint fog_mode)
 {
 	struct r300_vertex_program *vp;
 
@@ -1398,10 +1418,34 @@ static struct r300_vertex_program *build_program(struct r300_vertex_program_key
 	if (wpos_idx > -1) {
 		pos_as_texcoord(vp, &mesa_vp->Base);
 	}
+	
+	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).
+		 */
+		/* Patch instructions to split the secondary color register */
+		struct prog_instruction *vpi;
+		for(vpi=mesa_vp->Base.Instructions; vpi->Opcode != OPCODE_END; vpi++){
+			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;
+				}
+			}
+		}
+	}
 
 	assert(mesa_vp->Base.NumInstructions);
 	vp->num_temporaries = mesa_vp->Base.NumTemporaries;
-	r300TranslateVertexShader(vp, mesa_vp->Base.Instructions);
+	r300TranslateVertexShader(vp, mesa_vp->Base.Instructions, fog_mode);
 
 	return vp;
 }
@@ -1428,6 +1472,9 @@ void r300SelectVertexShader(r300ContextPtr r300)
 	vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
 	wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead;
 	wanted_key.OutputsWritten = vpc->mesa_program.Base.OutputsWritten;
+ 	if (wanted_key.OutputsWritten & (1<<VERT_RESULT_FOGC)){
+ 		ctx->FragmentProgram._Current->Base.InputsRead |= FRAG_BIT_COL1;
+ 	}
 	InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
 
 	wpos_idx = -1;
@@ -1455,6 +1502,10 @@ void r300SelectVertexShader(r300ContextPtr r300)
 		add_outputs(&wanted_key, VERT_RESULT_COL1);
 	}
 
+	if (InputsRead & FRAG_BIT_FOGC) {
+		add_outputs(&wanted_key, VERT_RESULT_FOGC);
+	}
+
 	for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
 		if (InputsRead & (FRAG_BIT_TEX0 << i)) {
 			add_outputs(&wanted_key, VERT_RESULT_TEX0 + i);
@@ -1472,9 +1523,14 @@ void r300SelectVertexShader(r300ContextPtr r300)
 			r300->selected_vp = vp;
 			return;
 		}
+
+	GLint fog_mode = 0;
+	if(ctx->Fog.Enabled){
+		fog_mode = ctx->Fog.Mode;
+	}
 	//_mesa_print_program(&vpc->mesa_program.Base);
 
-	vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx);
+	vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx, fog_mode);
 	vp->next = vpc->progs;
 	vpc->progs = vp;
 	r300->selected_vp = vp;
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Mesa3d-dev mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to