mesa: add/update comments in _mesa_copy_buffer_subdata()
[mesa.git] / src / mesa / drivers / dri / i965 / brw_vs_emit.c
index 674a994bace565d741c25f1b86f6ce2f5d3f6226..2b4b13a10d9956b6ed2bdca12d873b7bd2eec547 100644 (file)
@@ -40,7 +40,7 @@
 /* Return the SrcReg index of the channels that can be immediate float operands
  * instead of usage of PROGRAM_CONSTANT values through push/pull.
  */
-static GLboolean
+static bool
 brw_vs_arg_can_be_immediate(enum prog_opcode opcode, int arg)
 {
    int opcode_array[] = {
@@ -68,11 +68,11 @@ brw_vs_arg_can_be_immediate(enum prog_opcode opcode, int arg)
     */
    if (opcode == OPCODE_MAD || opcode == OPCODE_LRP) {
       if (arg == 1 || arg == 2)
-        return GL_TRUE;
+        return true;
    }
 
    if (opcode > ARRAY_SIZE(opcode_array))
-      return GL_FALSE;
+      return false;
 
    return arg == opcode_array[opcode] - 1;
 }
@@ -132,6 +132,40 @@ clear_current_const(struct brw_vs_compile *c)
    }
 }
 
+/* The message length for all SEND messages is restricted to [1,15].  This
+ * includes 1 for the header, so anything in slots 14 and above needs to be
+ * placed in a general-purpose register and emitted using a second URB write.
+ */
+#define MAX_SLOTS_IN_FIRST_URB_WRITE 14
+
+/**
+ * Determine whether the given vertex output can be written directly to a MRF
+ * or whether it has to be stored in a general-purpose register.
+ */
+static inline bool can_use_direct_mrf(int vert_result,
+                                      int first_reladdr_output, int slot)
+{
+   if (vert_result == VERT_RESULT_HPOS || vert_result == VERT_RESULT_PSIZ) {
+      /* These never go straight into MRF's.  They are placed in the MRF by
+       * epilog code.
+       */
+      return false;
+   }
+   if (first_reladdr_output <= vert_result && vert_result < VERT_RESULT_MAX) {
+      /* Relative addressing might be used to access this vert_result, so it
+       * needs to go into a general-purpose register.
+       */
+      return false;
+   }
+   if (slot >= MAX_SLOTS_IN_FIRST_URB_WRITE) {
+      /* This output won't go out until the second URB write so it must be
+       * stored in a general-purpose register until then.
+       */
+      return false;
+   }
+   return true;
+}
+
 /**
  * Preallocate GRF register before code emit.
  * Do things as simply as possible.  Allocate and populate all regs
@@ -140,13 +174,13 @@ clear_current_const(struct brw_vs_compile *c)
 static void brw_vs_alloc_regs( struct brw_vs_compile *c )
 {
    struct intel_context *intel = &c->func.brw->intel;
-   GLuint i, reg = 0, mrf, j;
+   GLuint i, reg = 0, slot;
    int attributes_in_vue;
    int first_reladdr_output;
    int max_constant;
    int constant = 0;
-   int vert_result_reoder[VERT_RESULT_MAX];
-   int bfc = 0;
+   struct brw_vertex_program *vp = c->vp;
+   const struct gl_program_parameter_list *params = vp->program.Base.Parameters;
 
    /* Determine whether to use a real constant buffer or use a block
     * of GRF registers for constants.  The later is faster but only
@@ -155,9 +189,9 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
     */
    if (c->vp->program.Base.Parameters->NumParameters +
        c->vp->program.Base.NumTemporaries + 20 > BRW_MAX_GRF)
-      c->vp->use_const_buffer = GL_TRUE;
+      c->vp->use_const_buffer = true;
    else
-      c->vp->use_const_buffer = GL_FALSE;
+      c->vp->use_const_buffer = false;
 
    /*printf("use_const_buffer = %d\n", c->vp->use_const_buffer);*/
 
