intel: Add a batch flush between front-buffer downsample and X protocol.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_sf_emit.c
index 3eae41ee7424743163a8d1620104923b83c6ac74..b206797f756bff25f1dcdc658a33e8d0d1ddd8af 100644 (file)
 #include "brw_sf.h"
 
 
-static struct brw_reg get_vert_attr(struct brw_sf_compile *c,
-                                   struct brw_reg vert,
-                                   GLuint attr)
+/**
+ * Determine the vue slot corresponding to the given half of the given register.
+ */
+static inline int vert_reg_to_vue_slot(struct brw_sf_compile *c, GLuint reg,
+                                       int half)
+{
+   return (reg + c->urb_entry_read_offset) * 2 + half;
+}
+
+/**
+ * Determine the varying corresponding to the given half of the given
+ * register.  half=0 means the first half of a register, half=1 means the
+ * second half.
+ */
+static inline int vert_reg_to_varying(struct brw_sf_compile *c, GLuint reg,
+                                      int half)
 {
-   GLuint off = c->attr_to_idx[attr] / 2;
-   GLuint sub = c->attr_to_idx[attr] % 2;
+   int vue_slot = vert_reg_to_vue_slot(c, reg, half);
+   return c->vue_map.slot_to_varying[vue_slot];
+}
+
+/**
+ * Determine the register corresponding to the given vue slot
+ */
+static struct brw_reg get_vue_slot(struct brw_sf_compile *c,
+                                   struct brw_reg vert,
+                                   int vue_slot)
+{
+   GLuint off = vue_slot / 2 - c->urb_entry_read_offset;
+   GLuint sub = vue_slot % 2;
 
    return brw_vec4_grf(vert.nr + off, sub * 4);
 }
 
-static GLboolean have_attr(struct brw_sf_compile *c,
-                          GLuint attr)
+/**
+ * Determine the register corresponding to the given varying.
+ */
+static struct brw_reg get_varying(struct brw_sf_compile *c,
+                                  struct brw_reg vert,
+                                  GLuint varying)
+{
+   int vue_slot = c->vue_map.varying_to_slot[varying];
+   assert (vue_slot >= c->urb_entry_read_offset);
+   return get_vue_slot(c, vert, vue_slot);
+}
+
+static bool
+have_attr(struct brw_sf_compile *c, GLuint attr)
 {
    return (c->key.attrs & BITFIELD64_BIT(attr)) ? 1 : 0;
 }
@@ -69,11 +105,11 @@ static void copy_bfc( struct brw_sf_compile *c,
    GLuint i;
 
    for (i = 0; i < 2; i++) {
-      if (have_attr(c, VERT_RESULT_COL0+i) &&
-         have_attr(c, VERT_RESULT_BFC0+i))
+      if (have_attr(c, VARYING_SLOT_COL0+i) &&
+         have_attr(c, VARYING_SLOT_BFC0+i))
         brw_MOV(p, 
-                get_vert_attr(c, vert, VERT_RESULT_COL0+i), 
-                get_vert_attr(c, vert, VERT_RESULT_BFC0+i));
+                get_varying(c, vert, VARYING_SLOT_COL0+i),
+                get_varying(c, vert, VARYING_SLOT_BFC0+i));
    }
 }
 
