i965/vec4: Make with_writemask() non-static.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_clip_tri.c
index 05959f66f863704b0f1f9dcde0c92f86e2052937..995a8909ccfacc1b1277232c866c7738bab48a5c 100644 (file)
@@ -50,7 +50,7 @@ static void release_tmps( struct brw_clip_compile *c )
 void brw_clip_tri_alloc_regs( struct brw_clip_compile *c, 
                              GLuint nr_verts )
 {
-   struct intel_context *intel = &c->func.brw->intel;
+   struct brw_context *brw = c->func.brw;
    GLuint i = 0,j;
 
    /* Register usage is static, precompute here:
@@ -119,7 +119,11 @@ void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
       i++;
    }
 
-   if (intel->needs_ff_sync) {
+   c->reg.vertex_src_mask = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
+   c->reg.clipdistance_offset = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_W);
+   i++;
+
+   if (brw->gen == 5) {
       c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
       i++;
    }
@@ -187,8 +191,8 @@ void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
 
    brw_IF(p, BRW_EXECUTE_1);
    {
-      brw_clip_copy_colors(c, 1, 0);
-      brw_clip_copy_colors(c, 2, 0);
+      brw_clip_copy_flatshaded_attributes(c, 1, 0);
+      brw_clip_copy_flatshaded_attributes(c, 2, 0);
    }
    brw_ELSE(p);
    {
@@ -200,25 +204,58 @@ void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
                 brw_imm_ud(_3DPRIM_TRIFAN));
         brw_IF(p, BRW_EXECUTE_1);
         {
-           brw_clip_copy_colors(c, 0, 1);
-           brw_clip_copy_colors(c, 2, 1);
+           brw_clip_copy_flatshaded_attributes(c, 0, 1);
+           brw_clip_copy_flatshaded_attributes(c, 2, 1);
         }
         brw_ELSE(p);
         {
-           brw_clip_copy_colors(c, 1, 0);
-           brw_clip_copy_colors(c, 2, 0);
+           brw_clip_copy_flatshaded_attributes(c, 1, 0);
+           brw_clip_copy_flatshaded_attributes(c, 2, 0);
         }
         brw_ENDIF(p);
       }
       else {
-         brw_clip_copy_colors(c, 0, 2);
-         brw_clip_copy_colors(c, 1, 2);
+         brw_clip_copy_flatshaded_attributes(c, 0, 2);
+         brw_clip_copy_flatshaded_attributes(c, 1, 2);
       }
    }
    brw_ENDIF(p);
 }
 
 
+/**
+ * Loads the clip distance for a vertex into `dst`, and ends with
+ * a comparison of it to zero with the condition `cond`.
+ *
+ * - If using a fixed plane, the distance is dot(hpos, plane).
+ * - If using a user clip plane, the distance is directly available in the vertex.
+ */
+static inline void
+load_clip_distance(struct brw_clip_compile *c, struct brw_indirect vtx,
+                struct brw_reg dst, GLuint hpos_offset, int cond)
+{
+   struct brw_compile *p = &c->func;
+
+   dst = vec4(dst);
+   brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+   brw_AND(p, vec1(brw_null_reg()), c->reg.vertex_src_mask, brw_imm_ud(1));
+   brw_IF(p, BRW_EXECUTE_1);
+   {
+      struct brw_indirect temp_ptr = brw_indirect(7, 0);
+      brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx), c->reg.clipdistance_offset);
+      brw_MOV(p, vec1(dst), deref_1f(temp_ptr, 0));
+   }
+   brw_ELSE(p);
+   {
+      brw_MOV(p, dst, deref_4f(vtx, hpos_offset));
+      brw_DP4(p, dst, dst, c->reg.plane_equation);
+   }
+   brw_ENDIF(p);
+
+   brw_set_conditionalmod(p, cond);
+   brw_CMP(p, brw_null_reg(), cond, vec1(dst), brw_imm_f(0.0f));
+}
+
 
 /* Use mesa's clipping algorithms, translated to GEN4 assembly.
  */
@@ -233,7 +270,10 @@ void brw_clip_tri( struct brw_clip_compile *c )
    struct brw_indirect outlist_ptr = brw_indirect(5, 0);
    struct brw_indirect freelist_ptr = brw_indirect(6, 0);
    GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS);