@@ -168,19 +202,19 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
 
    /* User clip planes from curbe: 
     */
-   if (c->key.nr_userclip) {
+   if (c->key.userclip_active) {
       if (intel->gen >= 6) {
-        for (i = 0; i < c->key.nr_userclip; i++) {
+        for (i = 0; i <= c->key.nr_userclip_plane_consts; i++) {
            c->userplane[i] = stride(brw_vec4_grf(reg + i / 2,
                                                  (i % 2) * 4), 0, 4, 1);
         }
-        reg += ALIGN(c->key.nr_userclip, 2) / 2;
+        reg += ALIGN(c->key.nr_userclip_plane_consts, 2) / 2;
       } else {
-        for (i = 0; i < c->key.nr_userclip; i++) {
+        for (i = 0; i < c->key.nr_userclip_plane_consts; i++) {
            c->userplane[i] = stride(brw_vec4_grf(reg + (6 + i) / 2,
                                                  (i % 2) * 4), 0, 4, 1);
         }
-        reg += (ALIGN(6 + c->key.nr_userclip, 4) / 4) * 2;
+        reg += (ALIGN(6 + c->key.nr_userclip_plane_consts, 4) / 4) * 2;
       }
 
    }
@@ -205,7 +239,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
     */
    if (intel->gen >= 6) {
       /* We can only load 32 regs of push constants. */
-      max_constant = 32 * 2 - c->key.nr_userclip;
+      max_constant = 32 * 2 - c->key.nr_userclip_plane_consts;
    } else {
       max_constant = BRW_MAX_GRF - 20 - c->vp->program.Base.NumTemporaries;
    }
@@ -231,7 +265,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
         }
 
         if (inst->SrcReg[arg].RelAddr) {
-           c->vp->use_const_buffer = GL_TRUE;
+           c->vp->use_const_buffer = true;
            continue;
         }
 
@@ -247,7 +281,19 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
     * case) we need them all in place anyway.
     */
    if (constant == max_constant)
-      c->vp->use_const_buffer = GL_TRUE;
+      c->vp->use_const_buffer = true;
+
+   /* Set up the references to the pull parameters if present.  This backend
+    * uses a 1:1 mapping from Mesa IR's index to location in the pull constant
+    * buffer, while the new VS backend allocates values to the pull buffer on
+    * demand.
+    */
+   if (c->vp->use_const_buffer) {
+      for (i = 0; i < params->NumParameters * 4; i++) {
+        c->prog_data.pull_param[i] = &params->ParameterValues[i / 4][i % 4].f;
+      }
+      c->prog_data.nr_pull_params = i;
+   }
 
    for (i = 0; i < constant; i++) {
       c->regs[PROGRAM_STATE_VAR][i] = stride(brw_vec4_grf(reg + i / 2,
@@ -265,7 +311,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
     */
    c->nr_inputs = 0;
    for (i = 0; i < VERT_ATTRIB_MAX; i++) {
-      if (c->prog_data.inputs_read & (1 << i)) {
+      if (c->prog_data.inputs_read & BITFIELD64_BIT(i)) {
         c->nr_inputs++;
         c->regs[PROGRAM_INPUT][i] = brw_vec8_grf(reg, 0);
         reg++;
@@ -279,88 +325,20 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
 
    /* Allocate outputs.  The non-position outputs go straight into message regs.
     */
-   c->nr_outputs = 0;
+   brw_compute_vue_map(&c->vue_map, intel, c->key.userclip_active,
+                       c->prog_data.outputs_written);
    c->first_output = reg;
-   c->first_overflow_output = 0;
-
-   if (intel->gen >= 6) {
-      mrf = 3;
-      if (c->key.nr_userclip)
-        mrf += 2;
-   } else if (intel->gen == 5)
-      mrf = 8;
-   else
-      mrf = 4;
 
    first_reladdr_output = get_first_reladdr_output(&c->vp->program);
 
-   for (i = 0; i < VERT_RESULT_MAX; i++)
-       vert_result_reoder[i] = i;
-
-   /* adjust attribute order in VUE for BFC0/BFC1 on Gen6+ */
-   if (intel->gen >= 6 && c->key.two_side_color) {
-       if ((c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_COL1)) &&
-           (c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_BFC1))) {
-           assert(c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_COL0));
-           assert(c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_BFC0));
-           bfc = 2;
-       } else if ((c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_COL0)) &&
-           (c->prog_data.outputs_written & BITFIELD64_BIT(VERT_RESULT_BFC0)))
-           bfc = 1;
-
-       if (bfc) {
-           for (i = 0; i < bfc; i++) {
-               vert_result_reoder[VERT_RESULT_COL0 + i * 2 + 0] = VERT_RESULT_COL0 + i;
-               vert_result_reoder[VERT_RESULT_COL0 + i * 2 + 1] = VERT_RESULT_BFC0 + i;
-           }
-
-           for (i = VERT_RESULT_COL0 + bfc * 2; i < VERT_RESULT_BFC0 + bfc; i++) {
-               vert_result_reoder[i] = i - bfc;
-           }
-       }
-   }
-
-   for (j = 0; j < VERT_RESULT_MAX; j++) {
-      i = vert_result_reoder[j];
-
-      if (c->prog_data.outputs_written & BITFIELD64_BIT(i)) {
-        c->nr_outputs++;
-         assert(i < Elements(c->regs[PROGRAM_OUTPUT]));
-        if (i == VERT_RESULT_HPOS) {
-           c->regs[PROGRAM_OUTPUT][i] = brw_vec8_grf(reg, 0);
-           reg++;
-        }
-        else if (i == VERT_RESULT_PSIZ) {
-           c->regs[PROGRAM_OUTPUT][i] = brw_vec8_grf(reg, 0);
-           reg++;
-        }
-        else {
-           /* Two restrictions on our compute-to-MRF here.  The
-            * message length for all SEND messages is restricted to
-            * [1,15], so we can't use mrf 15, as that means a length
-            * of 16.
-            *
-            * Additionally, URB writes are aligned to URB rows, so we
-            * need to put an even number of registers of URB data in
-            * each URB write so that the later write is aligned.  A
-            * message length of 15 means 1 message header reg plus 14
-            * regs of URB data.
-            *
-            * For attributes beyond the compute-to-MRF, we compute to
-            * GRFs and they will be written in the second URB_WRITE.
-            */
-            if (first_reladdr_output > i && mrf < 15) {
-               c->regs[PROGRAM_OUTPUT][i] = brw_message_reg(mrf);
-               mrf++;
-            }
-            else {
-               if (mrf >= 15 && !c->first_overflow_output)
-                  c->first_overflow_output = i;
-               c->regs[PROGRAM_OUTPUT][i] = brw_vec8_grf(reg, 0);
-               reg++;
-              mrf++;
-            }
-        }
+   for (slot = 0; slot < c->vue_map.num_slots; slot++) {
+      int vert_result = c->vue_map.slot_to_vert_result[slot];
+      assert(vert_result < Elements(c->regs[PROGRAM_OUTPUT]));
+      if (can_use_direct_mrf(vert_result, first_reladdr_output, slot)) {
+         c->regs[PROGRAM_OUTPUT][vert_result] = brw_message_reg(slot + 1);
+      } else {
+         c->regs[PROGRAM_OUTPUT][vert_result] = brw_vec8_grf(reg, 0);
+         reg++;
       }
    }     
 
@@ -427,36 +405,19 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
    /* The VS VUEs are shared by VF (outputting our inputs) and VS, so size
     * them to fit the biggest thing they need to.
     */
-   attributes_in_vue = MAX2(c->nr_outputs, c->nr_inputs);
-
-   /* See emit_vertex_write() for where the VUE's overhead on top of the
-    * attributes comes from.
-    */
-   if (intel->gen >= 7) {
-      int header_regs = 2;
-      if (c->key.nr_userclip)
-        header_regs += 2;
+   attributes_in_vue = MAX2(c->vue_map.num_slots, c->nr_inputs);
 
-      /* Each attribute is 16 bytes (1 vec4), so dividing by 4 gives us the
-       * number of 64-byte (512-bit) units.
-       */
-      c->prog_data.urb_entry_size = (attributes_in_vue + header_regs + 3) / 4;
-   } else if (intel->gen == 6) {
-      int header_regs = 2;
-      if (c->key.nr_userclip)
-        header_regs += 2;
-
-      /* Each attribute is 16 bytes (1 vec4), so dividing by 8 gives us the
+   if (intel->gen == 6) {
+      /* Each attribute is 32 bytes (2 vec4s), so dividing by 8 gives us the
        * number of 128-byte (1024-bit) units.
        */
-      c->prog_data.urb_entry_size = (attributes_in_vue + header_regs + 7) / 8;
-   } else if (intel->gen == 5)
+      c->prog_data.urb_entry_size = ALIGN(attributes_in_vue, 8) / 8;
+   } else {
       /* Each attribute is 16 bytes (1 vec4), so dividing by 4 gives us the
        * number of 64-byte (512-bit) units.
        */
-      c->prog_data.urb_entry_size = (attributes_in_vue + 6 + 3) / 4;
-   else
-      c->prog_data.urb_entry_size = (attributes_in_vue + 2 + 3) / 4;
+      c->prog_data.urb_entry_size = ALIGN(attributes_in_vue, 4) / 4;
+   }
 
    c->prog_data.total_grf = reg;
 
@@ -704,11 +665,11 @@ static void emit_math1_gen4(struct brw_vs_compile *c,
     */
    struct brw_compile *p = &c->func;
    struct brw_reg tmp = dst;
-   GLboolean need_tmp = GL_FALSE;
+   bool need_tmp = false;
 
    if (dst.file != BRW_GENERAL_REGISTER_FILE ||
        dst.dw1.bits.writemask != 0xf)
-      need_tmp = GL_TRUE;
+      need_tmp = true;
 
    if (need_tmp)
       tmp = get_tmp(c);
@@ -789,11 +750,11 @@ static void emit_math2_gen4( struct brw_vs_compile *c,
 {
    struct brw_compile *p = &c->func;
    struct brw_reg tmp = dst;
-   GLboolean need_tmp = GL_FALSE;
+   bool need_tmp = false;
 
    if (dst.file != BRW_GENERAL_REGISTER_FILE ||
        dst.dw1.bits.writemask != 0xf)
-      need_tmp = GL_TRUE;
+      need_tmp = true;
 
    if (need_tmp) 
       tmp = get_tmp(c);
@@ -928,7 +889,7 @@ static void emit_log_noalias( struct brw_vs_compile *c,
    struct brw_reg tmp = dst;
    struct brw_reg tmp_ud = retype(tmp, BRW_REGISTER_TYPE_UD);
    struct brw_reg arg0_ud = retype(arg0, BRW_REGISTER_TYPE_UD);
-   GLboolean need_tmp = (dst.dw1.bits.writemask != 0xf ||
+   bool need_tmp = (dst.dw1.bits.writemask != 0xf ||
                         dst.file != BRW_GENERAL_REGISTER_FILE);
 
    if (need_tmp) {
@@ -1049,7 +1010,7 @@ static void emit_lit_noalias( struct brw_vs_compile *c,
 {
    struct brw_compile *p = &c->func;
    struct brw_reg tmp = dst;
-   GLboolean need_tmp = (dst.file != BRW_GENERAL_REGISTER_FILE);
+   bool need_tmp = (dst.file != BRW_GENERAL_REGISTER_FILE);
 
    if (need_tmp) 
       tmp = get_tmp(c);
@@ -1096,31 +1057,6 @@ static void emit_lrp_noalias(struct brw_vs_compile *c,
    brw_MAC(p, dst, arg0, arg1);
 }
 
-/** 3 or 4-component vector normalization */
-static void emit_nrm( struct brw_vs_compile *c, 
-                      struct brw_reg dst,
-                      struct brw_reg arg0,
-                      int num_comps)
-{
-   struct brw_compile *p = &c->func;
-   struct brw_reg tmp = get_tmp(c);
-
-   /* tmp = dot(arg0, arg0) */
-   if (num_comps == 3)
-      brw_DP3(p, tmp, arg0, arg0);
-   else
-      brw_DP4(p, tmp, arg0, arg0);
-
-   /* tmp = 1 / sqrt(tmp) */
-   emit_math1(c, BRW_MATH_FUNCTION_RSQ, tmp, tmp, BRW_MATH_PRECISION_FULL);
-
-   /* dst = arg0 * tmp */
-   brw_MUL(p, dst, arg0, tmp);
-
-   release_tmp(c, tmp);
-}
-
-
 static struct brw_reg
 get_constant(struct brw_vs_compile *c,
              const struct prog_instruction *inst,
@@ -1319,7 +1255,7 @@ get_src_reg( struct brw_vs_compile *c,
 {
    const GLuint file = inst->SrcReg[argIndex].File;
    const GLint index = inst->SrcReg[argIndex].Index;
-   const GLboolean relAddr = inst->SrcReg[argIndex].RelAddr;
+   const bool relAddr = inst->SrcReg[argIndex].RelAddr;
 
    if (brw_vs_arg_can_be_immediate(inst->Opcode, argIndex)) {
       const struct prog_src_register *src = &inst->SrcReg[argIndex];
@@ -1359,7 +1295,7 @@ get_src_reg( struct brw_vs_compile *c,
 
         if (component >= 0) {
            params = c->vp->program.Base.Parameters;
-           f = params->ParameterValues[src->Index][component];
+           f = params->ParameterValues[src->Index][component].f;
 
            if (src->Abs)
               f = fabs(f);
@@ -1502,7 +1438,7 @@ static void emit_swz( struct brw_vs_compile *c,
    GLuint ones_mask = 0;
    GLuint src_mask = 0;
    GLubyte src_swz[4];
-   GLboolean need_tmp = (src.Negate &&
+   bool need_tmp = (src.Negate &&
                         dst.file != BRW_GENERAL_REGISTER_FILE);
    struct brw_reg tmp = dst;
    GLuint i;
@@ -1593,8 +1529,9 @@ static void emit_vertex_write( struct brw_vs_compile *c)
    struct brw_reg ndc;
    int eot;
    GLuint len_vertex_header = 2;
-   int next_mrf, i;
+   int i;
    int msg_len;
+   int slot;
 
    if (c->key.copy_edgeflag) {
       brw_MOV(p, 
@@ -1627,8 +1564,8 @@ static void emit_vertex_write( struct brw_vs_compile *c)
       }
 
       /* Set the user clip distances in dword 8-15. (m3-4)*/
-      if (c->key.nr_userclip) {
-        for (i = 0; i < c->key.nr_userclip; i++) {
+      if (c->key.userclip_active) {
+        for (i = 0; i < c->key.nr_userclip_plane_consts; i++) {
            struct brw_reg m;
            if (i < 4)
               m = brw_message_reg(3);
@@ -1640,7 +1577,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
       }
    } else if ((c->prog_data.outputs_written &
               BITFIELD64_BIT(VERT_RESULT_PSIZ)) ||
-             c->key.nr_userclip || brw->has_negative_rhw_bug) {
+             c->key.userclip_active || brw->has_negative_rhw_bug) {
       struct brw_reg header1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
       GLuint i;
 
@@ -1656,7 +1593,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
                 header1, brw_imm_ud(0x7ff<<8));
       }
 
-      for (i = 0; i < c->key.nr_userclip; i++) {
+      for (i = 0; i < c->key.nr_userclip_plane_consts; i++) {
         brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
         brw_DP4(p, brw_null_reg(), pos, c->userplane[i]);
         brw_OR(p, brw_writemask(header1, WRITEMASK_W), header1, brw_imm_ud(1<<i));
@@ -1712,7 +1649,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
        */
       brw_MOV(p, brw_message_reg(2), pos);
       len_vertex_header = 1;
-      if (c->key.nr_userclip > 0)
+      if (c->key.userclip_active)
         len_vertex_header += 2;
    } else if (intel->gen == 5) {
       /* There are 20 DWs (D0-D19) in VUE header on Ironlake:
@@ -1741,31 +1678,26 @@ static void emit_vertex_write( struct brw_vs_compile *c)
    }
 
    /* Move variable-addressed, non-overflow outputs to their MRFs. */
-   next_mrf = 2 + len_vertex_header;
-   for (i = 0; i < VERT_RESULT_MAX; i++) {
-      if (c->first_overflow_output > 0 && i >= c->first_overflow_output)
-        break;
-      if (!(c->prog_data.outputs_written & BITFIELD64_BIT(i)))
-        continue;
-      if (i == VERT_RESULT_PSIZ)
-        continue;
+   for (slot = len_vertex_header; slot < c->vue_map.num_slots; ++slot) {
+      if (slot >= MAX_SLOTS_IN_FIRST_URB_WRITE)
+         break;
 
-      if (i >= VERT_RESULT_TEX0 &&
-         c->regs[PROGRAM_OUTPUT][i].file == BRW_GENERAL_REGISTER_FILE) {
-        brw_MOV(p, brw_message_reg(next_mrf), c->regs[PROGRAM_OUTPUT][i]);
-        next_mrf++;
-      } else if (c->regs[PROGRAM_OUTPUT][i].file == BRW_MESSAGE_REGISTER_FILE) {
-        next_mrf = c->regs[PROGRAM_OUTPUT][i].nr + 1;
+      int mrf = slot + 1;
+      int vert_result = c->vue_map.slot_to_vert_result[slot];
+      if (c->regs[PROGRAM_OUTPUT][vert_result].file ==
+          BRW_GENERAL_REGISTER_FILE) {
+         brw_MOV(p, brw_message_reg(mrf),
+                 c->regs[PROGRAM_OUTPUT][vert_result]);
       }
    }
 
-   eot = (c->first_overflow_output == 0);
+   eot = (slot >= c->vue_map.num_slots);
 
-   /* Message header, plus VUE header, plus the (first set of) outputs. */
-   msg_len = 1 + len_vertex_header + c->nr_outputs;
+   /* Message header, plus the (first part of the) VUE. */
+   msg_len = 1 + slot;
    msg_len = align_interleaved_urb_mlen(brw, msg_len);
-   /* Any outputs beyond BRW_MAX_MRF should be past first_overflow_output */
-   msg_len = MIN2(msg_len, (BRW_MAX_MRF - 1)),
+   /* Any outputs beyond BRW_MAX_MRF should be in the second URB write */
+   assert (msg_len <= BRW_MAX_MRF - 1);
 
    brw_urb_WRITE(p, 
                 brw_null_reg(), /* dest */
@@ -1780,18 +1712,18 @@ static void emit_vertex_write( struct brw_vs_compile *c)
                 0,             /* urb destination offset */
                 BRW_URB_SWIZZLE_INTERLEAVE);
 
-   if (c->first_overflow_output > 0) {
+   if (slot < c->vue_map.num_slots) {
       /* Not all of the vertex outputs/results fit into the MRF.
        * Move the overflowed attributes from the GRF to the MRF and
        * issue another brw_urb_WRITE().
        */
-      GLuint i, mrf = 1;
-      for (i = c->first_overflow_output; i < VERT_RESULT_MAX; i++) {
-         if (c->prog_data.outputs_written & BITFIELD64_BIT(i)) {
-            /* move from GRF to MRF */
-            brw_MOV(p, brw_message_reg(mrf), c->regs[PROGRAM_OUTPUT][i]);
-            mrf++;
-         }
+      GLuint mrf = 1;
+      for (; slot < c->vue_map.num_slots; ++slot) {
+         int vert_result = c->vue_map.slot_to_vert_result[slot];
+         /* move from GRF to MRF */
+         brw_MOV(p, brw_message_reg(mrf),
+                 c->regs[PROGRAM_OUTPUT][vert_result]);
+         mrf++;
       }
 
       brw_urb_WRITE(p,
@@ -1804,25 +1736,25 @@ static void emit_vertex_write( struct brw_vs_compile *c)
                     0,              /* response len */
                     1,              /* eot */
                     1,              /* writes complete */
-                    14 / 2,  /* urb destination offset */
+                    MAX_SLOTS_IN_FIRST_URB_WRITE / 2,  /* urb destination offset */
                     BRW_URB_SWIZZLE_INTERLEAVE);
    }
 }
 
-static GLboolean
+static bool
 accumulator_contains(struct brw_vs_compile *c, struct brw_reg val)
 {
    struct brw_compile *p = &c->func;
    struct brw_instruction *prev_insn = &p->store[p->nr_insn - 1];
 
    if (p->nr_insn == 0)
-      return GL_FALSE;
+      return false;
 
    if (val.address_mode != BRW_ADDRESS_DIRECT)
-      return GL_FALSE;
+      return false;
 
    if (val.negate || val.abs)
-      return GL_FALSE;
+      return false;
 
    switch (prev_insn->header.opcode) {
    case BRW_OPCODE_MOV:
@@ -1836,11 +1768,11 @@ accumulator_contains(struct brw_vs_compile *c, struct brw_reg val)
          prev_insn->bits1.da1.dest_reg_nr == val.nr &&
          prev_insn->bits1.da16.dest_subreg_nr == val.subnr / 16 &&
          prev_insn->bits1.da16.dest_writemask == 0xf)
-        return GL_TRUE;
+        return true;
       else
-        return GL_FALSE;
+        return false;
    default:
-      return GL_FALSE;
+      return false;
    }
 }
 
@@ -1888,7 +1820,7 @@ brw_vs_rescale_gl_fixed(struct brw_vs_compile *c)
    int i;
 
    for (i = 0; i < VERT_ATTRIB_MAX; i++) {
-      if (!(c->prog_data.inputs_read & (1 << i)))
+      if (!(c->prog_data.inputs_read & BITFIELD64_BIT(i)))
         continue;
 
       if (c->key.gl_fixed_input_size[i] != 0) {
@@ -1903,7 +1835,7 @@ brw_vs_rescale_gl_fixed(struct brw_vs_compile *c)
 
 /* Emit the vertex program instructions here.
  */
-void brw_vs_emit(struct brw_vs_compile *c )
+void brw_old_vs_emit(struct brw_vs_compile *c )
 {
 #define MAX_IF_DEPTH 32
 #define MAX_LOOP_DEPTH 32
@@ -1911,9 +1843,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
    struct brw_context *brw = p->brw;
    struct intel_context *intel = &brw->intel;
    const GLuint nr_insns = c->vp->program.Base.NumInstructions;
-   GLuint insn, loop_depth = 0;
-   struct brw_instruction *loop_inst[MAX_LOOP_DEPTH] = { 0 };
-   int if_depth_in_loop[MAX_LOOP_DEPTH];
+   GLuint insn;
    const struct brw_indirect stack_index = brw_indirect(0, 0);   
    GLuint index;
    GLuint file;
@@ -1921,13 +1851,12 @@ void brw_vs_emit(struct brw_vs_compile *c )
    if (unlikely(INTEL_DEBUG & DEBUG_VS)) {
       printf("vs-mesa:\n");
       _mesa_fprint_program_opt(stdout, &c->vp->program.Base, PROG_PRINT_DEBUG,
-                              GL_TRUE);
+                              true);
       printf("\n");
    }
 
    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
    brw_set_access_mode(p, BRW_ALIGN_16);
-   if_depth_in_loop[loop_depth] = 0;
 
    brw_set_acc_write_control(p, 1);
 
@@ -1943,13 +1872,13 @@ void brw_vs_emit(struct brw_vs_compile *c )
           GLuint index = src->Index;
           GLuint file = src->File;     
           if (file == PROGRAM_OUTPUT && index != VERT_RESULT_HPOS)
-              c->output_regs[index].used_in_src = GL_TRUE;
+              c->output_regs[index].used_in_src = true;
        }
 
        switch (inst->Opcode) {
        case OPCODE_CAL:
        case OPCODE_RET:
-         c->needs_stack = GL_TRUE;
+         c->needs_stack = true;
          break;
        default:
          break;
@@ -2045,12 +1974,6 @@ void brw_vs_emit(struct brw_vs_compile *c )
       case OPCODE_DPH:
         brw_DPH(p, dst, args[0], args[1]);
         break;
-      case OPCODE_NRM3:
-        emit_nrm(c, dst, args[0], 3);
-        break;
-      case OPCODE_NRM4:
-        emit_nrm(c, dst, args[0], 4);
-        break;
       case OPCODE_DST:
         unalias2(c, dst, args[0], args[1], emit_dst_noalias); 
         break;
@@ -2155,7 +2078,6 @@ void brw_vs_emit(struct brw_vs_compile *c )
         struct brw_instruction *if_inst = brw_IF(p, BRW_EXECUTE_8);
         /* Note that brw_IF smashes the predicate_control field. */
         if_inst->header.predicate_control = get_predicate(inst);
-        if_depth_in_loop[loop_depth]++;
         break;
       }
       case OPCODE_ELSE:
@@ -2165,54 +2087,29 @@ void brw_vs_emit(struct brw_vs_compile *c )
       case OPCODE_ENDIF:
         clear_current_const(c);
         brw_ENDIF(p);
-        if_depth_in_loop[loop_depth]--;
         break;                 
       case OPCODE_BGNLOOP:
         clear_current_const(c);
-         loop_inst[loop_depth++] = brw_DO(p, BRW_EXECUTE_8);
-        if_depth_in_loop[loop_depth] = 0;
+        brw_DO(p, BRW_EXECUTE_8);
          break;
       case OPCODE_BRK:
         brw_set_predicate_control(p, get_predicate(inst));
-        brw_BREAK(p, if_depth_in_loop[loop_depth]);
+        brw_BREAK(p);
         brw_set_predicate_control(p, BRW_PREDICATE_NONE);
          break;
       case OPCODE_CONT:
         brw_set_predicate_control(p, get_predicate(inst));
         if (intel->gen >= 6) {
-           gen6_CONT(p, loop_inst[loop_depth - 1]);
+           gen6_CONT(p);
         } else {
-           brw_CONT(p, if_depth_in_loop[loop_depth]);
+           brw_CONT(p);
         }
          brw_set_predicate_control(p, BRW_PREDICATE_NONE);
          break;
 
-      case OPCODE_ENDLOOP: {
+      case OPCODE_ENDLOOP:
         clear_current_const(c);
-        struct brw_instruction *inst0, *inst1;
-        GLuint br = 1;
-
-        loop_depth--;
-
-        if (intel->gen == 5)
-           br = 2;
-
-        inst0 = inst1 = brw_WHILE(p, loop_inst[loop_depth]);
-
-        if (intel->gen < 6) {
-           /* patch all the BREAK/CONT instructions from last BEGINLOOP */
-           while (inst0 > loop_inst[loop_depth]) {
-              inst0--;
-              if (inst0->header.opcode == BRW_OPCODE_BREAK &&
-                  inst0->bits3.if_else.jump_count == 0) {
-                 inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
-              } else if (inst0->header.opcode == BRW_OPCODE_CONTINUE &&
-                         inst0->bits3.if_else.jump_count == 0) {
-                 inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
-              }
-           }
-        }
-      }
+        brw_WHILE(p);
          break;
 
       case OPCODE_BRA: