i965: Fix glFrontFacing in twoside GLSL demo.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_wm_fp.c
index 7e80724130c4a0865c760a5c3783db6f755861a8..a7f5f1b9a28c21d232a92adc3ca32b130ae25d70 100644 (file)
@@ -30,9 +30,9 @@
   */
                
 
-#include "glheader.h"
-#include "macros.h"
-#include "enums.h"
+#include "main/glheader.h"
+#include "main/macros.h"
+#include "main/enums.h"
 #include "brw_context.h"
 #include "brw_wm.h"
 #include "brw_util.h"
@@ -58,7 +58,8 @@ static const char *wm_opcode_strings[] = {
    "PINTERP",
    "CINTERP",
    "WPOSXY",
-   "FB_WRITE"
+   "FB_WRITE",
+   "FRONTFACING",
 };
 
 #if 0
@@ -111,6 +112,12 @@ static struct prog_src_register src_swizzle1( struct prog_src_register reg, int
    return src_swizzle(reg, x, x, x, x);
 }
 
+static struct prog_src_register src_swizzle4( struct prog_src_register reg, uint swizzle )
+{
+   reg.Swizzle = swizzle;
+   return reg;
+}
+
 
 /***********************************************************************
  * Dest regs
@@ -122,10 +129,11 @@ static struct prog_dst_register dst_reg(GLuint file, GLuint idx)
    reg.File = file;
    reg.Index = idx;
    reg.WriteMask = WRITEMASK_XYZW;
-   reg.CondMask = 0;
+   reg.RelAddr = 0;
+   reg.CondMask = COND_TR;
    reg.CondSwizzle = 0;
-   reg.pad = 0;
    reg.CondSrc = 0;
+   reg.pad = 0;
    return reg;
 }
 
@@ -176,16 +184,16 @@ static struct prog_instruction *emit_insn(struct brw_wm_compile *c,
 {
    struct prog_instruction *inst = get_fp_inst(c);
    *inst = *inst0;
-   inst->Data = (void *)inst0;
    return inst;
 }
 
-static struct prog_instruction * emit_op(struct brw_wm_compile *c,
+static struct prog_instruction * emit_tex_op(struct brw_wm_compile *c,
                                       GLuint op,
                                       struct prog_dst_register dest,
                                       GLuint saturate,
                                       GLuint tex_src_unit,
                                       GLuint tex_src_target,
+                                      GLuint tex_shadow,
                                       struct prog_src_register src0,
                                       struct prog_src_register src1,
                                       struct prog_src_register src2 )
@@ -199,6 +207,7 @@ static struct prog_instruction * emit_op(struct brw_wm_compile *c,
    inst->SaturateMode = saturate;   
    inst->TexSrcUnit = tex_src_unit;
    inst->TexSrcTarget = tex_src_target;
+   inst->TexShadow = tex_shadow;
    inst->SrcReg[0] = src0;
    inst->SrcReg[1] = src1;
    inst->SrcReg[2] = src2;
@@ -206,6 +215,20 @@ static struct prog_instruction * emit_op(struct brw_wm_compile *c,
 }
    
 
+static struct prog_instruction * emit_op(struct brw_wm_compile *c,
+                                      GLuint op,
+                                      struct prog_dst_register dest,
+                                      GLuint saturate,
+                                      struct prog_src_register src0,
+                                      struct prog_src_register src1,
+                                      struct prog_src_register src2 )
+{
+   return emit_tex_op(c, op, dest, saturate,
+                      0, 0, 0,  /* tex unit, target, shadow */
+                      src0, src1, src2);
+}
+   
+
 
 
 /***********************************************************************
@@ -227,7 +250,7 @@ static struct prog_src_register get_pixel_xy( struct brw_wm_compile *c )
       emit_op(c,
              WM_PIXELXY,
              dst_mask(pixel_xy, WRITEMASK_XY),
-             0, 0, 0,
+             0,
              payload_r0_depth,
              src_undef(),
              src_undef());
@@ -250,7 +273,7 @@ static struct prog_src_register get_delta_xy( struct brw_wm_compile *c )
       emit_op(c,
              WM_DELTAXY,
              dst_mask(delta_xy, WRITEMASK_XY),
-             0, 0, 0,
+             0,
              pixel_xy, 
              payload_r0_depth,
              src_undef());
@@ -267,14 +290,13 @@ static struct prog_src_register get_pixel_w( struct brw_wm_compile *c )
       struct prog_dst_register pixel_w = get_temp(c);
       struct prog_src_register deltas = get_delta_xy(c);
       struct prog_src_register interp_wpos = src_reg(PROGRAM_PAYLOAD, FRAG_ATTRIB_WPOS);
-      
-      
+
       /* deltas.xyw = DELTAS2 deltas.xy, payload.interp_wpos.x
        */
       emit_op(c,
              WM_PIXELW,
              dst_mask(pixel_w, WRITEMASK_W),
-             0, 0, 0,
+             0,
              interp_wpos,
              deltas, 
              src_undef());