@@ -81,7 +117,6 @@ static void copy_bfc( struct brw_sf_compile *c,
 static void do_twoside_color( struct brw_sf_compile *c )
 {
    struct brw_compile *p = &c->func;
-   struct brw_instruction *if_insn;
    GLuint backface_conditional = c->key.frontface_ccw ? BRW_CONDITIONAL_G : BRW_CONDITIONAL_L;
 
    /* Already done in clip program:
@@ -89,14 +124,14 @@ static void do_twoside_color( struct brw_sf_compile *c )
    if (c->key.primitive == SF_UNFILLED_TRIS)
       return;
 
-   /* XXX: What happens if BFC isn't present?  This could only happen
-    * for user-supplied vertex programs, as t_vp_build.c always does
-    * the right thing.
+   /* If the vertex shader provides backface color, do the selection. The VS
+    * promises to set up the front color if the backface color is provided, but
+    * it may contain junk if never written to.
     */
-   if (!(have_attr(c, VERT_RESULT_COL0) && have_attr(c, VERT_RESULT_BFC0)) &&
-       !(have_attr(c, VERT_RESULT_COL1) && have_attr(c, VERT_RESULT_BFC1)))
+   if (!(have_attr(c, VARYING_SLOT_COL0) && have_attr(c, VARYING_SLOT_BFC0)) &&
+       !(have_attr(c, VARYING_SLOT_COL1) && have_attr(c, VARYING_SLOT_BFC1)))
       return;
-   
+
    /* Need to use BRW_EXECUTE_4 and also do an 4-wide compare in order
     * to get all channels active inside the IF.  In the clipping code
     * we run with NoMask, so it's not an option and we can use
@@ -104,7 +139,7 @@ static void do_twoside_color( struct brw_sf_compile *c )
     */
    brw_push_insn_state(p);
    brw_CMP(p, vec4(brw_null_reg()), backface_conditional, c->det, brw_imm_f(0));
-   if_insn = brw_IF(p, BRW_EXECUTE_4); 
+   brw_IF(p, BRW_EXECUTE_4);
    {
       switch (c->nr_verts) {
       case 3: copy_bfc(c, c->vert[2]);
@@ -112,7 +147,7 @@ static void do_twoside_color( struct brw_sf_compile *c )
       case 1: copy_bfc(c, c->vert[0]);
       }
    }
-   brw_ENDIF(p, if_insn);
+   brw_ENDIF(p);
    brw_pop_insn_state(p);
 }
 
@@ -122,24 +157,34 @@ static void do_twoside_color( struct brw_sf_compile *c )
  * Flat shading
  */
 
-#define VERT_RESULT_COLOR_BITS (BITFIELD64_BIT(VERT_RESULT_COL0) | \
-                               BITFIELD64_BIT(VERT_RESULT_COL1))
-
-static void copy_colors( struct brw_sf_compile *c,
-                    struct brw_reg dst,
-                    struct brw_reg src)
+static void copy_flatshaded_attributes(struct brw_sf_compile *c,
+                                       struct brw_reg dst,
+                                       struct brw_reg src)
 {
    struct brw_compile *p = &c->func;
-   GLuint i;
+   int i;
 
-   for (i = VERT_RESULT_COL0; i <= VERT_RESULT_COL1; i++) {
-      if (have_attr(c,i))
-        brw_MOV(p, 
-                get_vert_attr(c, dst, i), 
-                get_vert_attr(c, src, i));
+   for (i = 0; i < c->vue_map.num_slots; i++) {
+      if (c->key.interpolation_mode.mode[i] == INTERP_QUALIFIER_FLAT) {
+         brw_MOV(p,
+                 get_vue_slot(c, dst, i),
+                 get_vue_slot(c, src, i));
+      }
    }
 }
 
+static int count_flatshaded_attributes(struct brw_sf_compile *c)
+{
+   int i;
+   int count = 0;
+
+   for (i = 0; i < c->vue_map.num_slots; i++)
+      if (c->key.interpolation_mode.mode[i] == INTERP_QUALIFIER_FLAT)
+         count++;
+
+   return count;
+}
+
 
 
 /* Need to use a computed jump to copy flatshaded attributes as the
@@ -149,36 +194,36 @@ static void copy_colors( struct brw_sf_compile *c,
 static void do_flatshade_triangle( struct brw_sf_compile *c )
 {
    struct brw_compile *p = &c->func;
+   struct brw_context *brw = p->brw;
    struct brw_reg ip = brw_ip_reg();
-   GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
+   GLuint nr;
    GLuint jmpi = 1;
 
-   if (!nr)
-      return;
-
    /* Already done in clip program:
     */
    if (c->key.primitive == SF_UNFILLED_TRIS)
       return;
 
-   if (BRW_IS_IGDNG(p->brw))
+   if (brw->gen == 5)
        jmpi = 2;
 
+   nr = count_flatshaded_attributes(c);
+
    brw_push_insn_state(p);
-   
+
    brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr*2+1)));
    brw_JMPI(p, ip, ip, c->pv);
 
