summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2009-03-23 22:35:03 -0700
committerEric Anholt <[email protected]>2009-03-23 22:52:17 -0700
commit411d913ccea362dbd75411266d7abb685214ee93 (patch)
tree4335ff570f9ce44200b703239a1a2bc2d6d50fbd /src/mesa/drivers
parentb013f945d8514ed827183a4cbfbc4dccc100704f (diff)
i965: Fix fog coordinate g,b,a values when glFrontFacing isn't used.
Previously, we would sample (f,glFrontFacing,undef,undef) instead of the (f,0,0,1) that fragment.fogcoord is supposed to return. Due to glFrontFacing's presence in FOGC.y, we'll still give bad results there when glFrontFacing is used. Bug #19122, piglit testcase fp-fog.
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index cff50b85e26..63a7593449a 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -363,6 +363,56 @@ static void emit_interp( struct brw_wm_compile *c,
src_undef());
}
break;
+ case FRAG_ATTRIB_FOGC:
+ /* The FOGC input is really special. When a program uses glFogFragCoord,
+ * the results returned are supposed to be (f,0,0,1). But for Mesa GLSL,
+ * the glFrontFacing and glPointCoord values are also stashed in FOGC.
+ * So, write the interpolated fog value to X, then either 0, 1, or the
+ * stashed values to Y, Z, W. Note that this means that
+ * glFogFragCoord.yzw can be wrong in those cases!
+ */
+
+ /* Interpolate the fog coordinate */
+ emit_op(c,
+ WM_PINTERP,
+ dst_mask(dst, WRITEMASK_X),
+ 0,
+ interp,
+ deltas,
+ get_pixel_w(c));
+
+ /* Move the front facing value into FOGC.y if it's needed. */
+ if (c->fp->program.UsesFrontFacing) {
+ emit_op(c,
+ WM_PINTERP,
+ dst_mask(dst, WRITEMASK_Y),
+ 0,
+ interp,
+ deltas,
+ get_pixel_w(c));
+ } else {
+ emit_op(c,
+ OPCODE_MOV,
+ dst_mask(dst, WRITEMASK_Y),
+ 0,
+ src_swizzle1(interp, SWIZZLE_ZERO),
+ src_undef(),
+ src_undef());
+ }
+
+ /* Should do the PointCoord thing here. */
+ emit_op(c,
+ OPCODE_MOV,
+ dst_mask(dst, WRITEMASK_ZW),
+ 0,
+ src_swizzle(interp,
+ SWIZZLE_ZERO,
+ SWIZZLE_ZERO,
+ SWIZZLE_ZERO,
+ SWIZZLE_ONE),
+ src_undef(),
+ src_undef());
+ break;
default:
emit_op(c,
WM_PINTERP,