i965: change args to get_src_reg() to prep for new constant buffer support
[mesa.git] / src / mesa / drivers / dri / i965 / brw_wm_glsl.c
index ac7de6f95b56597dff410eca735bf45a751b5232..41db3a805b77c93404c4c5a5530490a5c8c18f90 100644 (file)
@@ -150,7 +150,7 @@ get_reg(struct brw_wm_compile *c, int file, int index, int component,
        /* ran out of temporary registers! */
 #if 1
         /* This is a big hack for now.
-         * Return bad register index, but don't just crash hange the GPU.
+         * Return bad register index, just don't hang the GPU.
          */
         _mesa_fprintf(stderr, "out of regs %d\n", c->reg_index);
         c->reg_index = BRW_WM_MAX_GRF - 13;
@@ -181,30 +181,52 @@ static void prealloc_reg(struct brw_wm_compile *c)
     GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted | c->fp_deriv_emitted;
 
     for (i = 0; i < 4; i++) {
-       reg = (i < c->key.nr_depth_regs) 
-           ? brw_vec8_grf(i*2, 0) : brw_vec8_grf(0, 0);
+        if (i < c->key.nr_depth_regs) 
+            reg = brw_vec8_grf(i * 2, 0);
+        else
+            reg = brw_vec8_grf(0, 0);
        set_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, i, reg);
     }
-    c->reg_index += 2*c->key.nr_depth_regs;
+    c->reg_index += 2 * c->key.nr_depth_regs;
 
     /* constants */
     {
-       int nr_params = c->fp->program.Base.Parameters->NumParameters;
-       struct gl_program_parameter_list *plist = 
-           c->fp->program.Base.Parameters;
-       int index = 0;
-       c->prog_data.nr_params = 4*nr_params;
-       for (i = 0; i < nr_params; i++) {
-           for (j = 0; j < 4; j++, index++) {
-               reg = brw_vec1_grf(c->reg_index + index/8, 
-                       index%8);
-               c->prog_data.param[index] = 
-                   &plist->ParameterValues[i][j];
-               set_reg(c, PROGRAM_STATE_VAR, i, j, reg);
-           }
-       }
-       c->nr_creg = 2*((4*nr_params+15)/16);
-       c->reg_index += c->nr_creg;
+        const int nr_params = c->fp->program.Base.Parameters->NumParameters;
+
+        if (1 /* XXX threshold: nr_params <= 8 */) {
+           const struct gl_program_parameter_list *plist = 
+              c->fp->program.Base.Parameters;
+           int index = 0;
+
+           /* number of float constants in CURBE */
+           c->prog_data.nr_params = 4 * nr_params;
+
+           /* loop over program constants (float[4]) */
+           for (i = 0; i < nr_params; i++) {
+              /* loop over XYZW channels */
+              for (j = 0; j < 4; j++, index++) {
+                 reg = brw_vec1_grf(c->reg_index + index / 8, index % 8);
+                 /* Save pointer to parameter/constant value.
+                  * Constants will be copied in prepare_constant_buffer()
+                  */
+                 c->prog_data.param[index] = &plist->ParameterValues[i][j];
+                 set_reg(c, PROGRAM_STATE_VAR, i, j, reg);
+              }
+           }
+           /* number of constant regs used (each reg is float[8]) */
+           c->nr_creg = 2 * ((4 * nr_params + 15) / 16);
+           c->reg_index += c->nr_creg;
+        }
+        else {
+           /* number of float constants in CURBE */
+           c->prog_data.nr_params = 0;
+
+           /* When there's a lot of FP constanst we'll store them in a
+            * texture-like buffer instead of using the CURBE buffer.
+            * This means we won't use GRF registers for constants and we'll
+            * have to fetch constants with a dataport read.
+            */
+        }
     }
 
     /* fragment shader inputs */
@@ -232,8 +254,10 @@ static void prealloc_reg(struct brw_wm_compile *c)
  * Convert Mesa dst register to brw register.
  */
 static struct brw_reg get_dst_reg(struct brw_wm_compile *c, 
-       struct prog_instruction *inst, int component, int nr)
+                                  const struct prog_instruction *inst,
+                                  GLuint component)
 {
+    const int nr = 1;
     return get_reg(c, inst->DstReg.File, inst->DstReg.Index, component, nr,
            0, 0);
 }
@@ -243,13 +267,47 @@ static struct brw_reg get_dst_reg(struct brw_wm_compile *c,
  * Convert Mesa src register to brw register.
  */
 static struct brw_reg get_src_reg(struct brw_wm_compile *c, 
-       struct prog_src_register *src, int index, int nr)
+                                  const struct prog_instruction *inst,
+                                  GLuint srcRegIndex, GLuint channel)
 {
-    int component = GET_SWZ(src->Swizzle, index);
+    const struct prog_src_register *src = &inst->SrcReg[srcRegIndex];
+    const GLuint nr = 1;
+    const GLuint component = GET_SWZ(src->Swizzle, channel);
+
     return get_reg(c, src->File, src->Index, component, nr, 
-           src->NegateBase, src->Abs);
+                   src->NegateBase, src->Abs);
 }
 