-   copy_colors(c, c->vert[1], c->vert[0]);
-   copy_colors(c, c->vert[2], c->vert[0]);
+   copy_flatshaded_attributes(c, c->vert[1], c->vert[0]);
+   copy_flatshaded_attributes(c, c->vert[2], c->vert[0]);
    brw_JMPI(p, ip, ip, brw_imm_d(jmpi*(nr*4+1)));
 
-   copy_colors(c, c->vert[0], c->vert[1]);
-   copy_colors(c, c->vert[2], c->vert[1]);
+   copy_flatshaded_attributes(c, c->vert[0], c->vert[1]);
+   copy_flatshaded_attributes(c, c->vert[2], c->vert[1]);
    brw_JMPI(p, ip, ip, brw_imm_d(jmpi*nr*2));
 
-   copy_colors(c, c->vert[0], c->vert[2]);
-   copy_colors(c, c->vert[1], c->vert[2]);
+   copy_flatshaded_attributes(c, c->vert[0], c->vert[2]);
+   copy_flatshaded_attributes(c, c->vert[1], c->vert[2]);
 
    brw_pop_insn_state(p);
 }
@@ -187,29 +232,29 @@ static void do_flatshade_triangle( struct brw_sf_compile *c )
 static void do_flatshade_line( struct brw_sf_compile *c )
 {
    struct brw_compile *p = &c->func;
+   struct brw_context *brw = p->brw;
    struct brw_reg ip = brw_ip_reg();
-   GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
+   GLuint nr;
    GLuint jmpi = 1;
 
-   if (!nr)
-      return;
-
    /* Already done in clip program: 
     */
    if (c->key.primitive == SF_UNFILLED_TRIS)
       return;
 
-   if (BRW_IS_IGDNG(p->brw))
+   if (brw->gen == 5)
        jmpi = 2;
 
+   nr = count_flatshaded_attributes(c);
+
    brw_push_insn_state(p);
    
    brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr+1)));
    brw_JMPI(p, ip, ip, c->pv);
-   copy_colors(c, c->vert[1], c->vert[0]);
+   copy_flatshaded_attributes(c, c->vert[1], c->vert[0]);
 
    brw_JMPI(p, ip, ip, brw_imm_ud(jmpi*nr));
-   copy_colors(c, c->vert[0], c->vert[1]);
+   copy_flatshaded_attributes(c, c->vert[0], c->vert[1]);
 
    brw_pop_insn_state(p);
 }
@@ -296,7 +341,6 @@ static void invert_det( struct brw_sf_compile *c)
    brw_math(&c->func, 
            c->inv_det, 
            BRW_MATH_FUNCTION_INV,
-           BRW_MATH_SATURATE_NONE,
            0, 
            c->det,
            BRW_MATH_DATA_SCALAR,
@@ -305,56 +349,75 @@ static void invert_det( struct brw_sf_compile *c)
 }
 
 
-static GLboolean calculate_masks( struct brw_sf_compile *c,
-                                 GLuint reg,
-                                 GLushort *pc,
-                                 GLushort *pc_persp,
-                                 GLushort *pc_linear)
+static bool
+calculate_masks(struct brw_sf_compile *c,
+                GLuint reg,
+                GLushort *pc,
+                GLushort *pc_persp,
+                GLushort *pc_linear)
 {
-   GLboolean is_last_attr = (reg == c->nr_setup_regs - 1);
-   GLbitfield64 persp_mask;
-   GLbitfield64 linear_mask;
-
-   if (c->key.do_flat_shading || c->key.linear_color)
-      persp_mask = c->key.attrs & ~(FRAG_BIT_WPOS |
-                                    FRAG_BIT_COL0 |
-                                    FRAG_BIT_COL1);
-   else
-      persp_mask = c->key.attrs & ~(FRAG_BIT_WPOS);
-
-   if (c->key.do_flat_shading)
-      linear_mask = c->key.attrs & ~(FRAG_BIT_COL0|FRAG_BIT_COL1);
-   else
-      linear_mask = c->key.attrs;
+   bool is_last_attr = (reg == c->nr_setup_regs - 1);
+   enum glsl_interp_qualifier interp;
 
    *pc_persp = 0;
    *pc_linear = 0;
    *pc = 0xf;
       
-   if (persp_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2]))
+   interp = c->key.interpolation_mode.mode[vert_reg_to_vue_slot(c, reg, 0)];
+   if (interp == INTERP_QUALIFIER_SMOOTH) {
+      *pc_linear = 0xf;
       *pc_persp = 0xf;
-
-   if (linear_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2]))
+   } else if (interp == INTERP_QUALIFIER_NOPERSPECTIVE)
       *pc_linear = 0xf;
 
    /* Maybe only processs one attribute on the final round:
     */