@@ -292,24 +314,19 @@ static void emit_interp( struct brw_wm_compile *c,
    struct prog_dst_register dst = dst_reg(PROGRAM_INPUT, idx);
    struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
    struct prog_src_register deltas = get_delta_xy(c);
-   struct prog_src_register arg2;
-   GLuint opcode;
-   
+
    /* Need to use PINTERP on attributes which have been
     * multiplied by 1/W in the SF program, and LINTERP on those
     * which have not:
     */
    switch (idx) {
    case FRAG_ATTRIB_WPOS:
-      opcode = WM_LINTERP;
-      arg2 = src_undef();
-
       /* Have to treat wpos.xy specially:
        */
       emit_op(c,
              WM_WPOSXY,
              dst_mask(dst, WRITEMASK_XY),
-             0, 0, 0,
+             0,
              get_pixel_xy(c),
              src_undef(),
              src_undef());
@@ -321,10 +338,10 @@ static void emit_interp( struct brw_wm_compile *c,
       emit_op(c,
              WM_LINTERP,
              dst,
-             0, 0, 0,
+             0,
              interp,
              deltas,
-             arg2);
+             src_undef());
       break;
    case FRAG_ATTRIB_COL0:
    case FRAG_ATTRIB_COL1:
@@ -332,7 +349,7 @@ static void emit_interp( struct brw_wm_compile *c,
         emit_op(c,
                 WM_CINTERP,
                 dst,
-                0, 0, 0,
+                0,
                 interp,
                 src_undef(),
                 src_undef());
@@ -341,17 +358,67 @@ static void emit_interp( struct brw_wm_compile *c,
         emit_op(c,
                 WM_LINTERP,
                 dst,
-                0, 0, 0,
+                0,
                 interp,
                 deltas,
                 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_FRONTFACING,
+                dst_mask(dst, WRITEMASK_Y),
+                0,
+                src_undef(),
+                src_undef(),
+                src_undef());
+      } 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,
              dst,
-             0, 0, 0,
+             0,
              interp,
              deltas,
              get_pixel_w(c));
@@ -371,7 +438,7 @@ static void emit_ddx( struct brw_wm_compile *c,
     emit_op(c,
             OPCODE_DDX,
             inst->DstReg,
-            0, 0, 0,
+            0,
             interp,
             get_pixel_w(c),
             src_undef());
@@ -387,7 +454,7 @@ static void emit_ddy( struct brw_wm_compile *c,
     emit_op(c,
             OPCODE_DDY,
             inst->DstReg,
-            0, 0, 0,
+            0,
             interp,
             get_pixel_w(c),
             src_undef());
@@ -426,10 +493,6 @@ static struct prog_src_register search_or_add_param5(struct brw_wm_compile *c,
 
    idx = _mesa_add_state_reference( paramList, tokens );
 
-   /* Recalculate state dependency: 
-    */
-   c->fp->param_state = paramList->StateFlags;
-
    return src_reg(PROGRAM_STATE_VAR, idx);
 }
 
@@ -486,13 +549,12 @@ static void precalc_dst( struct brw_wm_compile *c,
       emit_op(c,
              OPCODE_MUL,
              dst_mask(dst, WRITEMASK_Y),
-             inst->SaturateMode, 0, 0,
+             inst->SaturateMode,
              src0,
              src1,
              src_undef());
    }
 
-
    if (dst.WriteMask & WRITEMASK_XZ) {
       struct prog_instruction *swz;
       GLuint z = GET_SWZ(src0.Swizzle, Z);
@@ -502,7 +564,7 @@ static void precalc_dst( struct brw_wm_compile *c,
       swz = emit_op(c,
                    OPCODE_SWZ,
                    dst_mask(dst, WRITEMASK_XZ),
-                   inst->SaturateMode, 0, 0,
+                   inst->SaturateMode,
                    src_swizzle(src0, SWIZZLE_ONE, z, z, z),
                    src_undef(),
                    src_undef());
@@ -515,7 +577,7 @@ static void precalc_dst( struct brw_wm_compile *c,
       emit_op(c,
              OPCODE_MOV,
              dst_mask(dst, WRITEMASK_W),
-             inst->SaturateMode, 0, 0,
+             inst->SaturateMode,
              src1,
              src_undef(),
              src_undef());
@@ -537,7 +599,7 @@ static void precalc_lit( struct brw_wm_compile *c,
       swz = emit_op(c,
                    OPCODE_SWZ,
                    dst_mask(dst, WRITEMASK_XW),
-                   0, 0, 0,
+                   0,
                    src_swizzle1(src0, SWIZZLE_ONE),
                    src_undef(),
                    src_undef());
@@ -545,23 +607,30 @@ static void precalc_lit( struct brw_wm_compile *c,
       swz->SrcReg[0].NegateBase = 0;
    }
 
-
    if (dst.WriteMask & WRITEMASK_YZ) {
       emit_op(c,
              OPCODE_LIT,
              dst_mask(dst, WRITEMASK_YZ),
-             inst->SaturateMode, 0, 0,
+             inst->SaturateMode,
              src0,
              src_undef(),
              src_undef());
    }
 }
 
+
+/**
+ * Some TEX instructions require extra code, cube map coordinate
+ * normalization, or coordinate scaling for RECT textures, etc.
+ * This function emits those extra instructions and the TEX
+ * instruction itself.
+ */
 static void precalc_tex( struct brw_wm_compile *c,
                         const struct prog_instruction *inst )
 {
    struct prog_src_register coord;
    struct prog_dst_register tmpcoord;
+   const GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
 
    if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) {
        struct prog_instruction *out;
@@ -571,54 +640,61 @@ static void precalc_tex( struct brw_wm_compile *c,
        struct prog_src_register tmp1src = src_reg_from_dst(tmp1);
        struct prog_src_register src0 = inst->SrcReg[0];
 
+       /* find longest component of coord vector and normalize it */
        tmpcoord = get_temp(c);
        coord = src_reg_from_dst(tmpcoord);
 
+       /* tmpcoord = src0 (i.e.: coord = src0) */
        out = emit_op(c, OPCODE_MOV,
                      tmpcoord,
-                     0, 0, 0,
+                     0,
                      src0,
                      src_undef(),
                      src_undef());
        out->SrcReg[0].NegateBase = 0;
        out->SrcReg[0].Abs = 1;
 
+       /* tmp0 = MAX(coord.X, coord.Y) */
        emit_op(c, OPCODE_MAX,
                tmp0,
-               0, 0, 0,
+               0,
                src_swizzle1(coord, X),
                src_swizzle1(coord, Y),
                src_undef());
 
+       /* tmp1 = MAX(tmp0, coord.Z) */
        emit_op(c, OPCODE_MAX,
                tmp1,
-               0, 0, 0,
+               0,
                tmp0src,
                src_swizzle1(coord, Z),
                src_undef());
 
+       /* tmp0 = 1 / tmp1 */
        emit_op(c, OPCODE_RCP,
                tmp0,
-               0, 0, 0,
+               0,
                tmp1src,
                src_undef(),
                src_undef());
 
+       /* tmpCoord = src0 * tmp0 */
        emit_op(c, OPCODE_MUL,
                tmpcoord,
-               0, 0, 0,
+               0,
                src0,
                tmp0src,
                src_undef());
 
        release_temp(c, tmp0);
        release_temp(c, tmp1);
-   } else if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
+   }
+   else if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) {
       struct prog_src_register scale = 
         search_or_add_param5( c, 
                               STATE_INTERNAL, 
                               STATE_TEXRECT_SCALE,
-                              inst->TexSrcUnit,
+                              unit,
                               0,0 );
 
       tmpcoord = get_temp(c);
@@ -628,7 +704,7 @@ static void precalc_tex( struct brw_wm_compile *c,
       emit_op(c,
              OPCODE_MUL,
              tmpcoord,
-             0, 0, 0,
+             0,
              inst->SrcReg[0],
              scale,
              src_undef());
@@ -644,19 +720,9 @@ static void precalc_tex( struct brw_wm_compile *c,
     * conversion requires allocating a temporary variable which we
     * don't have the facility to do that late in the compilation.
     */
-   if (!(c->key.yuvtex_mask & (1<<inst->TexSrcUnit))) {
-      emit_op(c, 
-             OPCODE_TEX,
-             inst->DstReg,
-             inst->SaturateMode,
-             inst->TexSrcUnit,
-             inst->TexSrcTarget,
-             coord,
-             src_undef(),
-             src_undef());
-   }
-   else {
-       GLboolean  swap_uv = c->key.yuvtex_swap_mask & (1<<inst->TexSrcUnit);
+   if (c->key.yuvtex_mask & (1 << unit)) {
+      /* convert ycbcr to RGBA */
+      GLboolean  swap_uv = c->key.yuvtex_swap_mask & (1<<unit);
 
       /* 
         CONST C0 = { -.5, -.0625,  -.5, 1.164 }
@@ -678,22 +744,23 @@ static void precalc_tex( struct brw_wm_compile *c,
      
       /* tmp     = TEX ...
        */
-      emit_op(c, 
-             OPCODE_TEX,
-             tmp,
-             inst->SaturateMode,
-             inst->TexSrcUnit,
-             inst->TexSrcTarget,
-             coord,
-             src_undef(),
-             src_undef());
+      emit_tex_op(c, 
+                  OPCODE_TEX,
+                  tmp,
+                  inst->SaturateMode,
+                  unit,
+                  inst->TexSrcTarget,
+                  inst->TexShadow,
+                  coord,
+                  src_undef(),
+                  src_undef());
 
       /* tmp.xyz =  ADD TMP, C0
        */
       emit_op(c,
              OPCODE_ADD,
              dst_mask(tmp, WRITEMASK_XYZ),
-             0, 0, 0,
+             0,
              tmpsrc,
              C0,
              src_undef());
@@ -704,7 +771,7 @@ static void precalc_tex( struct brw_wm_compile *c,
       emit_op(c,
              OPCODE_MUL,
              dst_mask(tmp, WRITEMASK_Y),
-             0, 0, 0,
+             0,
              tmpsrc,
              src_swizzle1(C0, W),
              src_undef());
@@ -719,7 +786,7 @@ static void precalc_tex( struct brw_wm_compile *c,
       emit_op(c,
              OPCODE_MAD,
              dst_mask(dst, WRITEMASK_XYZ),
-             0, 0, 0,
+             0,
              swap_uv?src_swizzle(tmpsrc, Z,Z,X,X):src_swizzle(tmpsrc, X,X,Z,Z),
              C1,
              src_swizzle1(tmpsrc, Y));
@@ -729,15 +796,41 @@ static void precalc_tex( struct brw_wm_compile *c,
       emit_op(c,
              OPCODE_MAD,
              dst_mask(dst, WRITEMASK_Y),
-             0, 0, 0,
+             0,
              src_swizzle1(tmpsrc, Z),
              src_swizzle1(C1, W),
              src_swizzle1(src_reg_from_dst(dst), Y));
 
       release_temp(c, tmp);
    }
+   else {
+      /* ordinary RGBA tex instruction */
+      emit_tex_op(c, 
+                  OPCODE_TEX,
+                  inst->DstReg,
+                  inst->SaturateMode,
+                  unit,
+                  inst->TexSrcTarget,
+                  inst->TexShadow,
+                  coord,
+                  src_undef(),
+                  src_undef());
+   }
 
-   if (inst->TexSrcTarget == GL_TEXTURE_RECTANGLE_NV) 
+   /* For GL_EXT_texture_swizzle: */
+   if (c->key.tex_swizzles[unit] != SWIZZLE_NOOP) {
+      /* swizzle the result of the TEX instruction */
+      struct prog_src_register tmpsrc = src_reg_from_dst(inst->DstReg);
+      emit_op(c, OPCODE_SWZ,
+              inst->DstReg,
+              SATURATE_OFF, /* saturate already done above */
+              src_swizzle4(tmpsrc, c->key.tex_swizzles[unit]),
+              src_undef(),
+              src_undef());
+   }
+
+   if ((inst->TexSrcTarget == TEXTURE_RECT_INDEX) ||
+       (inst->TexSrcTarget == TEXTURE_CUBE_INDEX))
       release_temp(c, tmpcoord);
 }
 
@@ -779,7 +872,7 @@ static void precalc_txp( struct brw_wm_compile *c,
       emit_op(c,
              OPCODE_RCP,
              dst_mask(tmp, WRITEMASK_W),
-             0, 0, 0,
+             0,
              src_swizzle1(src0, GET_SWZ(src0.Swizzle, W)),
              src_undef(),
              src_undef());
@@ -789,7 +882,7 @@ static void precalc_txp( struct brw_wm_compile *c,
       emit_op(c,
              OPCODE_MUL,
              dst_mask(tmp, WRITEMASK_XYZ),
-             0, 0, 0,
+             0,
              src0,
              src_swizzle1(src_reg_from_dst(tmp), W),
              src_undef());
@@ -812,89 +905,44 @@ static void precalc_txp( struct brw_wm_compile *c,
 
 
 
-
-
-/***********************************************************************
- * Add instructions to perform fog blending
- */
-
-static void fog_blend( struct brw_wm_compile *c,
-                            struct prog_src_register fog_factor )
-{
-   struct prog_dst_register outcolor = dst_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
-   struct prog_src_register fogcolor = search_or_add_param5( c, STATE_FOG_COLOR, 0,0,0,0 );
-
-   /* color.xyz = LRP fog_factor.xxxx, output_color, fog_color */
-   
-   emit_op(c, 
-          OPCODE_LRP,
-          dst_mask(outcolor, WRITEMASK_XYZ),
-          0, 0, 0,
-          fog_factor,
-          src_reg_from_dst(outcolor),
-          fogcolor);
-}
-
-
-
-/* This one is simple - just take the interpolated fog coordinate and
- * use it as the fog blend factor.
- */
-static void fog_interpolated( struct brw_wm_compile *c )
-{
-   struct prog_src_register fogc = src_reg(PROGRAM_INPUT, FRAG_ATTRIB_FOGC);
-   
-   if (!(c->fp_interp_emitted & (1<<FRAG_ATTRIB_FOGC))) 
-      emit_interp(c, FRAG_ATTRIB_FOGC);
-
-   fog_blend( c, src_swizzle1(fogc, GET_SWZ(fogc.Swizzle,X)));
-}
-
-static void emit_fog( struct brw_wm_compile *c ) 
-{
-   if (!c->fp->program.FogOption)
-      return;
-
-   if (1) 
-      fog_interpolated( c );
-   else {
-      /* TODO: per-pixel fog */
-      assert(0);
-   }
-}
-
 static void emit_fb_write( struct brw_wm_compile *c )
 {
-   struct prog_src_register outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
    struct prog_src_register payload_r0_depth = src_reg(PROGRAM_PAYLOAD, PAYLOAD_DEPTH);
-   struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPR);
+   struct prog_src_register outdepth = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DEPTH);
+   struct prog_src_register outcolor;
    GLuint i;
 
    struct prog_instruction *inst, *last_inst;
    struct brw_context *brw = c->func.brw;
 
-   /* inst->Sampler is not used by backend, 
-      use it for fb write target and eot */
-
-   if (brw->state.nr_draw_regions > 1) {
-       for (i = 0 ; i < brw->state.nr_draw_regions; i++) {
-          outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i);
-          last_inst = inst = emit_op(c,
-                  WM_FB_WRITE, dst_mask(dst_undef(),0), 0, 0, 0,
-                  outcolor, payload_r0_depth, outdepth);
-          inst->Sampler = (i<<1);
-          if (c->fp_fragcolor_emitted) {
-              outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR);
-              last_inst = inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
-                      0, 0, 0, outcolor, payload_r0_depth, outdepth);
-              inst->Sampler = (i<<1);
-          }
-       }
-       last_inst->Sampler |= 1; //eot
-   }else {
-       inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
-              0, 0, 0, outcolor, payload_r0_depth, outdepth);
-       inst->Sampler = 1|(0<<1);
+   /* The inst->Aux field is used for FB write target and the EOT marker */
+
+   if (brw->state.nr_color_regions > 1) {
+      for (i = 0 ; i < brw->state.nr_color_regions; i++) {
+         outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i);
+         last_inst = inst = emit_op(c,
+                                    WM_FB_WRITE, dst_mask(dst_undef(),0), 0,
+                                    outcolor, payload_r0_depth, outdepth);
+         inst->Aux = (i<<1);
+         if (c->fp_fragcolor_emitted) {
+            outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR);
+            last_inst = inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
+                                       0, outcolor, payload_r0_depth, outdepth);
+            inst->Aux = (i<<1);
+         }
+      }
+      last_inst->Aux |= 1; //eot
+   }
+   else {
+      /* if gl_FragData[0] is written, use it, else use gl_FragColor */
+      if (c->fp->program.Base.OutputsWritten & (1 << FRAG_RESULT_DATA0))
+         outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_DATA0);
+      else 
+         outcolor = src_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR);
+
+      inst = emit_op(c, WM_FB_WRITE, dst_mask(dst_undef(),0),
+                     0, outcolor, payload_r0_depth, outdepth);
+      inst->Aux = 1|(0<<1);
    }
 }
 
@@ -925,9 +973,9 @@ static void validate_dst_regs( struct brw_wm_compile *c,
                               const struct prog_instruction *inst )
 {
    if (inst->DstReg.File == PROGRAM_OUTPUT) {
-       GLuint idx = inst->DstReg.Index;
-       if (idx == FRAG_RESULT_COLR)
-          c->fp_fragcolor_emitted = 1;
+      GLuint idx = inst->DstReg.Index;
+      if (idx == FRAG_RESULT_COLOR)
+         c->fp_fragcolor_emitted = 1;
    }
 }
 
@@ -947,18 +995,22 @@ static void print_insns( const struct prog_instruction *insn,
                                     3);
       }
       else 
-        _mesa_printf("UNKNOWN\n");
-          
+        _mesa_printf("965 Opcode %d\n", insn->Opcode);
    }
 }
 
+
+/**
+ * Initial pass for fragment program code generation.
+ * This function is used by both the GLSL and non-GLSL paths.
+ */
 void brw_wm_pass_fp( struct brw_wm_compile *c )
 {
    struct brw_fragment_program *fp = c->fp;
    GLuint insn;
 
    if (INTEL_DEBUG & DEBUG_WM) {
-      _mesa_printf("\n\n\npre-fp:\n");
+      _mesa_printf("pre-fp:\n");
       _mesa_print_program(&fp->program.Base); 
       _mesa_printf("\n");
    }
@@ -968,15 +1020,19 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
    c->pixel_w = src_undef();
    c->nr_fp_insns = 0;
 
-   /* Emit preamble instructions:
+   /* Emit preamble instructions.  This is where special instructions such as
+    * WM_CINTERP, WM_LINTERP, WM_PINTERP and WM_WPOSXY are emitted to
+    * compute shader inputs from varying vars.
     */
-
-
    for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {
       const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];
       validate_src_regs(c, inst);
       validate_dst_regs(c, inst);
    }
+
+   /* Loop over all instructions doing assorted simplifications and
+    * transformations.
+    */
    for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {
       const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];
       struct prog_instruction *out;
@@ -985,7 +1041,6 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
        * necessary:
        */
 
-
       switch (inst->Opcode) {
       case OPCODE_SWZ: 
         out = emit_insn(c, inst);
@@ -1019,11 +1074,20 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
       case OPCODE_LIT:
         precalc_lit(c, inst);
         break;
-     
+
+      case OPCODE_TEX:
+        precalc_tex(c, inst);
+        break;
+
       case OPCODE_TXP:
         precalc_txp(c, inst);
         break;
 
+      case OPCODE_TXB:
+        out = emit_insn(c, inst);
+        out->TexSrcUnit = fp->program.Base.SamplerUnits[inst->TexSrcUnit];
+        break;
+
       case OPCODE_XPD: 
         out = emit_insn(c, inst);
         /* This should probably be done in the parser. 
@@ -1044,7 +1108,6 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
          emit_ddy(c, inst);
        break;
       case OPCODE_END:
-        emit_fog(c);
         emit_fb_write(c);
         break;
       case OPCODE_PRINT:
@@ -1057,9 +1120,9 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
    }
 
    if (INTEL_DEBUG & DEBUG_WM) {
-          _mesa_printf("\n\n\npass_fp:\n");
-          print_insns( c->prog_instructions, c->nr_fp_insns );
-          _mesa_printf("\n");
+      _mesa_printf("pass_fp:\n");
+      print_insns( c->prog_instructions, c->nr_fp_insns );
+      _mesa_printf("\n");
    }
 }