+
+/**
+ * Same as \sa get_src_reg() but if the register is a literal, emit
+ * a brw_reg encoding the literal.
+ * Note that a brw instruction only allows one src operand to be a literal.
+ * For instructions with more than one operand, only the second can be a literal.
+ */
+static struct brw_reg get_src_reg_imm(struct brw_wm_compile *c, 
+                                      const struct prog_instruction *inst,
+                                      GLuint srcRegIndex, GLuint channel)
+{
+    const struct prog_src_register *src = &inst->SrcReg[srcRegIndex];
+    if (src->File == PROGRAM_CONSTANT) {
+       /* a literal */
+       const int component = GET_SWZ(src->Swizzle, channel);
+       const GLfloat *param =
+          c->fp->program.Base.Parameters->ParameterValues[src->Index];
+       GLfloat value = param[component];
+       if (src->NegateBase)
+          value = -value;
+       if (src->Abs)
+          value = FABSF(value);
+       return brw_imm_f(value);
+    }
+    else {
+       return get_src_reg(c, inst, srcRegIndex, channel);
+    }
+}
+
+
 /**
  * Subroutines are minimal support for resusable instruction sequences.
  * They are implemented as simply as possible to minimise overhead: there
@@ -323,8 +381,8 @@ static void emit_abs( struct brw_wm_compile *c,
     for (i = 0; i < 4; i++) {
        if (inst->DstReg.WriteMask & (1<<i)) {
            struct brw_reg src, dst;
-           dst = get_dst_reg(c, inst, i, 1);
-           src = get_src_reg(c, &inst->SrcReg[0], i, 1);
+           dst = get_dst_reg(c, inst, i);
+           src = get_src_reg(c, inst, 0, i);
            brw_MOV(p, dst, brw_abs(src));
        }
     }
@@ -341,8 +399,8 @@ static void emit_trunc( struct brw_wm_compile *c,
     for (i = 0; i < 4; i++) {
        if (mask & (1<<i)) {
            struct brw_reg src, dst;
-           dst = get_dst_reg(c, inst, i, 1) ;
-           src = get_src_reg(c, &inst->SrcReg[0], i, 1);
+           dst = get_dst_reg(c, inst, i);
+           src = get_src_reg(c, inst, 0, i);
            brw_RNDZ(p, dst, src);
        }
     }
@@ -359,8 +417,8 @@ static void emit_mov( struct brw_wm_compile *c,
     for (i = 0; i < 4; i++) {
        if (mask & (1<<i)) {
            struct brw_reg src, dst;
-           dst = get_dst_reg(c, inst, i, 1);
-           src = get_src_reg(c, &inst->SrcReg[0], i, 1);
+           dst = get_dst_reg(c, inst, i);
+           src = get_src_reg_imm(c, inst, 0, i);
            brw_MOV(p, dst, src);
        }
     }
@@ -377,8 +435,8 @@ static void emit_pixel_xy(struct brw_wm_compile *c,
     struct brw_compile *p = &c->func;
     GLuint mask = inst->DstReg.WriteMask;
 
-    dst0 = get_dst_reg(c, inst, 0, 1);
-    dst1 = get_dst_reg(c, inst, 1, 1);
+    dst0 = get_dst_reg(c, inst, 0);
+    dst1 = get_dst_reg(c, inst, 1);
     /* Calculate pixel centers by adding 1 or 0 to each of the
      * micro-tile coordinates passed in r1.
      */