-   if (reg*2+1 < c->nr_setup_attrs) {
+   if (vert_reg_to_varying(c, reg, 1) != BRW_VARYING_SLOT_COUNT) {
       *pc |= 0xf0;
 
-      if (persp_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2+1]))
-        *pc_persp |= 0xf0;
-
-      if (linear_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2+1]))
-        *pc_linear |= 0xf0;
+      interp = c->key.interpolation_mode.mode[vert_reg_to_vue_slot(c, reg, 1)];
+      if (interp == INTERP_QUALIFIER_SMOOTH) {
+         *pc_linear |= 0xf0;
+         *pc_persp |= 0xf0;
+      } else if (interp == INTERP_QUALIFIER_NOPERSPECTIVE)
+         *pc_linear |= 0xf0;
    }
 
    return is_last_attr;
 }
 
+/* Calculates the predicate control for which channels of a reg
+ * (containing 2 attrs) to do point sprite coordinate replacement on.
+ */
+static uint16_t
+calculate_point_sprite_mask(struct brw_sf_compile *c, GLuint reg)
+{
+   int varying1, varying2;
+   uint16_t pc = 0;
+
+   varying1 = vert_reg_to_varying(c, reg, 0);
+   if (varying1 >= VARYING_SLOT_TEX0 && varying1 <= VARYING_SLOT_TEX7) {
+      if (c->key.point_sprite_coord_replace & (1 << (varying1 - VARYING_SLOT_TEX0)))
+        pc |= 0x0f;
+   }
+   if (varying1 == BRW_VARYING_SLOT_PNTC)
+      pc |= 0x0f;
+
+   varying2 = vert_reg_to_varying(c, reg, 1);
+   if (varying2 >= VARYING_SLOT_TEX0 && varying2 <= VARYING_SLOT_TEX7) {
+      if (c->key.point_sprite_coord_replace & (1 << (varying2 -
+                                                     VARYING_SLOT_TEX0)))
+         pc |= 0xf0;
+   }
+   if (varying2 == BRW_VARYING_SLOT_PNTC)
+      pc |= 0xf0;
+
+   return pc;
+}
 
 
-void brw_emit_tri_setup( struct brw_sf_compile *c, GLboolean allocate)
+
+void brw_emit_tri_setup(struct brw_sf_compile *c, bool allocate)
 {
    struct brw_compile *p = &c->func;
    GLuint i;
@@ -370,7 +433,7 @@ void brw_emit_tri_setup( struct brw_sf_compile *c, GLboolean allocate)
    if (c->key.do_twoside_color) 
       do_twoside_color(c);
 
-   if (c->key.do_flat_shading)
+   if (c->has_flat_shading)
       do_flatshade_triangle(c);
       
    
@@ -382,7 +445,7 @@ void brw_emit_tri_setup( struct brw_sf_compile *c, GLboolean allocate)
       struct brw_reg a1 = offset(c->vert[1], i);
       struct brw_reg a2 = offset(c->vert[2], i);
       GLushort pc, pc_persp, pc_linear;
-      GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
+      bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
 
       if (pc_persp)
       {
@@ -428,12 +491,10 @@ void brw_emit_tri_setup( struct brw_sf_compile *c, GLboolean allocate)
                       brw_null_reg(),
                       0,
                       brw_vec8_grf(0, 0), /* r0, will be copied to m0 */
-                      0,       /* allocate */
-                      1,       /* used */
+                       last ? BRW_URB_WRITE_EOT_COMPLETE
+                       : BRW_URB_WRITE_NO_FLAGS,
                       4,       /* msg len */
                       0,       /* response len */
-                      last,    /* eot */
-                      last,    /* writes complete */
                       i*4,     /* offset */
                       BRW_URB_SWIZZLE_TRANSPOSE); /* XXX: Swizzle control "SF to windower" */
       }
