i965: Assert that an OPCODE_IF was seen before an OPCODE_ELSE.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_sf_emit.c
index 2f63610425006213b91274b9d82de49287f46453..56f7c986e7844c4dd58d66a109b7d8e9513f1bc9 100644 (file)
@@ -56,7 +56,7 @@ static struct brw_reg get_vert_attr(struct brw_sf_compile *c,
 static GLboolean have_attr(struct brw_sf_compile *c,
                           GLuint attr)
 {
-   return (c->key.attrs & (1<<attr)) ? 1 : 0;
+   return (c->key.attrs & BITFIELD64_BIT(attr)) ? 1 : 0;
 }
 
 /*********************************************************************** 
@@ -122,8 +122,8 @@ static void do_twoside_color( struct brw_sf_compile *c )
  * Flat shading
  */
 
-#define VERT_RESULT_COLOR_BITS ((1<<VERT_RESULT_COL0) | \
-                                 (1<<VERT_RESULT_COL1))
+#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,
@@ -149,8 +149,11 @@ 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 intel_context *intel = &p->brw->intel;
    struct brw_reg ip = brw_ip_reg();
    GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
+   GLuint jmpi = 1;
+
    if (!nr)
       return;
 
@@ -159,18 +162,21 @@ static void do_flatshade_triangle( struct brw_sf_compile *c )
    if (c->key.primitive == SF_UNFILLED_TRIS)
       return;
 
+   if (intel->is_ironlake)
+       jmpi = 2;
+
    brw_push_insn_state(p);
    
-   brw_MUL(p, c->pv, c->pv, brw_imm_ud(nr*2+1));
+   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]);
-   brw_JMPI(p, ip, ip, brw_imm_ud(nr*4+1));
+   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]);
-   brw_JMPI(p, ip, ip, brw_imm_ud(nr*2));
+   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]);
@@ -182,9 +188,11 @@ 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 intel_context *intel = &p->brw->intel;
    struct brw_reg ip = brw_ip_reg();
    GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
-   
+   GLuint jmpi = 1;
+
    if (!nr)
       return;
 
@@ -193,13 +201,16 @@ static void do_flatshade_line( struct brw_sf_compile *c )
    if (c->key.primitive == SF_UNFILLED_TRIS)
       return;
 
+   if (intel->is_ironlake)
+       jmpi = 2;
+
    brw_push_insn_state(p);
    
-   brw_MUL(p, c->pv, c->pv, brw_imm_ud(nr+1));
+   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]);
 
-   brw_JMPI(p, ip, ip, brw_imm_ud(nr));
+   brw_JMPI(p, ip, ip, brw_imm_ud(jmpi*nr));
    copy_colors(c, c->vert[0], c->vert[1]);
 
    brw_pop_insn_state(p);
@@ -218,7 +229,7 @@ static void alloc_regs( struct brw_sf_compile *c )
 
    /* Values computed by fixed function unit:
     */
-   c->pv  = retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_UD);
+   c->pv  = retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_D);
    c->det = brw_vec1_grf(1, 2);
    c->dx0 = brw_vec1_grf(1, 3);
    c->dx2 = brw_vec1_grf(1, 4);
@@ -303,8 +314,8 @@ static GLboolean calculate_masks( struct brw_sf_compile *c,
                                  GLushort *pc_linear)
 {
    GLboolean is_last_attr = (reg == c->nr_setup_regs - 1);
-   GLuint persp_mask;
-   GLuint linear_mask;
+   GLbitfield64 persp_mask;
+   GLbitfield64 linear_mask;
 
    if (c->key.do_flat_shading || c->key.linear_color)
       persp_mask = c->key.attrs & ~(FRAG_BIT_WPOS |
@@ -322,10 +333,10 @@ static GLboolean calculate_masks( struct brw_sf_compile *c,
    *pc_linear = 0;
    *pc = 0xf;
       
-   if (persp_mask & (1 << c->idx_to_attr[reg*2])) 
+   if (persp_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2]))
       *pc_persp = 0xf;
 
-   if (linear_mask & (1 << c->idx_to_attr[reg*2])) 
+   if (linear_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2]))
       *pc_linear = 0xf;
 
    /* Maybe only processs one attribute on the final round:
@@ -333,16 +344,43 @@ static GLboolean calculate_masks( struct brw_sf_compile *c,
    if (reg*2+1 < c->nr_setup_attrs) {
       *pc |= 0xf0;
 
-      if (persp_mask & (1 << c->idx_to_attr[reg*2+1])) 
+      if (persp_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2+1]))
         *pc_persp |= 0xf0;
 
-      if (linear_mask & (1 << c->idx_to_attr[reg*2+1])) 
+      if (linear_mask & BITFIELD64_BIT(c->idx_to_attr[reg*2+1]))
         *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 attr1, attr2;
+   uint16_t pc = 0;
+
+   attr1 = c->idx_to_attr[reg * 2];
+   if (attr1 >= VERT_RESULT_TEX0 && attr1 <= VERT_RESULT_TEX7) {
+      if (c->key.point_sprite_coord_replace & (1 << (attr1 - VERT_RESULT_TEX0)))
+        pc |= 0x0f;
+   }
+
+   if (reg * 2 + 1 < c->nr_setup_attrs) {
+       attr2 = c->idx_to_attr[reg * 2 + 1];
+       if (attr2 >= VERT_RESULT_TEX0 && attr2 <= VERT_RESULT_TEX7) {
+         if (c->key.point_sprite_coord_replace & (1 << (attr2 -
+                                                        VERT_RESULT_TEX0)))
+            pc |= 0xf0;
+       }
+   }
+
+   return pc;
+}
+
 
 
 void brw_emit_tri_setup( struct brw_sf_compile *c, GLboolean allocate)
@@ -518,22 +556,27 @@ 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;
+      GLushort pc, pc_persp, pc_linear, pc_coord_replace;
       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]);
-         }
+
+      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,
@@ -542,50 +585,51 @@ void brw_emit_point_sprite_setup( struct brw_sf_compile *c, GLboolean allocate)
                  BRW_MATH_DATA_SCALAR,
                  BRW_MATH_PRECISION_FULL);
 
-         if (c->key.SpriteOrigin == GL_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.SpriteOrigin == GL_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),
+                   0,  /* allocate */
+                   1,  /* used */
+                   4,  /* msg len */
+                   0,  /* response len */
+                   last,       /* eot */
+                   last,       /* writes complete */
+                   i*4,        /* urb destination offset */
+                   BRW_URB_SWIZZLE_TRANSPOSE);
    }
 }
 
@@ -678,7 +722,7 @@ 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_w(0));
+   jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
    {
       saveflag = p->flag_value;
       brw_push_insn_state(p); 
@@ -699,7 +743,7 @@ 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_w(0));
+   jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
    {
       saveflag = p->flag_value;
       brw_push_insn_state(p); 
@@ -712,7 +756,7 @@ 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_w(0));
+   jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
    {
       saveflag = p->flag_value;
       brw_push_insn_state(p);