@@ -405,10 +463,10 @@ static void emit_delta_xy(struct brw_wm_compile *c,
     struct brw_compile *p = &c->func;
     GLuint mask = inst->DstReg.WriteMask;
 
-    dst0 = get_dst_reg(c, inst, 0, 1);
-    dst1 = get_dst_reg(c, inst, 1, 1);
-    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
-    src1 = get_src_reg(c, &inst->SrcReg[0], 1, 1);
+    dst0 = get_dst_reg(c, inst, 0);
+    dst1 = get_dst_reg(c, inst, 1);
+    src0 = get_src_reg(c, inst, 0, 0);
+    src1 = get_src_reg(c, inst, 0, 1);
     /* Calc delta X,Y by subtracting origin in r1 from the pixel
      * centers.
      */
@@ -473,7 +531,7 @@ static void emit_fb_write(struct brw_wm_compile *c,
 
     brw_push_insn_state(p);
     for (channel = 0; channel < 4; channel++) {
-        src0 = get_src_reg(c,  &inst->SrcReg[0], channel, 1);
+        src0 = get_src_reg(c,  inst, 0, channel);
         /*  mov (8) m2.0<1>:ud   r28.0<8;8,1>:ud  { Align1 } */
         /*  mov (8) m6.0<1>:ud   r29.0<8;8,1>:ud  { Align1 SecHalf } */
         brw_MOV(p, brw_message_reg(nr + channel), src0);
@@ -484,17 +542,43 @@ static void emit_fb_write(struct brw_wm_compile *c,
 
     if (c->key.source_depth_to_render_target) {
        if (c->key.computes_depth) {
-          src0 = get_src_reg(c, &inst->SrcReg[2], 2, 1);
+          src0 = get_src_reg(c, inst, 2, 2);
           brw_MOV(p, brw_message_reg(nr), src0);
        }
        else {
-          src0 = get_src_reg(c, &inst->SrcReg[1], 1, 1);
+          src0 = get_src_reg(c, inst, 1, 1);
           brw_MOV(p, brw_message_reg(nr), src0);
        }
 
        nr += 2;
     }
 
+    if (c->key.dest_depth_reg) {
+        GLuint comp = c->key.dest_depth_reg / 2;
+        GLuint off = c->key.dest_depth_reg % 2;
+
+        assert(comp == 1);
+        assert(off == 0);
+#if 0
+        /* XXX do we need this code?   comp always 1, off always 0, it seems */
+        if (off != 0) {
+            brw_push_insn_state(p);
+            brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+
+            brw_MOV(p, brw_message_reg(nr), offset(arg1[comp],1));
+            /* 2nd half? */
+            brw_MOV(p, brw_message_reg(nr+1), arg1[comp+1]);
+            brw_pop_insn_state(p);
+        }
+        else
+#endif
+        {
+           struct brw_reg src =  get_src_reg(c, inst, 1, 1);
+           brw_MOV(p, brw_message_reg(nr), src);
+        }
+        nr += 2;
+   }
+
     target = inst->Aux >> 1;
     eot = inst->Aux & 1;
     fire_fb_write(c, 0, nr, target, eot);
@@ -509,10 +593,10 @@ static void emit_pixel_w( struct brw_wm_compile *c,
        struct brw_reg dst, src0, delta0, delta1;
        struct brw_reg interp3;
 
-       dst = get_dst_reg(c, inst, 3, 1);
-       src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
-       delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
-       delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1);
+       dst = get_dst_reg(c, inst, 3);
+       src0 = get_src_reg(c, inst, 0, 0);
+       delta0 = get_src_reg(c, inst, 1, 0);
+       delta1 = get_src_reg(c, inst, 1, 1);
 
        interp3 = brw_vec1_grf(src0.nr+1, 4);
        /* Calc 1/w - just linterp wpos[3] optimized by putting the
@@ -538,12 +622,12 @@ static void emit_linterp(struct brw_wm_compile *c,
     struct brw_reg interp[4];
     struct brw_reg dst, delta0, delta1;
     struct brw_reg src0;
+    GLuint nr, i;
 
-    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
-    delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
-    delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1);
-    GLuint nr = src0.nr;
-    int i;
+    src0 = get_src_reg(c, inst, 0, 0);
+    delta0 = get_src_reg(c, inst, 1, 0);
+    delta1 = get_src_reg(c, inst, 1, 1);
+    nr = src0.nr;
 
     interp[0] = brw_vec1_grf(nr, 0);
     interp[1] = brw_vec1_grf(nr, 4);
@@ -552,7 +636,7 @@ static void emit_linterp(struct brw_wm_compile *c,
 
     for(i = 0; i < 4; i++ ) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
+           dst = get_dst_reg(c, inst, i);
            brw_LINE(p, brw_null_reg(), interp[i], delta0);
            brw_MAC(p, dst, suboffset(interp[i],1), delta1);
        }
@@ -567,10 +651,10 @@ static void emit_cinterp(struct brw_wm_compile *c,
 
     struct brw_reg interp[4];
     struct brw_reg dst, src0;
+    GLuint nr, i;
 
-    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
-    GLuint nr = src0.nr;
-    int i;
+    src0 = get_src_reg(c, inst, 0, 0);
+    nr = src0.nr;
 
     interp[0] = brw_vec1_grf(nr, 0);
     interp[1] = brw_vec1_grf(nr, 4);
@@ -579,7 +663,7 @@ static void emit_cinterp(struct brw_wm_compile *c,
 
     for(i = 0; i < 4; i++ ) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
+           dst = get_dst_reg(c, inst, i);
            brw_MOV(p, dst, suboffset(interp[i],3));
        }
     }
@@ -594,13 +678,13 @@ static void emit_pinterp(struct brw_wm_compile *c,
     struct brw_reg interp[4];
     struct brw_reg dst, delta0, delta1;
     struct brw_reg src0, w;
+    GLuint nr, i;
 
-    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
-    delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
-    delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1);
-    w = get_src_reg(c, &inst->SrcReg[2], 3, 1);
-    GLuint nr = src0.nr;
-    int i;
+    src0 = get_src_reg(c, inst, 0, 0);
+    delta0 = get_src_reg(c, inst, 1, 0);
+    delta1 = get_src_reg(c, inst, 1, 1);
+    w = get_src_reg(c, inst, 2, 3);
+    nr = src0.nr;
 
     interp[0] = brw_vec1_grf(nr, 0);
     interp[1] = brw_vec1_grf(nr, 4);
@@ -609,7 +693,7 @@ static void emit_pinterp(struct brw_wm_compile *c,
 
     for(i = 0; i < 4; i++ ) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
+           dst = get_dst_reg(c, inst, i);
            brw_LINE(p, brw_null_reg(), interp[i], delta0);
            brw_MAC(p, dst, suboffset(interp[i],1), 
                    delta1);
@@ -618,6 +702,36 @@ static void emit_pinterp(struct brw_wm_compile *c,
     }
 }
 
+/* Sets the destination channels to 1.0 or 0.0 according to glFrontFacing. */
+static void emit_frontfacing(struct brw_wm_compile *c,
+                            struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg r1_6ud = retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_UD);
+    struct brw_reg dst;
+    GLuint mask = inst->DstReg.WriteMask;
+    int i;
+
+    for (i = 0; i < 4; i++) {
+       if (mask & (1<<i)) {
+           dst = get_dst_reg(c, inst, i);
+           brw_MOV(p, dst, brw_imm_f(0.0));
+       }
+    }
+
+    /* bit 31 is "primitive is back face", so checking < (1 << 31) gives
+     * us front face
+     */
+    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, r1_6ud, brw_imm_ud(1 << 31));
+    for (i = 0; i < 4; i++) {
+       if (mask & (1<<i)) {
+           dst = get_dst_reg(c, inst, i);
+           brw_MOV(p, dst, brw_imm_f(1.0));
+       }
+    }
+    brw_set_predicate_control_flag_value(p, 0xff);
+}
+
 static void emit_xpd(struct brw_wm_compile *c,
                struct prog_instruction *inst)
 {
@@ -629,12 +743,12 @@ static void emit_xpd(struct brw_wm_compile *c,
        GLuint i1 = (i+1)%3;
        if (mask & (1<<i)) {
            struct brw_reg src0, src1, dst;
-           dst = get_dst_reg(c, inst, i, 1);
-           src0 = negate(get_src_reg(c, &inst->SrcReg[0], i2, 1));
-           src1 = get_src_reg(c, &inst->SrcReg[1], i1, 1);
+           dst = get_dst_reg(c, inst, i);
+           src0 = negate(get_src_reg(c, inst, 0, i2));
+           src1 = get_src_reg_imm(c, inst, 1, i1);
            brw_MUL(p, brw_null_reg(), src0, src1);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i1, 1);
-           src1 = get_src_reg(c, &inst->SrcReg[1], i2, 1);
+           src0 = get_src_reg(c, inst, 0, i1);
+           src1 = get_src_reg_imm(c, inst, 1, i2);
            brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
            brw_MAC(p, dst, src0, src1);
            brw_set_saturate(p, 0);
@@ -650,11 +764,11 @@ static void emit_dp3(struct brw_wm_compile *c,
     int i;
     struct brw_compile *p = &c->func;
     for (i = 0; i < 3; i++) {
-       src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
-       src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1);
+       src0[i] = get_src_reg(c, inst, 0, i);
+       src1[i] = get_src_reg_imm(c, inst, 1, i);
     }
 
-    dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+    dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
     brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
     brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
     brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
@@ -669,10 +783,10 @@ static void emit_dp4(struct brw_wm_compile *c,
     int i;
     struct brw_compile *p = &c->func;
     for (i = 0; i < 4; i++) {
-       src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
-       src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1);
+       src0[i] = get_src_reg(c, inst, 0, i);
+       src1[i] = get_src_reg_imm(c, inst, 1, i);
     }
-    dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+    dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
     brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
     brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
     brw_MAC(p, brw_null_reg(), src0[2], src1[2]);
@@ -688,10 +802,10 @@ static void emit_dph(struct brw_wm_compile *c,
     int i;
     struct brw_compile *p = &c->func;
     for (i = 0; i < 4; i++) {
-       src0[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
-       src1[i] = get_src_reg(c, &inst->SrcReg[1], i, 1);
+       src0[i] = get_src_reg(c, inst, 0, i);
+       src1[i] = get_src_reg_imm(c, inst, 1, i);
     }
-    dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
+    dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
     brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
     brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
     brw_MAC(p, dst, src0[2], src1[2]);
@@ -716,7 +830,7 @@ static void emit_math1(struct brw_wm_compile *c,
     tmp = alloc_tmp(c);
 
     /* Get first component of source register */
-    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+    src0 = get_src_reg(c, inst, 0, 0);
 
     /* tmp = func(src0) */
     brw_MOV(p, brw_message_reg(2), src0);
@@ -734,7 +848,7 @@ static void emit_math1(struct brw_wm_compile *c,
     /* replicate tmp value across enabled dest channels */
     for (i = 0; i < 4; i++) {
        if (inst->DstReg.WriteMask & (1 << i)) {
-          dst = get_dst_reg(c, inst, i, 1);    
+          dst = get_dst_reg(c, inst, i);
           brw_MOV(p, dst, tmp);
        }
     }
@@ -788,15 +902,28 @@ static void emit_add(struct brw_wm_compile *c,
     brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
     for (i = 0 ; i < 4; i++) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
-           src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+           dst = get_dst_reg(c, inst, i);
+           src0 = get_src_reg(c, inst, 0, i);
+           src1 = get_src_reg_imm(c, inst, 1, i);
            brw_ADD(p, dst, src0, src1);
        }
     }
     brw_set_saturate(p, 0);
 }
 
+static void emit_arl(struct brw_wm_compile *c,
+                     struct prog_instruction *inst)
+{
+    struct brw_compile *p = &c->func;
+    struct brw_reg src0, addr_reg;
+    brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
+    addr_reg = brw_uw8_reg(BRW_ARCHITECTURE_REGISTER_FILE, 
+                           BRW_ARF_ADDRESS, 0);
+    src0 = get_src_reg(c, inst, 0, 0); /* channel 0 */
+    brw_MOV(p, addr_reg, src0);
+    brw_set_saturate(p, 0);
+}
+
 static void emit_sub(struct brw_wm_compile *c,
                struct prog_instruction *inst)
 {
@@ -807,9 +934,9 @@ static void emit_sub(struct brw_wm_compile *c,
     brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
     for (i = 0 ; i < 4; i++) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
-           src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+           dst = get_dst_reg(c, inst, i);
+           src0 = get_src_reg(c, inst, 0, i);
+           src1 = get_src_reg_imm(c, inst, 1, i);
            brw_ADD(p, dst, src0, negate(src1));
        }
     }
@@ -826,9 +953,9 @@ static void emit_mul(struct brw_wm_compile *c,
     brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
     for (i = 0 ; i < 4; i++) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
-           src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+           dst = get_dst_reg(c, inst, i);
+           src0 = get_src_reg(c, inst, 0, i);
+           src1 = get_src_reg_imm(c, inst, 1, i);
            brw_MUL(p, dst, src0, src1);
        }
     }
@@ -845,8 +972,8 @@ static void emit_frc(struct brw_wm_compile *c,
     brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
     for (i = 0 ; i < 4; i++) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+           dst = get_dst_reg(c, inst, i);
+           src0 = get_src_reg_imm(c, inst, 0, i);
            brw_FRC(p, dst, src0);
        }
     }
@@ -864,8 +991,8 @@ static void emit_flr(struct brw_wm_compile *c,
     brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
     for (i = 0 ; i < 4; i++) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+           dst = get_dst_reg(c, inst, i);
+           src0 = get_src_reg_imm(c, inst, 0, i);
            brw_RNDD(p, dst, src0);
        }
     }
@@ -882,9 +1009,9 @@ static void emit_max(struct brw_wm_compile *c,
     brw_push_insn_state(p);
     for (i = 0; i < 4; i++) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
-           src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+           dst = get_dst_reg(c, inst, i);
+           src0 = get_src_reg(c, inst, 0, i);
+           src1 = get_src_reg_imm(c, inst, 1, i);
            brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
            brw_MOV(p, dst, src0);
            brw_set_saturate(p, 0);
@@ -910,9 +1037,9 @@ static void emit_min(struct brw_wm_compile *c,
     brw_push_insn_state(p);
     for (i = 0; i < 4; i++) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
-           src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+           dst = get_dst_reg(c, inst, i);
+           src0 = get_src_reg_imm(c, inst, 0, i);
+           src1 = get_src_reg(c, inst, 1, i);
            brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
            brw_MOV(p, dst, src0);
            brw_set_saturate(p, 0);
@@ -933,9 +1060,9 @@ static void emit_pow(struct brw_wm_compile *c,
 {
     struct brw_compile *p = &c->func;
     struct brw_reg dst, src0, src1;
-    dst = get_dst_reg(c, inst, get_scalar_dst_index(inst), 1);
-    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
-    src1 = get_src_reg(c, &inst->SrcReg[1], 0, 1);
+    dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
+    src0 = get_src_reg_imm(c, inst, 0, 0);
+    src1 = get_src_reg_imm(c, inst, 1, 0);
 
     brw_MOV(p, brw_message_reg(2), src0);
     brw_MOV(p, brw_message_reg(3), src1);
@@ -960,10 +1087,10 @@ static void emit_lrp(struct brw_wm_compile *c,
     int mark = mark_tmps(c);
     for (i = 0; i < 4; i++) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
+           dst = get_dst_reg(c, inst, i);
+           src0 = get_src_reg(c, inst, 0, i);
 
-           src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+           src1 = get_src_reg_imm(c, inst, 1, i);
 
            if (src1.nr == dst.nr) {
                tmp1 = alloc_tmp(c);
@@ -971,7 +1098,7 @@ static void emit_lrp(struct brw_wm_compile *c,
            } else
                tmp1 = src1;
 
-           src2 = get_src_reg(c, &inst->SrcReg[2], i, 1);
+           src2 = get_src_reg(c, inst, 2, i);
            if (src2.nr == dst.nr) {
                tmp2 = alloc_tmp(c);
                brw_MOV(p, tmp2, src2);
@@ -1013,10 +1140,10 @@ static void emit_mad(struct brw_wm_compile *c,
 
     for (i = 0; i < 4; i++) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
-           src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
-           src2 = get_src_reg(c, &inst->SrcReg[2], i, 1);
+           dst = get_dst_reg(c, inst, i);
+           src0 = get_src_reg(c, inst, 0, i);
+           src1 = get_src_reg_imm(c, inst, 1, i);
+           src2 = get_src_reg_imm(c, inst, 2, i);
            brw_MUL(p, dst, src0, src1);
 
            brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
@@ -1036,9 +1163,9 @@ static void emit_sop(struct brw_wm_compile *c,
 
     for (i = 0; i < 4; i++) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i, 1);
-           src1 = get_src_reg(c, &inst->SrcReg[1], i, 1);
+           dst = get_dst_reg(c, inst, i);
+           src0 = get_src_reg(c, inst, 0, i);
+           src1 = get_src_reg_imm(c, inst, 1, i);
            brw_push_insn_state(p);
            brw_CMP(p, brw_null_reg(), cond, src0, src1);
            brw_set_predicate_control(p, BRW_PREDICATE_NONE);
@@ -1095,8 +1222,8 @@ static void emit_ddx(struct brw_wm_compile *c,
     struct brw_reg dst;
     struct brw_reg src0, w;
     GLuint nr, i;
-    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
-    w = get_src_reg(c, &inst->SrcReg[1], 3, 1);
+    src0 = get_src_reg(c, inst, 0, 0);
+    w = get_src_reg(c, inst, 1, 3);
     nr = src0.nr;
     interp[0] = brw_vec1_grf(nr, 0);
     interp[1] = brw_vec1_grf(nr, 4);
@@ -1105,7 +1232,7 @@ static void emit_ddx(struct brw_wm_compile *c,
     brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
     for(i = 0; i < 4; i++ ) {
         if (mask & (1<<i)) {
-            dst = get_dst_reg(c, inst, i, 1);
+            dst = get_dst_reg(c, inst, i);
             brw_MOV(p, dst, interp[i]);
             brw_MUL(p, dst, dst, w);
         }
@@ -1123,9 +1250,9 @@ static void emit_ddy(struct brw_wm_compile *c,
     struct brw_reg src0, w;
     GLuint nr, i;
 
-    src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1);
+    src0 = get_src_reg(c, inst, 0, 0);
     nr = src0.nr;
-    w = get_src_reg(c, &inst->SrcReg[1], 3, 1);
+    w = get_src_reg(c, inst, 1, 3);
     interp[0] = brw_vec1_grf(nr, 0);
     interp[1] = brw_vec1_grf(nr, 4);
     interp[2] = brw_vec1_grf(nr+1, 0);
@@ -1133,7 +1260,7 @@ static void emit_ddy(struct brw_wm_compile *c,
     brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
     for(i = 0; i < 4; i++ ) {
         if (mask & (1<<i)) {
-            dst = get_dst_reg(c, inst, i, 1);
+            dst = get_dst_reg(c, inst, i);
             brw_MOV(p, dst, suboffset(interp[i], 1));
             brw_MUL(p, dst, dst, w);
         }
@@ -1267,7 +1394,7 @@ static void emit_noise1( struct brw_wm_compile *c,
 
     assert( mark == 0 );
     
-    src = get_src_reg( c, inst->SrcReg, 0, 1 );
+    src = get_src_reg( c, inst, 0, 0 );
 
     param = alloc_tmp( c );
 
@@ -1279,7 +1406,7 @@ static void emit_noise1( struct brw_wm_compile *c,
     brw_set_saturate( p, inst->SaturateMode == SATURATE_ZERO_ONE );
     for (i = 0 ; i < 4; i++) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
+           dst = get_dst_reg(c, inst, i);
            brw_MOV( p, dst, param );
        }
     }
@@ -1437,8 +1564,8 @@ static void emit_noise2( struct brw_wm_compile *c,
 
     assert( mark == 0 );
     
-    src0 = get_src_reg( c, inst->SrcReg, 0, 1 );
-    src1 = get_src_reg( c, inst->SrcReg, 1, 1 );
+    src0 = get_src_reg( c, inst, 0, 0 );
+    src1 = get_src_reg( c, inst, 0, 1 );
 
     param0 = alloc_tmp( c );
     param1 = alloc_tmp( c );
@@ -1452,7 +1579,7 @@ static void emit_noise2( struct brw_wm_compile *c,
     brw_set_saturate( p, inst->SaturateMode == SATURATE_ZERO_ONE );
     for (i = 0 ; i < 4; i++) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
+           dst = get_dst_reg(c, inst, i);
            brw_MOV( p, dst, param0 );
        }
     }
@@ -1740,9 +1867,9 @@ static void emit_noise3( struct brw_wm_compile *c,
 
     assert( mark == 0 );
     
-    src0 = get_src_reg( c, inst->SrcReg, 0, 1 );
-    src1 = get_src_reg( c, inst->SrcReg, 1, 1 );
-    src2 = get_src_reg( c, inst->SrcReg, 2, 1 );
+    src0 = get_src_reg( c, inst, 0, 0 );
+    src1 = get_src_reg( c, inst, 0, 1 );
+    src2 = get_src_reg( c, inst, 0, 2 );
 
     param0 = alloc_tmp( c );
     param1 = alloc_tmp( c );
@@ -1758,7 +1885,7 @@ static void emit_noise3( struct brw_wm_compile *c,
     brw_set_saturate( p, inst->SaturateMode == SATURATE_ZERO_ONE );
     for (i = 0 ; i < 4; i++) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
+           dst = get_dst_reg(c, inst, i);
            brw_MOV( p, dst, param0 );
        }
     }
@@ -2163,10 +2290,10 @@ static void emit_noise4( struct brw_wm_compile *c,
 
     assert( mark == 0 );
     
-    src0 = get_src_reg( c, inst->SrcReg, 0, 1 );
-    src1 = get_src_reg( c, inst->SrcReg, 1, 1 );
-    src2 = get_src_reg( c, inst->SrcReg, 2, 1 );
-    src3 = get_src_reg( c, inst->SrcReg, 3, 1 );
+    src0 = get_src_reg( c, inst, 0, 0 );
+    src1 = get_src_reg( c, inst, 0, 1 );
+    src2 = get_src_reg( c, inst, 0, 2 );
+    src3 = get_src_reg( c, inst, 0, 3 );
 
     param0 = alloc_tmp( c );
     param1 = alloc_tmp( c );
@@ -2184,7 +2311,7 @@ static void emit_noise4( struct brw_wm_compile *c,
     brw_set_saturate( p, inst->SaturateMode == SATURATE_ZERO_ONE );
     for (i = 0 ; i < 4; i++) {
        if (mask & (1<<i)) {
-           dst = get_dst_reg(c, inst, i, 1);
+           dst = get_dst_reg(c, inst, i);
            brw_MOV( p, dst, param0 );
        }
     }
@@ -2201,11 +2328,11 @@ static void emit_wpos_xy(struct brw_wm_compile *c,
     GLuint mask = inst->DstReg.WriteMask;
     struct brw_reg src0[2], dst[2];
 
-    dst[0] = get_dst_reg(c, inst, 0, 1);
-    dst[1] = get_dst_reg(c, inst, 1, 1);
+    dst[0] = get_dst_reg(c, inst, 0);
+    dst[1] = get_dst_reg(c, inst, 1);
 
-    src0[0] = get_src_reg(c, &inst->SrcReg[0], 0, 1);
-    src0[1] = get_src_reg(c, &inst->SrcReg[0], 1, 1);
+    src0[0] = get_src_reg(c, inst, 0, 0);
+    src0[1] = get_src_reg(c, inst, 0, 1);
 
     /* Calculate the pixel offset from window bottom left into destination
      * X and Y channels.
@@ -2228,7 +2355,7 @@ static void emit_wpos_xy(struct brw_wm_compile *c,
 }
 
 /* TODO
-   BIAS on SIMD8 not workind yet...
+   BIAS on SIMD8 not working yet...
  */    
 static void emit_txb(struct brw_wm_compile *c,
                struct prog_instruction *inst)
@@ -2236,19 +2363,20 @@ static void emit_txb(struct brw_wm_compile *c,
     struct brw_compile *p = &c->func;
     struct brw_reg dst[4], src[4], payload_reg;
     GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
-
     GLuint i;
+
     payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
+
     for (i = 0; i < 4; i++) 
-       dst[i] = get_dst_reg(c, inst, i, 1);
+       dst[i] = get_dst_reg(c, inst, i);
     for (i = 0; i < 4; i++)
-       src[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
+       src[i] = get_src_reg(c, inst, 0, i);
 
     switch (inst->TexSrcTarget) {
        case TEXTURE_1D_INDEX:
-           brw_MOV(p, brw_message_reg(2), src[0]);
-           brw_MOV(p, brw_message_reg(3), brw_imm_f(0));
-           brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
+           brw_MOV(p, brw_message_reg(2), src[0]);         /* s coord */
+           brw_MOV(p, brw_message_reg(3), brw_imm_f(0));   /* t coord */
+           brw_MOV(p, brw_message_reg(4), brw_imm_f(0));   /* r coord */
            break;
        case TEXTURE_2D_INDEX:
        case TEXTURE_RECT_INDEX:
@@ -2262,28 +2390,28 @@ static void emit_txb(struct brw_wm_compile *c,
            brw_MOV(p, brw_message_reg(4), src[2]);
            break;
     }
-    brw_MOV(p, brw_message_reg(5), src[3]);
-    brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
+    brw_MOV(p, brw_message_reg(5), src[3]);          /* bias */
+    brw_MOV(p, brw_message_reg(6), brw_imm_f(0));    /* ref (unused?) */
     brw_SAMPLE(p,
-           retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),
-           1,
-           retype(payload_reg, BRW_REGISTER_TYPE_UW),
-           unit + MAX_DRAW_BUFFERS, /* surface */
-           unit,     /* sampler */
-           inst->DstReg.WriteMask,
-           BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS,
-           4,
-           4,
-           0);
+               retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),  /* dest */
+               1,                                           /* msg_reg_nr */
+               retype(payload_reg, BRW_REGISTER_TYPE_UW),   /* src0 */
+               unit + MAX_DRAW_BUFFERS,                     /* surface */
+               unit,                                        /* sampler */
+               inst->DstReg.WriteMask,                      /* writemask */
+               BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS,      /* msg_type */
+               4,                                           /* response_length */
+               4,                                           /* msg_length */
+               0);                                          /* eot */
 }
 
+
 static void emit_tex(struct brw_wm_compile *c,
                struct prog_instruction *inst)
 {
     struct brw_compile *p = &c->func;
     struct brw_reg dst[4], src[4], payload_reg;
     GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
-
     GLuint msg_len;
     GLuint i, nr;
     GLuint emit;
@@ -2292,10 +2420,9 @@ static void emit_tex(struct brw_wm_compile *c,
     payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
 
     for (i = 0; i < 4; i++) 
-       dst[i] = get_dst_reg(c, inst, i, 1);
+       dst[i] = get_dst_reg(c, inst, i);
     for (i = 0; i < 4; i++)
-       src[i] = get_src_reg(c, &inst->SrcReg[0], i, 1);
-
+       src[i] = get_src_reg(c, inst, 0, i);
 
     switch (inst->TexSrcTarget) {
        case TEXTURE_1D_INDEX:
@@ -2314,6 +2441,7 @@ static void emit_tex(struct brw_wm_compile *c,
     }
     msg_len = 1;
 
+    /* move/load S, T, R coords */
     for (i = 0; i < nr; i++) {
        static const GLuint swz[4] = {0,1,2,2};
        if (emit & (1<<i))
@@ -2324,26 +2452,69 @@ static void emit_tex(struct brw_wm_compile *c,
     }
 
     if (shadow) {
-       brw_MOV(p, brw_message_reg(5), brw_imm_f(0));
-       brw_MOV(p, brw_message_reg(6), src[2]);
+       brw_MOV(p, brw_message_reg(5), brw_imm_f(0));  /* lod / bias */
+       brw_MOV(p, brw_message_reg(6), src[2]);        /* ref value / R coord */
     }
 
     brw_SAMPLE(p,
-           retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW),
-           1,
-           retype(payload_reg, BRW_REGISTER_TYPE_UW),
-           unit + MAX_DRAW_BUFFERS, /* surface */
-           unit,     /* sampler */
-           inst->DstReg.WriteMask,
-           BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE,
-           4,
-           shadow ? 6 : 4,
-           0);
+               retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW), /* dest */
+               1,                                          /* msg_reg_nr */
+               retype(payload_reg, BRW_REGISTER_TYPE_UW),  /* src0 */
+               unit + MAX_DRAW_BUFFERS,                    /* surface */
+               unit,                                       /* sampler */
+               inst->DstReg.WriteMask,                     /* writemask */
+               BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE,           /* msg_type */
+               4,                                          /* response_length */
+               shadow ? 6 : 4,                             /* msg_length */
+               0);                                         /* eot */
 
     if (shadow)
        brw_MOV(p, dst[3], brw_imm_f(1.0));
 }
 
+
+static void emit_get_constant(struct brw_context *brw,
+                              struct brw_wm_compile *c,
+                              struct prog_instruction *inst,
+                              GLuint constIndex)
+{
+   struct brw_compile *p = &c->func;
+   struct brw_reg dst[4];
+   GLuint i;
+   const int mark = mark_tmps( c );
+   struct brw_reg writeback_reg[4];
+
+   /* XXX only need 1 temp reg??? */
+   for (i = 0; i < 4; i++) {
+      writeback_reg[i] = alloc_tmp(c);
+   }
+
+   for (i = 0; i < 4; i++) {
+      dst[i] = get_dst_reg(c, inst, i);
+   }
+
+   /* Get float[4] vector from constant buffer */
+   brw_dp_READ_4(p,
+                 writeback_reg[0],     /* first writeback dest */
+                 1,                    /* msg_reg */
+                 GL_FALSE,             /* rel addr? */
+                 16 * constIndex,      /* byte offset */
+                 BRW_WM_MAX_SURF - 1   /* surface, binding table index */
+                 );
+
+   /* Extract the four channel values, smear across dest registers */
+   for (i = 0; i < 4; i++) {
+      /* extract 1 float from the writeback reg */
+      struct brw_reg new_src = stride(writeback_reg[0], 0, 1, 0);
+      new_src.subnr = i * 4;
+      /* and smear it into the dest register */
+      brw_MOV(p, dst[i], new_src);
+   }
+
+   release_tmps( c, mark );
+}
+
+
 /**
  * Resolve subroutine calls after code emit is done.
  */
@@ -2400,12 +2571,18 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
            case WM_FB_WRITE:
                emit_fb_write(c, inst);
                break;
+           case WM_FRONTFACING:
+               emit_frontfacing(c, inst);
+               break;
            case OPCODE_ABS:
                emit_abs(c, inst);
                break;
            case OPCODE_ADD:
                emit_add(c, inst);
                break;
+           case OPCODE_ARL:
+               emit_arl(c, inst);
+               break;
            case OPCODE_SUB:
                emit_sub(c, inst);
                break;
@@ -2422,7 +2599,17 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
                emit_trunc(c, inst);
                break;
            case OPCODE_MOV:
+#if 0
+                /* test hook for new constant buffer code */
+                if (inst->SrcReg[0].File == PROGRAM_UNIFORM) {
+                   emit_get_constant(brw, c, inst, inst->SrcReg[0].Index);
+                }
+                else {
+                   emit_mov(c, inst);
+                }
+#else
                emit_mov(c, inst);
+#endif
                break;
            case OPCODE_DP3:
                emit_dp3(c, inst);