-   
+   GLint clipdist0_offset = c->key.nr_userclip
+      ? brw_varying_to_offset(&c->vue_map, VARYING_SLOT_CLIP_DIST0)
+      : 0;
+
    brw_MOV(p, get_addr_reg(vtxPrev),     brw_address(c->reg.vertex[2]) );
    brw_MOV(p, get_addr_reg(plane_ptr),   brw_clip_plane0_address(c));
    brw_MOV(p, get_addr_reg(inlist_ptr),  brw_address(c->reg.inlist));
@@ -241,6 +281,15 @@ void brw_clip_tri( struct brw_clip_compile *c )
 
    brw_MOV(p, get_addr_reg(freelist_ptr), brw_address(c->reg.vertex[3]) );
 
+   /* Set the initial vertex source mask: The first 6 planes are the bounds
+    * of the view volume; the next 8 planes are the user clipping planes.
+    */
+   brw_MOV(p, c->reg.vertex_src_mask, brw_imm_ud(0x3fc0));
+
+   /* Set the initial clipdistance offset to be 6 floats before gl_ClipDistance[0].
+    * We'll increment 6 times before we start hitting actual user clipping. */
+   brw_MOV(p, c->reg.clipdistance_offset, brw_imm_d(clipdist0_offset - 6*sizeof(float)));
+
    brw_DO(p, BRW_EXECUTE_1);
    {
       /* if (planemask & 1)
@@ -269,15 +318,13 @@ void brw_clip_tri( struct brw_clip_compile *c )
             */
            brw_MOV(p, get_addr_reg(vtx), deref_1uw(inlist_ptr, 0));
 
+            load_clip_distance(c, vtxPrev, c->reg.dpPrev, hpos_offset, BRW_CONDITIONAL_L);
            /* IS_NEGATIVE(prev) */
-           brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
-           brw_DP4(p, vec4(c->reg.dpPrev), deref_4f(vtxPrev, hpos_offset), c->reg.plane_equation);
            brw_IF(p, BRW_EXECUTE_1);
            {
+               load_clip_distance(c, vtx, c->reg.dp, hpos_offset, BRW_CONDITIONAL_GE);
               /* IS_POSITIVE(next)
                */
-              brw_set_conditionalmod(p, BRW_CONDITIONAL_GE);
-              brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, hpos_offset), c->reg.plane_equation);
               brw_IF(p, BRW_EXECUTE_1);
               {
 
@@ -316,10 +363,9 @@ void brw_clip_tri( struct brw_clip_compile *c )
               brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
               brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
 
+               load_clip_distance(c, vtx, c->reg.dp, hpos_offset, BRW_CONDITIONAL_L);
               /* IS_NEGATIVE(next)
                */
-              brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
-              brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, hpos_offset), c->reg.plane_equation);
               brw_IF(p, BRW_EXECUTE_1);
               {
                  /* Going out of bounds.  Avoid division by zero as we
@@ -392,6 +438,8 @@ void brw_clip_tri( struct brw_clip_compile *c )
        */
       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
       brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
+      brw_SHR(p, c->reg.vertex_src_mask, c->reg.vertex_src_mask, brw_imm_ud(1));
+      brw_ADD(p, c->reg.clipdistance_offset, c->reg.clipdistance_offset, brw_imm_w(sizeof(float)));
    }
    brw_WHILE(p);
 }
@@ -418,7 +466,7 @@ void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
       brw_MOV(p, get_addr_reg(vptr), brw_address(c->reg.inlist));
       brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
 
-      brw_clip_emit_vue(c, v0, 1, 0,
+      brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE,
                         ((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
                          | URB_WRITE_PRIM_START));
       
@@ -427,7 +475,7 @@ void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
 
       brw_DO(p, BRW_EXECUTE_1);
       {
-        brw_clip_emit_vue(c, v0, 1, 0,
+        brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE,
                            (_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT));
   
         brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
@@ -438,7 +486,7 @@ void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
       }
       brw_WHILE(p);
 
-      brw_clip_emit_vue(c, v0, 0, 1,
+      brw_clip_emit_vue(c, v0, BRW_URB_WRITE_EOT_COMPLETE,
                         ((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
                          | URB_WRITE_PRIM_END));
    }
@@ -605,7 +653,7 @@ void brw_emit_tri_clip( struct brw_clip_compile *c )
     * flatshading, need to apply the flatshade here because we don't
     * respect the PV when converting to trifan for emit:
     */
-   if (c->key.do_flat_shading) 
+   if (c->has_flat_shading)
       brw_clip_tri_flat_shade(c); 
       
    if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) ||