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 ffde59e14396d5c4d2a5e0337262de6be072a2f4..41db3a805b77c93404c4c5a5530490a5c8c18f90 100644 (file)
@@ -192,28 +192,41 @@ static void prealloc_reg(struct brw_wm_compile *c)
     /* constants */
     {
         const int nr_params = c->fp->program.Base.Parameters->NumParameters;
-        const struct gl_program_parameter_list *plist = 
-           c->fp->program.Base.Parameters;
-       int index = 0;
-
-        /* number of float constants */
-       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;
+
+        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 */
@@ -241,7 +254,8 @@ 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)
+                                  const struct prog_instruction *inst,
+                                  GLuint component)
 {
     const int nr = 1;
     return get_reg(c, inst->DstReg.File, inst->DstReg.Index, component, nr,
@@ -253,14 +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)
+                                  const struct prog_instruction *inst,
+                                  GLuint srcRegIndex, GLuint channel)
 {
-    const int nr = 1;
-    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
@@ -335,7 +382,7 @@ static void emit_abs( struct brw_wm_compile *c,
        if (inst->DstReg.WriteMask & (1<<i)) {
            struct brw_reg src, dst;
            dst = get_dst_reg(c, inst, i);
-           src = get_src_reg(c, &inst->SrcReg[0], i);
+           src = get_src_reg(c, inst, 0, i);
            brw_MOV(p, dst, brw_abs(src));
        }
     }
@@ -353,7 +400,7 @@ static void emit_trunc( struct brw_wm_compile *c,
        if (mask & (1<<i)) {
            struct brw_reg src, dst;
            dst = get_dst_reg(c, inst, i);
-           src = get_src_reg(c, &inst->SrcReg[0], i);
+           src = get_src_reg(c, inst, 0, i);
            brw_RNDZ(p, dst, src);
        }
     }
@@ -371,7 +418,7 @@ static void emit_mov( struct brw_wm_compile *c,
        if (mask & (1<<i)) {
            struct brw_reg src, dst;
            dst = get_dst_reg(c, inst, i);
-           src = get_src_reg(c, &inst->SrcReg[0], i);
+           src = get_src_reg_imm(c, inst, 0, i);
            brw_MOV(p, dst, src);
        }
     }
@@ -418,8 +465,8 @@ static void emit_delta_xy(struct brw_wm_compile *c,
 
     dst0 = get_dst_reg(c, inst, 0);
     dst1 = get_dst_reg(c, inst, 1);
-    src0 = get_src_reg(c, &inst->SrcReg[0], 0);
-    src1 = get_src_reg(c, &inst->SrcReg[0], 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.
      */
@@ -484,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);
+        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);
@@ -495,11 +542,11 @@ 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);
+          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);
+          src0 = get_src_reg(c, inst, 1, 1);
           brw_MOV(p, brw_message_reg(nr), src0);
        }
 
@@ -526,7 +573,7 @@ static void emit_fb_write(struct brw_wm_compile *c,
         else
 #endif
         {
-           struct brw_reg src =  get_src_reg(c, &inst->SrcReg[1], 1);
+           struct brw_reg src =  get_src_reg(c, inst, 1, 1);
            brw_MOV(p, brw_message_reg(nr), src);
         }
         nr += 2;
@@ -547,9 +594,9 @@ static void emit_pixel_w( struct brw_wm_compile *c,
        struct brw_reg interp3;
 
        dst = get_dst_reg(c, inst, 3);
-       src0 = get_src_reg(c, &inst->SrcReg[0], 0);
-       delta0 = get_src_reg(c, &inst->SrcReg[1], 0);
-       delta1 = get_src_reg(c, &inst->SrcReg[1], 1);
+       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
@@ -577,9 +624,9 @@ static void emit_linterp(struct brw_wm_compile *c,
     struct brw_reg src0;
     GLuint nr, i;
 
-    src0 = get_src_reg(c, &inst->SrcReg[0], 0);
-    delta0 = get_src_reg(c, &inst->SrcReg[1], 0);
-    delta1 = get_src_reg(c, &inst->SrcReg[1], 1);
+    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);
@@ -606,7 +653,7 @@ static void emit_cinterp(struct brw_wm_compile *c,
     struct brw_reg dst, src0;
     GLuint nr, i;
 
-    src0 = get_src_reg(c, &inst->SrcReg[0], 0);
+    src0 = get_src_reg(c, inst, 0, 0);
     nr = src0.nr;
 
     interp[0] = brw_vec1_grf(nr, 0);
@@ -633,10 +680,10 @@ static void emit_pinterp(struct brw_wm_compile *c,
     struct brw_reg src0, w;
     GLuint nr, i;
 
-    src0 = get_src_reg(c, &inst->SrcReg[0], 0);
-    delta0 = get_src_reg(c, &inst->SrcReg[1], 0);
-    delta1 = get_src_reg(c, &inst->SrcReg[1], 1);
-    w = get_src_reg(c, &inst->SrcReg[2], 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);
+    w = get_src_reg(c, inst, 2, 3);
     nr = src0.nr;
 
     interp[0] = brw_vec1_grf(nr, 0);
@@ -697,11 +744,11 @@ static void emit_xpd(struct brw_wm_compile *c,
        if (mask & (1<<i)) {
            struct brw_reg src0, src1, dst;
            dst = get_dst_reg(c, inst, i);
-           src0 = negate(get_src_reg(c, &inst->SrcReg[0], i2));
-           src1 = get_src_reg(c, &inst->SrcReg[1], i1);
+           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);
-           src1 = get_src_reg(c, &inst->SrcReg[1], i2);
+           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);
@@ -717,8 +764,8 @@ 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);
-       src1[i] = get_src_reg(c, &inst->SrcReg[1], i);
+       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));
@@ -736,8 +783,8 @@ 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);
-       src1[i] = get_src_reg(c, &inst->SrcReg[1], i);
+       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));
     brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