@@ -442,7 +503,7 @@ void brw_emit_tri_setup( struct brw_sf_compile *c, GLboolean allocate)
 
 
 
-void brw_emit_line_setup( struct brw_sf_compile *c, GLboolean allocate)
+void brw_emit_line_setup(struct brw_sf_compile *c, bool allocate)
 {
    struct brw_compile *p = &c->func;
    GLuint i;
@@ -456,7 +517,7 @@ void brw_emit_line_setup( struct brw_sf_compile *c, GLboolean allocate)
    invert_det(c);
    copy_z_inv_w(c);
 
-   if (c->key.do_flat_shading)
+   if (c->has_flat_shading)
       do_flatshade_line(c);
 
    for (i = 0; i < c->nr_setup_regs; i++)
@@ -466,7 +527,7 @@ void brw_emit_line_setup( struct brw_sf_compile *c, GLboolean allocate)
       struct brw_reg a0 = offset(c->vert[0], i);
       struct brw_reg a1 = offset(c->vert[1], i);
       GLushort pc, pc_persp, pc_linear;
-      GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
+      bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
 
       if (pc_persp)
       {
@@ -502,19 +563,17 @@ void brw_emit_line_setup( struct brw_sf_compile *c, GLboolean allocate)
                       brw_null_reg(),
                       0,
                       brw_vec8_grf(0, 0),
-                      0,       /* allocate */
-                      1,       /* used */
+                       last ? BRW_URB_WRITE_EOT_COMPLETE
+                       : BRW_URB_WRITE_NO_FLAGS,
                       4,       /* msg len */
                       0,       /* response len */
-                      last,    /* eot */
-                      last,    /* writes complete */
                       i*4,     /* urb destination offset */
                       BRW_URB_SWIZZLE_TRANSPOSE); 
       }
    } 
 }
 
-void brw_emit_point_sprite_setup( struct brw_sf_compile *c, GLboolean allocate)
+void brw_emit_point_sprite_setup(struct brw_sf_compile *c, bool allocate)
 {
    struct brw_compile *p = &c->func;
    GLuint i;
@@ -527,81 +586,84 @@ void brw_emit_point_sprite_setup( struct brw_sf_compile *c, GLboolean allocate)
    copy_z_inv_w(c);
    for (i = 0; i < c->nr_setup_regs; i++)
    {
-      struct brw_sf_point_tex *tex = &c->point_attrs[c->idx_to_attr[2*i]];
       struct brw_reg a0 = offset(c->vert[0], i);
-      GLushort pc, pc_persp, pc_linear;
-      GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
-            
-      if (pc_persp)
-      {                                
-         if (!tex->CoordReplace) {
-             brw_set_predicate_control_flag_value(p, pc_persp);
-             brw_MUL(p, a0, a0, c->inv_w[0]);
-         }
+      GLushort pc, pc_persp, pc_linear, pc_coord_replace;
+      bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
+
+      pc_coord_replace = calculate_point_sprite_mask(c, i);
+      pc_persp &= ~pc_coord_replace;
+
+      if (pc_persp) {
+        brw_set_predicate_control_flag_value(p, pc_persp);
+        brw_MUL(p, a0, a0, c->inv_w[0]);
       }
 
-      if (tex->CoordReplace) {
-         /* Caculate 1.0/PointWidth */
-         brw_math(&c->func,
+      /* Point sprite coordinate replacement: A texcoord with this
+       * enabled gets replaced with the value (x, y, 0, 1) where x and
+       * y vary from 0 to 1 across the horizontal and vertical of the
+       * point.
+       */
+      if (pc_coord_replace) {
+        brw_set_predicate_control_flag_value(p, pc_coord_replace);
+        /* Caculate 1.0/PointWidth */
+        brw_math(&c->func,
                  c->tmp,
                  BRW_MATH_FUNCTION_INV,
-                 BRW_MATH_SATURATE_NONE,
                  0,
                  c->dx0,
                  BRW_MATH_DATA_SCALAR,
                  BRW_MATH_PRECISION_FULL);
 
-         if (c->key.sprite_origin_lower_left) {
-               brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]);
-               brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0));
-               brw_MUL(p, c->m2Cy, c->tmp, negate(c->inv_w[0]));
-               brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0));
-         } else {
-               brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]);
-               brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0));
-               brw_MUL(p, c->m2Cy, c->tmp, c->inv_w[0]);
-               brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0));
-         }
-      } else {
-         brw_MOV(p, c->m1Cx, brw_imm_ud(0));
-         brw_MOV(p, c->m2Cy, brw_imm_ud(0));
-      }
+        brw_set_access_mode(p, BRW_ALIGN_16);
 