@@ -755,8 +802,8 @@ 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);
-       src1[i] = get_src_reg(c, &inst->SrcReg[1], i);
+       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));
     brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
@@ -783,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);
+    src0 = get_src_reg(c, inst, 0, 0);
 
     /* tmp = func(src0) */
     brw_MOV(p, brw_message_reg(2), src0);
@@ -856,14 +903,27 @@ static void emit_add(struct brw_wm_compile *c,
     for (i = 0 ; i < 4; i++) {
        if (mask & (1<<i)) {
            dst = get_dst_reg(c, inst, i);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i);
-           src1 = get_src_reg(c, &inst->SrcReg[1], 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)
 {
@@ -875,8 +935,8 @@ static void emit_sub(struct brw_wm_compile *c,
     for (i = 0 ; i < 4; i++) {
        if (mask & (1<<i)) {
            dst = get_dst_reg(c, inst, i);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i);
-           src1 = get_src_reg(c, &inst->SrcReg[1], 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));
        }
     }
@@ -894,8 +954,8 @@ static void emit_mul(struct brw_wm_compile *c,
     for (i = 0 ; i < 4; i++) {
        if (mask & (1<<i)) {
            dst = get_dst_reg(c, inst, i);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i);
-           src1 = get_src_reg(c, &inst->SrcReg[1], i);
+           src0 = get_src_reg(c, inst, 0, i);
+           src1 = get_src_reg_imm(c, inst, 1, i);
            brw_MUL(p, dst, src0, src1);
        }
     }
@@ -913,7 +973,7 @@ static void emit_frc(struct brw_wm_compile *c,
     for (i = 0 ; i < 4; i++) {
        if (mask & (1<<i)) {
            dst = get_dst_reg(c, inst, i);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i);
+           src0 = get_src_reg_imm(c, inst, 0, i);
            brw_FRC(p, dst, src0);
        }
     }
@@ -932,7 +992,7 @@ static void emit_flr(struct brw_wm_compile *c,
     for (i = 0 ; i < 4; i++) {
        if (mask & (1<<i)) {
            dst = get_dst_reg(c, inst, i);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i);
+           src0 = get_src_reg_imm(c, inst, 0, i);
            brw_RNDD(p, dst, src0);
        }
     }
@@ -950,8 +1010,8 @@ static void emit_max(struct brw_wm_compile *c,
     for (i = 0; i < 4; i++) {
        if (mask & (1<<i)) {
            dst = get_dst_reg(c, inst, i);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i);
-           src1 = get_src_reg(c, &inst->SrcReg[1], 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);
@@ -978,8 +1038,8 @@ static void emit_min(struct brw_wm_compile *c,
     for (i = 0; i < 4; i++) {
        if (mask & (1<<i)) {
            dst = get_dst_reg(c, inst, i);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i);
-           src1 = get_src_reg(c, &inst->SrcReg[1], 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);
@@ -1001,8 +1061,8 @@ 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));
-    src0 = get_src_reg(c, &inst->SrcReg[0], 0);
-    src1 = get_src_reg(c, &inst->SrcReg[1], 0);
+    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);
@@ -1028,9 +1088,9 @@ static void emit_lrp(struct brw_wm_compile *c,
     for (i = 0; i < 4; i++) {
        if (mask & (1<<i)) {
            dst = get_dst_reg(c, inst, i);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i);
+           src0 = get_src_reg(c, inst, 0, i);
 
-           src1 = get_src_reg(c, &inst->SrcReg[1], i);
+           src1 = get_src_reg_imm(c, inst, 1, i);
 
            if (src1.nr == dst.nr) {
                tmp1 = alloc_tmp(c);
@@ -1038,7 +1098,7 @@ static void emit_lrp(struct brw_wm_compile *c,
            } else
                tmp1 = src1;
 
-           src2 = get_src_reg(c, &inst->SrcReg[2], i);
+           src2 = get_src_reg(c, inst, 2, i);
            if (src2.nr == dst.nr) {
                tmp2 = alloc_tmp(c);
                brw_MOV(p, tmp2, src2);
@@ -1081,9 +1141,9 @@ 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);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i);
-           src1 = get_src_reg(c, &inst->SrcReg[1], i);
-           src2 = get_src_reg(c, &inst->SrcReg[2], 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);
@@ -1104,8 +1164,8 @@ 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);
-           src0 = get_src_reg(c, &inst->SrcReg[0], i);
-           src1 = get_src_reg(c, &inst->SrcReg[1], 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);
@@ -1162,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);
-    w = get_src_reg(c, &inst->SrcReg[1], 3);
+    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);
@@ -1190,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);
+    src0 = get_src_reg(c, inst, 0, 0);
     nr = src0.nr;
-    w = get_src_reg(c, &inst->SrcReg[1], 3);
+    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);
@@ -1334,7 +1394,7 @@ static void emit_noise1( struct brw_wm_compile *c,
 
     assert( mark == 0 );
     
-    src = get_src_reg( c, inst->SrcReg, 0 );
+    src = get_src_reg( c, inst, 0, 0 );
 
     param = alloc_tmp( c );
 
@@ -1504,8 +1564,8 @@ static void emit_noise2( struct brw_wm_compile *c,
 
     assert( mark == 0 );
     
-    src0 = get_src_reg( c, inst->SrcReg, 0 );
-    src1 = get_src_reg( c, inst->SrcReg, 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 );
@@ -1807,9 +1867,9 @@ static void emit_noise3( struct brw_wm_compile *c,
 
     assert( mark == 0 );
     
-    src0 = get_src_reg( c, inst->SrcReg, 0 );
-    src1 = get_src_reg( c, inst->SrcReg, 1 );
-    src2 = get_src_reg( c, inst->SrcReg, 2 );
+    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 );
@@ -2230,10 +2290,10 @@ static void emit_noise4( struct brw_wm_compile *c,
 
     assert( mark == 0 );
     
-    src0 = get_src_reg( c, inst->SrcReg, 0 );
-    src1 = get_src_reg( c, inst->SrcReg, 1 );
-    src2 = get_src_reg( c, inst->SrcReg, 2 );
-    src3 = get_src_reg( c, inst->SrcReg, 3 );
+    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 );
@@ -2271,8 +2331,8 @@ static void emit_wpos_xy(struct brw_wm_compile *c,
     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);
-    src0[1] = get_src_reg(c, &inst->SrcReg[0], 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.
@@ -2303,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);
     for (i = 0; i < 4; i++)
-       src[i] = get_src_reg(c, &inst->SrcReg[0], i);
+       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:
@@ -2329,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;
@@ -2361,8 +2422,7 @@ static void emit_tex(struct brw_wm_compile *c,
     for (i = 0; i < 4; i++) 
        dst[i] = get_dst_reg(c, inst, i);
     for (i = 0; i < 4; i++)
-       src[i] = get_src_reg(c, &inst->SrcReg[0], i);
-
+       src[i] = get_src_reg(c, inst, 0, i);
 
     switch (inst->TexSrcTarget) {
        case TEXTURE_1D_INDEX:
@@ -2381,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))
@@ -2391,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.
  */
@@ -2476,6 +2580,9 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
            case OPCODE_ADD:
                emit_add(c, inst);
                break;
+           case OPCODE_ARL:
+               emit_arl(c, inst);
+               break;
            case OPCODE_SUB:
                emit_sub(c, inst);
                break;
@@ -2492,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);