-      {
-        brw_set_predicate_control_flag_value(p, pc); 
-        if (tex->CoordReplace) {
-            if (c->key.sprite_origin_lower_left) {
-                brw_MUL(p, c->m3C0, c->inv_w[0], brw_imm_f(1.0));
-                brw_MOV(p, vec1(suboffset(c->m3C0, 0)), brw_imm_f(0.0));
-            }
-            else
-                brw_MOV(p, c->m3C0, brw_imm_f(0.0));
+        /* dA/dx, dA/dy */
+        brw_MOV(p, c->m1Cx, brw_imm_f(0.0));
+        brw_MOV(p, c->m2Cy, brw_imm_f(0.0));
+        brw_MOV(p, brw_writemask(c->m1Cx, WRITEMASK_X), c->tmp);
+        if (c->key.sprite_origin_lower_left) {
+           brw_MOV(p, brw_writemask(c->m2Cy, WRITEMASK_Y), negate(c->tmp));
         } else {
-               brw_MOV(p, c->m3C0, a0); /* constant value */
+           brw_MOV(p, brw_writemask(c->m2Cy, WRITEMASK_Y), c->tmp);
         }
 
-        /* Copy m0..m3 to URB. 
-         */
-        brw_urb_WRITE(p, 
-                      brw_null_reg(),
-                      0,
-                      brw_vec8_grf(0, 0),
-                      0,       /* allocate */
-                      1,       /* used */
-                      4,       /* msg len */
-                      0,       /* response len */
-                      last,    /* eot */
-                      last,    /* writes complete */
-                      i*4,     /* urb destination offset */
-                      BRW_URB_SWIZZLE_TRANSPOSE);
+        /* attribute constant offset */
+        brw_MOV(p, c->m3C0, brw_imm_f(0.0));
+        if (c->key.sprite_origin_lower_left) {
+           brw_MOV(p, brw_writemask(c->m3C0, WRITEMASK_YW), brw_imm_f(1.0));
+        } else {
+           brw_MOV(p, brw_writemask(c->m3C0, WRITEMASK_W), brw_imm_f(1.0));
+        }
+
+        brw_set_access_mode(p, BRW_ALIGN_1);
       }
+
+      if (pc & ~pc_coord_replace) {
+        brw_set_predicate_control_flag_value(p, pc & ~pc_coord_replace);
+        brw_MOV(p, c->m1Cx, brw_imm_ud(0));
+        brw_MOV(p, c->m2Cy, brw_imm_ud(0));
+        brw_MOV(p, c->m3C0, a0); /* constant value */
+      }
+
+
+      brw_set_predicate_control_flag_value(p, pc);
+      /* Copy m0..m3 to URB. */
+      brw_urb_WRITE(p,
+                   brw_null_reg(),
+                   0,
+                   brw_vec8_grf(0, 0),
+                    last ? BRW_URB_WRITE_EOT_COMPLETE
+                    : BRW_URB_WRITE_NO_FLAGS,
+                   4,  /* msg len */
+                   0,  /* response len */
+                   i*4,        /* urb destination offset */
+                   BRW_URB_SWIZZLE_TRANSPOSE);
    }
 }
 
 /* Points setup - several simplifications as all attributes are
  * constant across the face of the point (point sprites excluded!)
  */
-void brw_emit_point_setup( struct brw_sf_compile *c, GLboolean allocate)
+void brw_emit_point_setup(struct brw_sf_compile *c, bool allocate)
 {
    struct brw_compile *p = &c->func;
    GLuint i;
@@ -620,7 +682,7 @@ void brw_emit_point_setup( struct brw_sf_compile *c, GLboolean allocate)
    {
       struct brw_reg a0 = offset(c->vert[0], i);
       GLushort pc, pc_persp, pc_linear;
-      GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
+      bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
             
       if (pc_persp)
       {                                
@@ -647,12 +709,10 @@ void brw_emit_point_setup( struct brw_sf_compile *c, GLboolean allocate)
                       brw_null_reg(),
                       0,
                       brw_vec8_grf(0, 0),
-                      0,       /* allocate */
-                      1,       /* used */
+                       last ? BRW_URB_WRITE_EOT_COMPLETE
+                       : BRW_URB_WRITE_NO_FLAGS,
                       4,       /* msg len */
                       0,       /* response len */
-                      last,    /* eot */
-                      last,    /* writes complete */
                       i*4,     /* urb destination offset */
                       BRW_URB_SWIZZLE_TRANSPOSE);
       }
@@ -666,7 +726,7 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c )
    struct brw_reg payload_prim = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0);
    struct brw_reg payload_attr = get_element_ud(brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0), 0); 
    struct brw_reg primmask;
-   struct brw_instruction *jmp;
+   int jmp;
    struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD));
    
    GLuint saveflag;
@@ -687,11 +747,11 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c )
                                               (1<<_3DPRIM_POLYGON) |
                                               (1<<_3DPRIM_RECTLIST) |
                                               (1<<_3DPRIM_TRIFAN_NOSTIPPLE)));
-   jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
+   jmp = brw_JMPI(p, ip, ip, brw_imm_d(0)) - p->store;
    {
       saveflag = p->flag_value;
       brw_push_insn_state(p); 
-      brw_emit_tri_setup( c, GL_FALSE );
+      brw_emit_tri_setup( c, false );
       brw_pop_insn_state(p);
       p->flag_value = saveflag;
       /* note - thread killed in subroutine, so must
@@ -708,11 +768,11 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c )
                                               (1<<_3DPRIM_LINESTRIP_CONT) |
                                               (1<<_3DPRIM_LINESTRIP_BF) |
                                               (1<<_3DPRIM_LINESTRIP_CONT_BF)));
-   jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
+   jmp = brw_JMPI(p, ip, ip, brw_imm_d(0)) - p->store;
    {
       saveflag = p->flag_value;
       brw_push_insn_state(p); 
-      brw_emit_line_setup( c, GL_FALSE );
+      brw_emit_line_setup( c, false );
       brw_pop_insn_state(p);
       p->flag_value = saveflag;
       /* note - thread killed in subroutine */
@@ -721,17 +781,17 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c )
 
    brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
    brw_AND(p, v1_null_ud, payload_attr, brw_imm_ud(1<<BRW_SPRITE_POINT_ENABLE));
-   jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
+   jmp = brw_JMPI(p, ip, ip, brw_imm_d(0)) - p->store;
    {
       saveflag = p->flag_value;
       brw_push_insn_state(p); 
-      brw_emit_point_sprite_setup( c, GL_FALSE );
+      brw_emit_point_sprite_setup( c, false );
       brw_pop_insn_state(p);
       p->flag_value = saveflag;
    }
    brw_land_fwd_jump(p, jmp); 
 
-   brw_emit_point_setup( c, GL_FALSE );
+   brw_emit_point_setup( c, false );
 }