i965: Move clip program compilation to the compiler
authorJason Ekstrand <jason.ekstrand@intel.com>
Sat, 18 Mar 2017 19:02:45 +0000 (12:02 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Fri, 26 May 2017 14:58:01 +0000 (07:58 -0700)
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
19 files changed:
src/intel/Makefile.sources
src/intel/compiler/brw_clip.h [new file with mode: 0644]
src/intel/compiler/brw_clip_line.c [new file with mode: 0644]
src/intel/compiler/brw_clip_point.c [new file with mode: 0644]
src/intel/compiler/brw_clip_tri.c [new file with mode: 0644]
src/intel/compiler/brw_clip_unfilled.c [new file with mode: 0644]
src/intel/compiler/brw_clip_util.c [new file with mode: 0644]
src/intel/compiler/brw_compile_clip.c [new file with mode: 0644]
src/intel/compiler/brw_compiler.h
src/mesa/drivers/dri/i965/Makefile.sources
src/mesa/drivers/dri/i965/brw_clip.c
src/mesa/drivers/dri/i965/brw_clip.h [deleted file]
src/mesa/drivers/dri/i965/brw_clip_line.c [deleted file]
src/mesa/drivers/dri/i965/brw_clip_point.c [deleted file]
src/mesa/drivers/dri/i965/brw_clip_tri.c [deleted file]
src/mesa/drivers/dri/i965/brw_clip_unfilled.c [deleted file]
src/mesa/drivers/dri/i965/brw_clip_util.c [deleted file]
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_defines.h

index a9520f412eda01e8aa091ac55b8cf1e47961d56b..3136a1b250d540b133a45f271b05b17f9bad210c 100644 (file)
@@ -23,6 +23,13 @@ DECODER_FILES = \
 COMPILER_FILES = \
        compiler/brw_cfg.cpp \
        compiler/brw_cfg.h \
+       compiler/brw_clip.h \
+       compiler/brw_clip_line.c \
+       compiler/brw_clip_point.c \
+       compiler/brw_clip_tri.c \
+       compiler/brw_clip_unfilled.c \
+       compiler/brw_clip_util.c \
+       compiler/brw_compile_clip.c \
        compiler/brw_compile_sf.c \
        compiler/brw_compiler.c \
        compiler/brw_compiler.h \
diff --git a/src/intel/compiler/brw_clip.h b/src/intel/compiler/brw_clip.h
new file mode 100644 (file)
index 0000000..bdf7ee2
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics to
+ develop this 3D driver.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice (including the
+ next paragraph) shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keithw@vmware.com>
+  */
+
+#ifndef BRW_CLIP_H
+#define BRW_CLIP_H
+
+#include "brw_compiler.h"
+#include "brw_eu.h"
+
+/* Initial 3 verts, plus at most 6 additional verts from intersections
+ * with fixed planes, plus at most 8 additional verts from intersections
+ * with user clip planes
+ */
+#define MAX_VERTS (3+6+8)
+
+#define PRIM_MASK  (0x1f)
+
+struct brw_clip_compile {
+   struct brw_codegen func;
+   struct brw_clip_prog_key key;
+   struct brw_clip_prog_data prog_data;
+
+   struct {
+      struct brw_reg R0;
+      struct brw_reg vertex[MAX_VERTS];
+
+      struct brw_reg t;
+      struct brw_reg t0, t1;
+      struct brw_reg dp0, dp1;
+
+      struct brw_reg dpPrev;
+      struct brw_reg dp;
+      struct brw_reg loopcount;
+      struct brw_reg nr_verts;
+      struct brw_reg planemask;
+
+      struct brw_reg inlist;
+      struct brw_reg outlist;
+      struct brw_reg freelist;
+
+      struct brw_reg dir;
+      struct brw_reg tmp0, tmp1;
+      struct brw_reg offset;
+
+      struct brw_reg fixed_planes;
+      struct brw_reg plane_equation;
+
+      struct brw_reg ff_sync;
+
+      /* Bitmask indicating which coordinate attribute should be used for
+       * comparison to each clipping plane. A 0 indicates that VARYING_SLOT_POS
+       * should be used, because it's one of the fixed +/- x/y/z planes that
+       * constitute the bounds of the view volume. A 1 indicates that
+       * VARYING_SLOT_CLIP_VERTEX should be used (if available) since it's a user-
+       * defined clipping plane.
+       */
+      struct brw_reg vertex_src_mask;
+
+      /* Offset into the vertex of the current plane's clipdistance value */
+      struct brw_reg clipdistance_offset;
+   } reg;
+
+   /* Number of registers storing VUE data */
+   GLuint nr_regs;
+
+   GLuint first_tmp;
+   GLuint last_tmp;
+
+   bool need_direction;
+
+   struct brw_vue_map vue_map;
+};
+
+/**
+ * True if the given varying is one of the outputs of the vertex shader.
+ */
+static inline bool brw_clip_have_varying(struct brw_clip_compile *c,
+                                         GLuint varying)
+{
+   return (c->key.attrs & BITFIELD64_BIT(varying)) ? 1 : 0;
+}
+
+/* Points are only culled, so no need for a clip routine, however it
+ * works out easier to have a dummy one.
+ */
+void brw_emit_unfilled_clip( struct brw_clip_compile *c );
+void brw_emit_tri_clip( struct brw_clip_compile *c );
+void brw_emit_line_clip( struct brw_clip_compile *c );
+void brw_emit_point_clip( struct brw_clip_compile *c );
+
+/* brw_clip_tri.c, for use by the unfilled clip routine:
+ */
+void brw_clip_tri_init_vertices( struct brw_clip_compile *c );
+void brw_clip_tri_flat_shade( struct brw_clip_compile *c );
+void brw_clip_tri( struct brw_clip_compile *c );
+void brw_clip_tri_emit_polygon( struct brw_clip_compile *c );
+void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
+                             GLuint nr_verts );
+
+
+/* Utils:
+ */
+
+void brw_clip_interp_vertex( struct brw_clip_compile *c,
+                            struct brw_indirect dest_ptr,
+                            struct brw_indirect v0_ptr, /* from */
+                            struct brw_indirect v1_ptr, /* to */
+                            struct brw_reg t0,
+                            bool force_edgeflag );
+
+void brw_clip_init_planes( struct brw_clip_compile *c );
+
+void brw_clip_emit_vue(struct brw_clip_compile *c,
+                      struct brw_indirect vert,
+                       enum brw_urb_write_flags flags,
+                      GLuint header);
+
+void brw_clip_kill_thread(struct brw_clip_compile *c);
+
+struct brw_reg brw_clip_plane_stride( struct brw_clip_compile *c );
+struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c );
+
+void brw_clip_copy_flatshaded_attributes( struct brw_clip_compile *c,
+                                          GLuint to, GLuint from );
+
+void brw_clip_init_clipmask( struct brw_clip_compile *c );
+
+struct brw_reg get_tmp( struct brw_clip_compile *c );
+
+void brw_clip_project_position(struct brw_clip_compile *c,
+             struct brw_reg pos );
+void brw_clip_ff_sync(struct brw_clip_compile *c);
+void brw_clip_init_ff_sync(struct brw_clip_compile *c);
+
+#endif
diff --git a/src/intel/compiler/brw_clip_line.c b/src/intel/compiler/brw_clip_line.c
new file mode 100644 (file)
index 0000000..37f2266
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics to
+ develop this 3D driver.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice (including the
+ next paragraph) shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keithw@vmware.com>
+  */
+
+#include "main/macros.h"
+#include "main/enums.h"
+#include "program/program.h"
+
+#include "brw_clip.h"
+
+static void brw_clip_line_alloc_regs( struct brw_clip_compile *c )
+{
+   const struct gen_device_info *devinfo = c->func.devinfo;
+   GLuint i = 0,j;
+
+   /* Register usage is static, precompute here:
+    */
+   c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
+
+   if (c->key.nr_userclip) {
+      c->reg.fixed_planes = brw_vec4_grf(i, 0);
+      i += (6 + c->key.nr_userclip + 1) / 2;
+
+      c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2;
+   }
+   else
+      c->prog_data.curb_read_length = 0;
+
+
+   /* Payload vertices plus space for more generated vertices:
+    */
+   for (j = 0; j < 4; j++) {
+      c->reg.vertex[j] = brw_vec4_grf(i, 0);
+      i += c->nr_regs;
+   }
+
+   c->reg.t           = brw_vec1_grf(i, 0);
+   c->reg.t0          = brw_vec1_grf(i, 1);
+   c->reg.t1          = brw_vec1_grf(i, 2);
+   c->reg.planemask   = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
+   c->reg.plane_equation = brw_vec4_grf(i, 4);
+   i++;
+
+   c->reg.dp0         = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
+   c->reg.dp1         = brw_vec1_grf(i, 4);
+   i++;
+
+   if (!c->key.nr_userclip) {
+      c->reg.fixed_planes = brw_vec8_grf(i, 0);
+      i++;
+   }
+
+   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 (devinfo->gen == 5) {
+      c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
+      i++;
+   }
+
+   c->first_tmp = i;
+   c->last_tmp = i;
+
+   c->prog_data.urb_read_length = c->nr_regs; /* ? */
+   c->prog_data.total_grf = i;
+}
+
+
+/* Line clipping, more or less following the following algorithm:
+ *
+ *  for (p=0;p<MAX_PLANES;p++) {
+ *     if (clipmask & (1 << p)) {
+ *        GLfloat dp0 = DOTPROD( vtx0, plane[p] );
+ *        GLfloat dp1 = DOTPROD( vtx1, plane[p] );
+ *
+ *        if (dp1 < 0.0f) {
+ *           GLfloat t = dp1 / (dp1 - dp0);
+ *           if (t > t1) t1 = t;
+ *        } else {
+ *           GLfloat t = dp0 / (dp0 - dp1);
+ *           if (t > t0) t0 = t;
+ *        }
+ *
+ *        if (t0 + t1 >= 1.0)
+ *           return;
+ *     }
+ *  }
+ *
+ *  interp( ctx, newvtx0, vtx0, vtx1, t0 );
+ *  interp( ctx, newvtx1, vtx1, vtx0, t1 );
+ *
+ */
+static void clip_and_emit_line( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+   struct brw_indirect vtx0     = brw_indirect(0, 0);
+   struct brw_indirect vtx1      = brw_indirect(1, 0);
+   struct brw_indirect newvtx0   = brw_indirect(2, 0);
+   struct brw_indirect newvtx1   = brw_indirect(3, 0);
+   struct brw_indirect plane_ptr = brw_indirect(4, 0);
+   struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD);
+   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(vtx0),      brw_address(c->reg.vertex[0]));
+   brw_MOV(p, get_addr_reg(vtx1),      brw_address(c->reg.vertex[1]));
+   brw_MOV(p, get_addr_reg(newvtx0),   brw_address(c->reg.vertex[2]));
+   brw_MOV(p, get_addr_reg(newvtx1),   brw_address(c->reg.vertex[3]));
+   brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c));
+
+   /* Note: init t0, t1 together:
+    */
+   brw_MOV(p, vec2(c->reg.t0), brw_imm_f(0));
+
+   brw_clip_init_planes(c);
+   brw_clip_init_clipmask(c);
+
+   /* -ve rhw workaround */
+   if (p->devinfo->has_negative_rhw_bug) {
+      brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
+              brw_imm_ud(1<<20));
+      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
+      brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f));
+      brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+   }
+
+   /* 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)
+       */
+      brw_AND(p, v1_null_ud, c->reg.planemask, brw_imm_ud(1));
+      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
+
+      brw_IF(p, BRW_EXECUTE_1);
+      {
+         brw_AND(p, v1_null_ud, c->reg.vertex_src_mask, brw_imm_ud(1));
+         brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
+         brw_IF(p, BRW_EXECUTE_1);
+         {
+            /* user clip distance: just fetch the correct float from each vertex */
+            struct brw_indirect temp_ptr = brw_indirect(7, 0);
+            brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx0), c->reg.clipdistance_offset);
+            brw_MOV(p, c->reg.dp0, deref_1f(temp_ptr, 0));
+            brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx1), c->reg.clipdistance_offset);
+            brw_MOV(p, c->reg.dp1, deref_1f(temp_ptr, 0));
+         }
+         brw_ELSE(p);
+         {
+            /* fixed plane: fetch the hpos, dp4 against the plane. */
+            if (c->key.nr_userclip)
+               brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
+            else
+               brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
+
+            brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, hpos_offset), c->reg.plane_equation);
+            brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, hpos_offset), c->reg.plane_equation);
+         }
+         brw_ENDIF(p);
+
+         brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, vec1(c->reg.dp1), brw_imm_f(0.0f));
+
+         brw_IF(p, BRW_EXECUTE_1);
+         {
+             /*
+              * Both can be negative on GM965/G965 due to RHW workaround
+              * if so, this object should be rejected.
+              */
+             if (p->devinfo->has_negative_rhw_bug) {
+                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, c->reg.dp0, brw_imm_f(0.0));
+                 brw_IF(p, BRW_EXECUTE_1);
+                 {
+                     brw_clip_kill_thread(c);
+                 }
+                 brw_ENDIF(p);
+             }
+
+             brw_ADD(p, c->reg.t, c->reg.dp1, negate(c->reg.dp0));
+             brw_math_invert(p, c->reg.t, c->reg.t);
+             brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp1);
+
+             brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t1 );
+             brw_MOV(p, c->reg.t1, c->reg.t);
+             brw_inst_set_pred_control(p->devinfo, brw_last_inst,
+                                       BRW_PREDICATE_NORMAL);
+        }
+        brw_ELSE(p);
+        {
+             /* Coming back in.  We know that both cannot be negative
+              * because the line would have been culled in that case.
+              */
+
+             /* If both are positive, do nothing */
+             /* Only on GM965/G965 */
+             if (p->devinfo->has_negative_rhw_bug) {
+                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0));
+                 brw_IF(p, BRW_EXECUTE_1);
+             }
+
+             {
+                 brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1));
+                 brw_math_invert(p, c->reg.t, c->reg.t);
+                 brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0);
+
+                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 );
+                 brw_MOV(p, c->reg.t0, c->reg.t);
+                 brw_inst_set_pred_control(p->devinfo, brw_last_inst,
+                                           BRW_PREDICATE_NORMAL);
+             }
+
+             if (p->devinfo->has_negative_rhw_bug) {
+                 brw_ENDIF(p);
+             }
+         }
+        brw_ENDIF(p);
+      }
+      brw_ENDIF(p);
+
+      /* plane_ptr++;
+       */
+      brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
+
+      /* while (planemask>>=1) != 0
+       */
+      brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
+      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
+      brw_SHR(p, c->reg.vertex_src_mask, c->reg.vertex_src_mask, brw_imm_ud(1));
+      brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+      brw_ADD(p, c->reg.clipdistance_offset, c->reg.clipdistance_offset, brw_imm_w(sizeof(float)));
+      brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+   }
+   brw_WHILE(p);
+   brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+
+   brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1);
+   brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0));
+   brw_IF(p, BRW_EXECUTE_1);
+   {
+      brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, false);
+      brw_clip_interp_vertex(c, newvtx1, vtx1, vtx0, c->reg.t1, false);
+
+      brw_clip_emit_vue(c, newvtx0, BRW_URB_WRITE_ALLOCATE_COMPLETE,
+                        (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT)
+                        | URB_WRITE_PRIM_START);
+      brw_clip_emit_vue(c, newvtx1, BRW_URB_WRITE_EOT_COMPLETE,
+                        (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT)
+                        | URB_WRITE_PRIM_END);
+   }
+   brw_ENDIF(p);
+   brw_clip_kill_thread(c);
+}
+
+
+
+void brw_emit_line_clip( struct brw_clip_compile *c )
+{
+   brw_clip_line_alloc_regs(c);
+   brw_clip_init_ff_sync(c);
+
+   if (c->key.contains_flat_varying) {
+      if (c->key.pv_first)
+         brw_clip_copy_flatshaded_attributes(c, 1, 0);
+      else
+         brw_clip_copy_flatshaded_attributes(c, 0, 1);
+   }
+
+   clip_and_emit_line(c);
+}
diff --git a/src/intel/compiler/brw_clip_point.c b/src/intel/compiler/brw_clip_point.c
new file mode 100644 (file)
index 0000000..ac8f315
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics to
+ develop this 3D driver.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice (including the
+ next paragraph) shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keithw@vmware.com>
+  */
+
+#include "main/macros.h"
+#include "main/enums.h"
+#include "program/program.h"
+
+#include "brw_clip.h"
+
+
+/* Point clipping, nothing to do?
+ */
+void brw_emit_point_clip( struct brw_clip_compile *c )
+{
+   /* Send an empty message to kill the thread:
+    */
+   brw_clip_tri_alloc_regs(c, 0);
+   brw_clip_init_ff_sync(c);
+
+   brw_clip_kill_thread(c);
+}
diff --git a/src/intel/compiler/brw_clip_tri.c b/src/intel/compiler/brw_clip_tri.c
new file mode 100644 (file)
index 0000000..8ccf9e4
--- /dev/null
@@ -0,0 +1,662 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics to
+ develop this 3D driver.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice (including the
+ next paragraph) shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keithw@vmware.com>
+  */
+
+#include "main/macros.h"
+#include "main/enums.h"
+#include "program/program.h"
+
+#include "brw_clip.h"
+
+static void release_tmps( struct brw_clip_compile *c )
+{
+   c->last_tmp = c->first_tmp;
+}
+
+
+void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
+                             GLuint nr_verts )
+{
+   const struct gen_device_info *devinfo = c->func.devinfo;
+   GLuint i = 0,j;
+
+   /* Register usage is static, precompute here:
+    */
+   c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
+
+   if (c->key.nr_userclip) {
+      c->reg.fixed_planes = brw_vec4_grf(i, 0);
+      i += (6 + c->key.nr_userclip + 1) / 2;
+
+      c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2;
+   }
+   else
+      c->prog_data.curb_read_length = 0;
+
+
+   /* Payload vertices plus space for more generated vertices:
+    */
+   for (j = 0; j < nr_verts; j++) {
+      c->reg.vertex[j] = brw_vec4_grf(i, 0);
+      i += c->nr_regs;
+   }
+
+   if (c->vue_map.num_slots % 2) {
+      /* The VUE has an odd number of slots so the last register is only half
+       * used.  Fill the second half with zero.
+       */
+      for (j = 0; j < 3; j++) {
+        GLuint delta = brw_vue_slot_to_offset(c->vue_map.num_slots);
+
+        brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0));
+      }
+   }
+
+   c->reg.t          = brw_vec1_grf(i, 0);
+   c->reg.loopcount  = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_D);
+   c->reg.nr_verts   = retype(brw_vec1_grf(i, 2), BRW_REGISTER_TYPE_UD);
+   c->reg.planemask  = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
+   c->reg.plane_equation = brw_vec4_grf(i, 4);
+   i++;
+
+   c->reg.dpPrev     = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
+   c->reg.dp         = brw_vec1_grf(i, 4);
+   i++;
+
+   c->reg.inlist     = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
+   i++;
+
+   c->reg.outlist    = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
+   i++;
+
+   c->reg.freelist   = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
+   i++;
+
+   if (!c->key.nr_userclip) {
+      c->reg.fixed_planes = brw_vec8_grf(i, 0);
+      i++;
+   }
+
+   if (c->key.do_unfilled) {
+      c->reg.dir     = brw_vec4_grf(i, 0);
+      c->reg.offset  = brw_vec4_grf(i, 4);
+      i++;
+      c->reg.tmp0    = brw_vec4_grf(i, 0);
+      c->reg.tmp1    = brw_vec4_grf(i, 4);
+      i++;
+   }
+
+   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 (devinfo->gen == 5) {
+      c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
+      i++;
+   }
+
+   c->first_tmp = i;
+   c->last_tmp = i;
+
+   c->prog_data.urb_read_length = c->nr_regs; /* ? */
+   c->prog_data.total_grf = i;
+}
+
+
+
+void brw_clip_tri_init_vertices( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+   struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
+
+   /* Initial list of indices for incoming vertexes:
+    */
+   brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
+   brw_CMP(p,
+          vec1(brw_null_reg()),
+          BRW_CONDITIONAL_EQ,
+          tmp0,
+          brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE));
+
+   /* XXX: Is there an easier way to do this?  Need to reverse every
+    * second tristrip element:  Can ignore sometimes?
+    */
+   brw_IF(p, BRW_EXECUTE_1);
+   {
+      brw_MOV(p, get_element(c->reg.inlist, 0),  brw_address(c->reg.vertex[1]) );
+      brw_MOV(p, get_element(c->reg.inlist, 1),  brw_address(c->reg.vertex[0]) );
+      if (c->need_direction)
+        brw_MOV(p, c->reg.dir, brw_imm_f(-1));
+   }
+   brw_ELSE(p);
+   {
+      brw_MOV(p, get_element(c->reg.inlist, 0),  brw_address(c->reg.vertex[0]) );
+      brw_MOV(p, get_element(c->reg.inlist, 1),  brw_address(c->reg.vertex[1]) );
+      if (c->need_direction)
+        brw_MOV(p, c->reg.dir, brw_imm_f(1));
+   }
+   brw_ENDIF(p);
+
+   brw_MOV(p, get_element(c->reg.inlist, 2),  brw_address(c->reg.vertex[2]) );
+   brw_MOV(p, brw_vec8_grf(c->reg.outlist.nr, 0), brw_imm_f(0));
+   brw_MOV(p, c->reg.nr_verts, brw_imm_ud(3));
+}
+
+
+
+void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+   struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
+
+   brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
+   brw_CMP(p,
+          vec1(brw_null_reg()),
+          BRW_CONDITIONAL_EQ,
+          tmp0,
+          brw_imm_ud(_3DPRIM_POLYGON));
+
+   brw_IF(p, BRW_EXECUTE_1);
+   {
+      brw_clip_copy_flatshaded_attributes(c, 1, 0);
+      brw_clip_copy_flatshaded_attributes(c, 2, 0);
+   }
+   brw_ELSE(p);
+   {
+      if (c->key.pv_first) {
+        brw_CMP(p,
+                vec1(brw_null_reg()),
+                BRW_CONDITIONAL_EQ,
+                tmp0,
+                brw_imm_ud(_3DPRIM_TRIFAN));
+        brw_IF(p, BRW_EXECUTE_1);
+        {
+           brw_clip_copy_flatshaded_attributes(c, 0, 1);
+           brw_clip_copy_flatshaded_attributes(c, 2, 1);
+        }
+        brw_ELSE(p);
+        {
+           brw_clip_copy_flatshaded_attributes(c, 1, 0);
+           brw_clip_copy_flatshaded_attributes(c, 2, 0);
+        }
+        brw_ENDIF(p);
+      }
+      else {
+         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_codegen *p = &c->func;
+
+   dst = vec4(dst);
+   brw_AND(p, vec1(brw_null_reg()), c->reg.vertex_src_mask, brw_imm_ud(1));
+   brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
+   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_CMP(p, brw_null_reg(), cond, vec1(dst), brw_imm_f(0.0f));
+}
+
+
+/* Use mesa's clipping algorithms, translated to GEN4 assembly.
+ */
+void brw_clip_tri( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+   struct brw_indirect vtx = brw_indirect(0, 0);
+   struct brw_indirect vtxPrev = brw_indirect(1, 0);
+   struct brw_indirect vtxOut = brw_indirect(2, 0);
+   struct brw_indirect plane_ptr = brw_indirect(3, 0);
+   struct brw_indirect inlist_ptr = brw_indirect(4, 0);
+   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));
+   brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
+
+   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)
+       */
+      brw_AND(p, vec1(brw_null_reg()), c->reg.planemask, brw_imm_ud(1));
+      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
+
+      brw_IF(p, BRW_EXECUTE_1);
+      {
+        /* vtxOut = freelist_ptr++
+         */
+        brw_MOV(p, get_addr_reg(vtxOut),       get_addr_reg(freelist_ptr) );
+        brw_ADD(p, get_addr_reg(freelist_ptr), get_addr_reg(freelist_ptr), brw_imm_uw(c->nr_regs * REG_SIZE));
+
+        if (c->key.nr_userclip)
+           brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
+        else
+           brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
+
+        brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
+        brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0));
+
+        brw_DO(p, BRW_EXECUTE_1);
+        {
+           /* vtx = *input_ptr;
+            */
+           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);
+           /* (prev < 0.0f) */
+           brw_IF(p, BRW_EXECUTE_1);
+           {
+               load_clip_distance(c, vtx, c->reg.dp, hpos_offset, BRW_CONDITIONAL_GE);
+              /* IS_POSITIVE(next)
+               */
+              brw_IF(p, BRW_EXECUTE_1);
+              {
+
+                 /* Coming back in.
+                  */
+                 brw_ADD(p, c->reg.t, c->reg.dpPrev, negate(c->reg.dp));
+                 brw_math_invert(p, c->reg.t, c->reg.t);
+                 brw_MUL(p, c->reg.t, c->reg.t, c->reg.dpPrev);
+
+                 /* If (vtxOut == 0) vtxOut = vtxPrev
+                  */
+                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
+                  brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtxPrev));
+                  brw_inst_set_pred_control(p->devinfo, brw_last_inst,
+                                            BRW_PREDICATE_NORMAL);
+
+                 brw_clip_interp_vertex(c, vtxOut, vtxPrev, vtx, c->reg.t, false);
+
+                 /* *outlist_ptr++ = vtxOut;
+                  * nr_verts++;
+                  * vtxOut = 0;
+                  */
+                 brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
+                 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));
+                 brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
+              }
+              brw_ENDIF(p);
+
+           }
+           brw_ELSE(p);
+           {
+              /* *outlist_ptr++ = vtxPrev;
+               * nr_verts++;
+               */
+              brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxPrev));
+              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);
+              /* (next < 0.0f)
+               */
+              brw_IF(p, BRW_EXECUTE_1);
+              {
+                 /* Going out of bounds.  Avoid division by zero as we
+                  * know dp != dpPrev from DIFFERENT_SIGNS, above.
+                  */
+                 brw_ADD(p, c->reg.t, c->reg.dp, negate(c->reg.dpPrev));
+                 brw_math_invert(p, c->reg.t, c->reg.t);
+                 brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp);
+
+                 /* If (vtxOut == 0) vtxOut = vtx
+                  */
+                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
+                  brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtx));
+                  brw_inst_set_pred_control(p->devinfo, brw_last_inst,
+                                            BRW_PREDICATE_NORMAL);
+
+                 brw_clip_interp_vertex(c, vtxOut, vtx, vtxPrev, c->reg.t, true);
+
+                 /* *outlist_ptr++ = vtxOut;
+                  * nr_verts++;
+                  * vtxOut = 0;
+                  */
+                 brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
+                 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));
+                 brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
+              }
+              brw_ENDIF(p);
+           }
+           brw_ENDIF(p);
+
+           /* vtxPrev = vtx;
+            * inlist_ptr++;
+            */
+           brw_MOV(p, get_addr_reg(vtxPrev), get_addr_reg(vtx));
+           brw_ADD(p, get_addr_reg(inlist_ptr), get_addr_reg(inlist_ptr), brw_imm_uw(sizeof(short)));
+
+           /* while (--loopcount != 0)
+            */
+           brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
+            brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
+        }
+        brw_WHILE(p);
+         brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+
+        /* vtxPrev = *(outlist_ptr-1)  OR: outlist[nr_verts-1]
+         * inlist = outlist
+         * inlist_ptr = &inlist[0]
+         * outlist_ptr = &outlist[0]
+         */
+        brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_w(-2));
+        brw_MOV(p, get_addr_reg(vtxPrev), deref_1uw(outlist_ptr, 0));
+        brw_MOV(p, brw_vec8_grf(c->reg.inlist.nr, 0), brw_vec8_grf(c->reg.outlist.nr, 0));
+        brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist));
+        brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
+      }
+      brw_ENDIF(p);
+
+      /* plane_ptr++;
+       */
+      brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
+
+      /* nr_verts >= 3
+       */
+      brw_CMP(p,
+             vec1(brw_null_reg()),
+             BRW_CONDITIONAL_GE,
+             c->reg.nr_verts,
+             brw_imm_ud(3));
+      brw_set_default_predicate_control(p, BRW_PREDICATE_NORMAL);
+
+      /* && (planemask>>=1) != 0
+       */
+      brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
+      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
+      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);
+   brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
+}
+
+
+
+void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
+{
+   struct brw_codegen *p = &c->func;
+
+   /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
+    */
+   brw_ADD(p,
+          c->reg.loopcount,
+          c->reg.nr_verts,
+          brw_imm_d(-2));
+   brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_G);
+
+   brw_IF(p, BRW_EXECUTE_1);
+   {
+      struct brw_indirect v0 = brw_indirect(0, 0);
+      struct brw_indirect vptr = brw_indirect(1, 0);
+
+      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, BRW_URB_WRITE_ALLOCATE_COMPLETE,
+                        ((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
+                         | URB_WRITE_PRIM_START));
+
+      brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
+      brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
+
+      brw_DO(p, BRW_EXECUTE_1);
+      {
+        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));
+        brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
+
+        brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
+         brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
+      }
+      brw_WHILE(p);
+      brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+
+      brw_clip_emit_vue(c, v0, BRW_URB_WRITE_EOT_COMPLETE,
+                        ((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
+                         | URB_WRITE_PRIM_END));
+   }
+   brw_ENDIF(p);
+}
+
+static void do_clip_tri( struct brw_clip_compile *c )
+{
+   brw_clip_init_planes(c);
+
+   brw_clip_tri(c);
+}
+
+
+static void maybe_do_clip_tri( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+
+   brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
+   brw_IF(p, BRW_EXECUTE_1);
+   {
+      do_clip_tri(c);
+   }
+   brw_ENDIF(p);
+}
+
+static void brw_clip_test( struct brw_clip_compile *c )
+{
+    struct brw_reg t = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
+    struct brw_reg t1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
+    struct brw_reg t2 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
+    struct brw_reg t3 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
+
+    struct brw_reg v0 = get_tmp(c);
+    struct brw_reg v1 = get_tmp(c);
+    struct brw_reg v2 = get_tmp(c);
+
+    struct brw_indirect vt0 = brw_indirect(0, 0);
+    struct brw_indirect vt1 = brw_indirect(1, 0);
+    struct brw_indirect vt2 = brw_indirect(2, 0);
+
+    struct brw_codegen *p = &c->func;
+    struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
+
+    GLuint hpos_offset = brw_varying_to_offset(&c->vue_map,
+                                                   VARYING_SLOT_POS);
+
+    brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0]));
+    brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1]));
+    brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2]));
+    brw_MOV(p, v0, deref_4f(vt0, hpos_offset));
+    brw_MOV(p, v1, deref_4f(vt1, hpos_offset));
+    brw_MOV(p, v2, deref_4f(vt2, hpos_offset));
+    brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f));
+
+    /* test nearz, xmin, ymin plane */
+    /* clip.xyz < -clip.w */
+    brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, negate(get_element(v0, 3)));
+    brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, negate(get_element(v1, 3)));
+    brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, negate(get_element(v2, 3)));
+
+    /* All vertices are outside of a plane, rejected */
+    brw_AND(p, t, t1, t2);
+    brw_AND(p, t, t, t3);
+    brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
+    brw_OR(p, tmp0, tmp0, get_element(t, 2));
+    brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
+    brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
+    brw_IF(p, BRW_EXECUTE_1);
+    {
+        brw_clip_kill_thread(c);
+    }
+    brw_ENDIF(p);
+    brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
+
+    /* some vertices are inside a plane, some are outside,need to clip */
+    brw_XOR(p, t, t1, t2);
+    brw_XOR(p, t1, t2, t3);
+    brw_OR(p, t, t, t1);
+    brw_AND(p, t, t, brw_imm_ud(0x1));
+    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+            get_element(t, 0), brw_imm_ud(0));
+    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5)));
+    brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+            get_element(t, 1), brw_imm_ud(0));
+    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3)));
+    brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+            get_element(t, 2), brw_imm_ud(0));
+    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1)));
+    brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+
+    /* test farz, xmax, ymax plane */
+    /* clip.xyz > clip.w */
+    brw_CMP(p, t1, BRW_CONDITIONAL_G, v0, get_element(v0, 3));
+    brw_CMP(p, t2, BRW_CONDITIONAL_G, v1, get_element(v1, 3));
+    brw_CMP(p, t3, BRW_CONDITIONAL_G, v2, get_element(v2, 3));
+
+    /* All vertices are outside of a plane, rejected */
+    brw_AND(p, t, t1, t2);
+    brw_AND(p, t, t, t3);
+    brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
+    brw_OR(p, tmp0, tmp0, get_element(t, 2));
+    brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
+    brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
+    brw_IF(p, BRW_EXECUTE_1);
+    {
+        brw_clip_kill_thread(c);
+    }
+    brw_ENDIF(p);
+    brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
+
+    /* some vertices are inside a plane, some are outside,need to clip */
+    brw_XOR(p, t, t1, t2);
+    brw_XOR(p, t1, t2, t3);
+    brw_OR(p, t, t, t1);
+    brw_AND(p, t, t, brw_imm_ud(0x1));
+    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+            get_element(t, 0), brw_imm_ud(0));
+    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4)));
+    brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+            get_element(t, 1), brw_imm_ud(0));
+    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2)));
+    brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
+            get_element(t, 2), brw_imm_ud(0));
+    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0)));
+    brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+
+    release_tmps(c);
+}
+
+
+void brw_emit_tri_clip( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+   brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
+   brw_clip_tri_init_vertices(c);
+   brw_clip_init_clipmask(c);
+   brw_clip_init_ff_sync(c);
+
+   /* if -ve rhw workaround bit is set,
+      do cliptest */
+   if (p->devinfo->has_negative_rhw_bug) {
+      brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
+              brw_imm_ud(1<<20));
+      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
+      brw_IF(p, BRW_EXECUTE_1);
+      {
+         brw_clip_test(c);
+      }
+      brw_ENDIF(p);
+   }
+   /* Can't push into do_clip_tri because with polygon (or quad)
+    * flatshading, need to apply the flatshade here because we don't
+    * respect the PV when converting to trifan for emit:
+    */
+   if (c->key.contains_flat_varying)
+      brw_clip_tri_flat_shade(c);
+
+   if ((c->key.clip_mode == BRW_CLIP_MODE_NORMAL) ||
+       (c->key.clip_mode == BRW_CLIP_MODE_KERNEL_CLIP))
+      do_clip_tri(c);
+   else
+      maybe_do_clip_tri(c);
+
+   brw_clip_tri_emit_polygon(c);
+
+   /* Send an empty message to kill the thread:
+    */
+   brw_clip_kill_thread(c);
+}
diff --git a/src/intel/compiler/brw_clip_unfilled.c b/src/intel/compiler/brw_clip_unfilled.c
new file mode 100644 (file)
index 0000000..83f9447
--- /dev/null
@@ -0,0 +1,531 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics to
+ develop this 3D driver.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice (including the
+ next paragraph) shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keithw@vmware.com>
+  */
+
+#include "main/macros.h"
+#include "main/enums.h"
+#include "program/program.h"
+
+#include "brw_clip.h"
+
+
+/* This is performed against the original triangles, so no indirection
+ * required:
+BZZZT!
+ */
+static void compute_tri_direction( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+   struct brw_reg e = c->reg.tmp0;
+   struct brw_reg f = c->reg.tmp1;
+   GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS);
+   struct brw_reg v0 = byte_offset(c->reg.vertex[0], hpos_offset);
+   struct brw_reg v1 = byte_offset(c->reg.vertex[1], hpos_offset);
+   struct brw_reg v2 = byte_offset(c->reg.vertex[2], hpos_offset);
+
+
+   struct brw_reg v0n = get_tmp(c);
+   struct brw_reg v1n = get_tmp(c);
+   struct brw_reg v2n = get_tmp(c);
+
+   /* Convert to NDC.
+    * NOTE: We can't modify the original vertex coordinates,
+    * as it may impact further operations.
+    * So, we have to keep normalized coordinates in temp registers.
+    *
+    * TBD-KC
+    * Try to optimize unnecessary MOV's.
+    */
+   brw_MOV(p, v0n, v0);
+   brw_MOV(p, v1n, v1);
+   brw_MOV(p, v2n, v2);
+
+   brw_clip_project_position(c, v0n);
+   brw_clip_project_position(c, v1n);
+   brw_clip_project_position(c, v2n);
+
+   /* Calculate the vectors of two edges of the triangle:
+    */
+   brw_ADD(p, e, v0n, negate(v2n));
+   brw_ADD(p, f, v1n, negate(v2n));
+
+   /* Take their crossproduct:
+    */
+   brw_set_default_access_mode(p, BRW_ALIGN_16);
+   brw_MUL(p, vec4(brw_null_reg()), brw_swizzle(e, BRW_SWIZZLE_YZXW),
+           brw_swizzle(f, BRW_SWIZZLE_ZXYW));
+   brw_MAC(p, vec4(e),  negate(brw_swizzle(e, BRW_SWIZZLE_ZXYW)),
+           brw_swizzle(f, BRW_SWIZZLE_YZXW));
+   brw_set_default_access_mode(p, BRW_ALIGN_1);
+
+   brw_MUL(p, c->reg.dir, c->reg.dir, vec4(e));
+}
+
+
+static void cull_direction( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+   GLuint conditional;
+
+   assert (!(c->key.fill_ccw == BRW_CLIP_FILL_MODE_CULL &&
+            c->key.fill_cw == BRW_CLIP_FILL_MODE_CULL));
+
+   if (c->key.fill_ccw == BRW_CLIP_FILL_MODE_CULL)
+      conditional = BRW_CONDITIONAL_GE;
+   else
+      conditional = BRW_CONDITIONAL_L;
+
+   brw_CMP(p,
+          vec1(brw_null_reg()),
+          conditional,
+          get_element(c->reg.dir, 2),
+          brw_imm_f(0));
+
+   brw_IF(p, BRW_EXECUTE_1);
+   {
+      brw_clip_kill_thread(c);
+   }
+   brw_ENDIF(p);
+}
+
+
+
+static void copy_bfc( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+   GLuint conditional;
+
+   /* Do we have any colors to copy?
+    */
+   if (!(brw_clip_have_varying(c, VARYING_SLOT_COL0) &&
+         brw_clip_have_varying(c, VARYING_SLOT_BFC0)) &&
+       !(brw_clip_have_varying(c, VARYING_SLOT_COL1) &&
+         brw_clip_have_varying(c, VARYING_SLOT_BFC1)))
+      return;
+
+   /* In some weird degenerate cases we can end up testing the
+    * direction twice, once for culling and once for bfc copying.  Oh
+    * well, that's what you get for setting weird GL state.
+    */
+   if (c->key.copy_bfc_ccw)
+      conditional = BRW_CONDITIONAL_GE;
+   else
+      conditional = BRW_CONDITIONAL_L;
+
+   brw_CMP(p,
+          vec1(brw_null_reg()),
+          conditional,
+          get_element(c->reg.dir, 2),
+          brw_imm_f(0));
+
+   brw_IF(p, BRW_EXECUTE_1);
+   {
+      GLuint i;
+
+      for (i = 0; i < 3; i++) {
+        if (brw_clip_have_varying(c, VARYING_SLOT_COL0) &&
+             brw_clip_have_varying(c, VARYING_SLOT_BFC0))
+           brw_MOV(p,
+                   byte_offset(c->reg.vertex[i],
+                                brw_varying_to_offset(&c->vue_map,
+                                                      VARYING_SLOT_COL0)),
+                   byte_offset(c->reg.vertex[i],
+                                brw_varying_to_offset(&c->vue_map,
+                                                      VARYING_SLOT_BFC0)));
+
+        if (brw_clip_have_varying(c, VARYING_SLOT_COL1) &&
+             brw_clip_have_varying(c, VARYING_SLOT_BFC1))
+           brw_MOV(p,
+                   byte_offset(c->reg.vertex[i],
+                                brw_varying_to_offset(&c->vue_map,
+                                                      VARYING_SLOT_COL1)),
+                   byte_offset(c->reg.vertex[i],
+                                brw_varying_to_offset(&c->vue_map,
+                                                      VARYING_SLOT_BFC1)));
+      }
+   }
+   brw_ENDIF(p);
+}
+
+
+
+
+/*
+  GLfloat iz   = 1.0 / dir.z;
+  GLfloat ac   = dir.x * iz;
+  GLfloat bc   = dir.y * iz;
+  offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
+  offset += MAX2( abs(ac), abs(bc) ) * ctx->Polygon.OffsetFactor;
+  if (ctx->Polygon.OffsetClamp && isfinite(ctx->Polygon.OffsetClamp)) {
+    if (ctx->Polygon.OffsetClamp < 0)
+      offset = MAX2( offset, ctx->Polygon.OffsetClamp );
+    else
+      offset = MIN2( offset, ctx->Polygon.OffsetClamp );
+  }
+  offset *= MRD;
+*/
+static void compute_offset( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+   struct brw_reg off = c->reg.offset;
+   struct brw_reg dir = c->reg.dir;
+
+   brw_math_invert(p, get_element(off, 2), get_element(dir, 2));
+   brw_MUL(p, vec2(off), vec2(dir), get_element(off, 2));
+
+   brw_CMP(p,
+          vec1(brw_null_reg()),
+          BRW_CONDITIONAL_GE,
+          brw_abs(get_element(off, 0)),
+          brw_abs(get_element(off, 1)));
+
+   brw_SEL(p, vec1(off),
+           brw_abs(get_element(off, 0)), brw_abs(get_element(off, 1)));
+   brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+
+   brw_MUL(p, vec1(off), vec1(off), brw_imm_f(c->key.offset_factor));
+   brw_ADD(p, vec1(off), vec1(off), brw_imm_f(c->key.offset_units));
+   if (c->key.offset_clamp && isfinite(c->key.offset_clamp)) {
+      brw_CMP(p,
+              vec1(brw_null_reg()),
+              c->key.offset_clamp < 0 ? BRW_CONDITIONAL_GE : BRW_CONDITIONAL_L,
+              vec1(off),
+              brw_imm_f(c->key.offset_clamp));
+      brw_SEL(p, vec1(off), vec1(off), brw_imm_f(c->key.offset_clamp));
+   }
+}
+
+
+static void merge_edgeflags( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+   struct brw_reg tmp0 = get_element_ud(c->reg.tmp0, 0);
+
+   brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
+   brw_CMP(p,
+          vec1(brw_null_reg()),
+          BRW_CONDITIONAL_EQ,
+          tmp0,
+          brw_imm_ud(_3DPRIM_POLYGON));
+
+   /* Get away with using reg.vertex because we know that this is not
+    * a _3DPRIM_TRISTRIP_REVERSE:
+    */
+   brw_IF(p, BRW_EXECUTE_1);
+   {
+      brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<8));
+      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_EQ);
+      brw_MOV(p, byte_offset(c->reg.vertex[0],
+                             brw_varying_to_offset(&c->vue_map,
+                                                   VARYING_SLOT_EDGE)),
+              brw_imm_f(0));
+      brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+
+      brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<9));
+      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_EQ);
+      brw_MOV(p, byte_offset(c->reg.vertex[2],
+                             brw_varying_to_offset(&c->vue_map,
+                                                   VARYING_SLOT_EDGE)),
+              brw_imm_f(0));
+      brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+   }
+   brw_ENDIF(p);
+}
+
+
+
+static void apply_one_offset( struct brw_clip_compile *c,
+                         struct brw_indirect vert )
+{
+   struct brw_codegen *p = &c->func;
+   GLuint ndc_offset = brw_varying_to_offset(&c->vue_map,
+                                             BRW_VARYING_SLOT_NDC);
+   struct brw_reg z = deref_1f(vert, ndc_offset +
+                              2 * type_sz(BRW_REGISTER_TYPE_F));
+
+   brw_ADD(p, z, z, vec1(c->reg.offset));
+}
+
+
+
+/***********************************************************************
+ * Output clipped polygon as an unfilled primitive:
+ */
+static void emit_lines(struct brw_clip_compile *c,
+                      bool do_offset)
+{
+   struct brw_codegen *p = &c->func;
+   struct brw_indirect v0 = brw_indirect(0, 0);
+   struct brw_indirect v1 = brw_indirect(1, 0);
+   struct brw_indirect v0ptr = brw_indirect(2, 0);
+   struct brw_indirect v1ptr = brw_indirect(3, 0);
+
+   /* Need a separate loop for offset:
+    */
+   if (do_offset) {
+      brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
+      brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist));
+
+      brw_DO(p, BRW_EXECUTE_1);
+      {
+        brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
+        brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2));
+
+        apply_one_offset(c, v0);
+
+        brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
+         brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_G);
+      }
+      brw_WHILE(p);
+      brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+   }
+
+   /* v1ptr = &inlist[nr_verts]
+    * *v1ptr = v0
+    */
+   brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
+   brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist));
+   brw_ADD(p, get_addr_reg(v1ptr), get_addr_reg(v0ptr), retype(c->reg.nr_verts, BRW_REGISTER_TYPE_UW));
+   brw_ADD(p, get_addr_reg(v1ptr), get_addr_reg(v1ptr), retype(c->reg.nr_verts, BRW_REGISTER_TYPE_UW));
+   brw_MOV(p, deref_1uw(v1ptr, 0), deref_1uw(v0ptr, 0));
+
+   brw_DO(p, BRW_EXECUTE_1);
+   {
+      brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
+      brw_MOV(p, get_addr_reg(v1), deref_1uw(v0ptr, 2));
+      brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2));
+
+      /* draw edge if edgeflag != 0 */
+      brw_CMP(p,
+             vec1(brw_null_reg()), BRW_CONDITIONAL_NZ,
+             deref_1f(v0, brw_varying_to_offset(&c->vue_map,
+                                                 VARYING_SLOT_EDGE)),
+             brw_imm_f(0));
+      brw_IF(p, BRW_EXECUTE_1);
+      {
+        brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE,
+                           (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT)
+                           | URB_WRITE_PRIM_START);
+        brw_clip_emit_vue(c, v1, BRW_URB_WRITE_ALLOCATE_COMPLETE,
+                           (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT)
+                           | URB_WRITE_PRIM_END);
+      }
+      brw_ENDIF(p);
+
+      brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
+      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
+   }
+   brw_WHILE(p);
+   brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+}
+
+
+
+static void emit_points(struct brw_clip_compile *c,
+                       bool do_offset )
+{
+   struct brw_codegen *p = &c->func;
+
+   struct brw_indirect v0 = brw_indirect(0, 0);
+   struct brw_indirect v0ptr = brw_indirect(2, 0);
+
+   brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
+   brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist));
+
+   brw_DO(p, BRW_EXECUTE_1);
+   {
+      brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
+      brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2));
+
+      /* draw if edgeflag != 0
+       */
+      brw_CMP(p,
+             vec1(brw_null_reg()), BRW_CONDITIONAL_NZ,
+             deref_1f(v0, brw_varying_to_offset(&c->vue_map,
+                                                 VARYING_SLOT_EDGE)),
+             brw_imm_f(0));
+      brw_IF(p, BRW_EXECUTE_1);
+      {
+        if (do_offset)
+           apply_one_offset(c, v0);
+
+        brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE,
+                           (_3DPRIM_POINTLIST << URB_WRITE_PRIM_TYPE_SHIFT)
+                           | URB_WRITE_PRIM_START | URB_WRITE_PRIM_END);
+      }
+      brw_ENDIF(p);
+
+      brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
+      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
+   }
+   brw_WHILE(p);
+   brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
+}
+
+
+
+
+
+
+
+static void emit_primitives( struct brw_clip_compile *c,
+                            GLuint mode,
+                            bool do_offset )
+{
+   switch (mode) {
+   case BRW_CLIP_FILL_MODE_FILL:
+      brw_clip_tri_emit_polygon(c);
+      break;
+
+   case BRW_CLIP_FILL_MODE_LINE:
+      emit_lines(c, do_offset);
+      break;
+
+   case BRW_CLIP_FILL_MODE_POINT:
+      emit_points(c, do_offset);
+      break;
+
+   case BRW_CLIP_FILL_MODE_CULL:
+      unreachable("not reached");
+   }
+}
+
+
+
+static void emit_unfilled_primitives( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+
+   /* Direction culling has already been done.
+    */
+   if (c->key.fill_ccw != c->key.fill_cw &&
+       c->key.fill_ccw != BRW_CLIP_FILL_MODE_CULL &&
+       c->key.fill_cw != BRW_CLIP_FILL_MODE_CULL)
+   {
+      brw_CMP(p,
+             vec1(brw_null_reg()),
+             BRW_CONDITIONAL_GE,
+             get_element(c->reg.dir, 2),
+             brw_imm_f(0));
+
+      brw_IF(p, BRW_EXECUTE_1);
+      {
+        emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw);
+      }
+      brw_ELSE(p);
+      {
+        emit_primitives(c, c->key.fill_cw, c->key.offset_cw);
+      }
+      brw_ENDIF(p);
+   }
+   else if (c->key.fill_cw != BRW_CLIP_FILL_MODE_CULL) {
+      emit_primitives(c, c->key.fill_cw, c->key.offset_cw);
+   }
+   else if (c->key.fill_ccw != BRW_CLIP_FILL_MODE_CULL) {
+      emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw);
+   }
+}
+
+
+
+
+static void check_nr_verts( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+
+   brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.nr_verts, brw_imm_d(3));
+   brw_IF(p, BRW_EXECUTE_1);
+   {
+      brw_clip_kill_thread(c);
+   }
+   brw_ENDIF(p);
+}
+
+
+void brw_emit_unfilled_clip( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+
+   c->need_direction = ((c->key.offset_ccw || c->key.offset_cw) ||
+                       (c->key.fill_ccw != c->key.fill_cw) ||
+                       c->key.fill_ccw == BRW_CLIP_FILL_MODE_CULL ||
+                       c->key.fill_cw == BRW_CLIP_FILL_MODE_CULL ||
+                       c->key.copy_bfc_cw ||
+                       c->key.copy_bfc_ccw);
+
+   brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
+   brw_clip_tri_init_vertices(c);
+   brw_clip_init_ff_sync(c);
+
+   assert(brw_clip_have_varying(c, VARYING_SLOT_EDGE));
+
+   if (c->key.fill_ccw == BRW_CLIP_FILL_MODE_CULL &&
+       c->key.fill_cw == BRW_CLIP_FILL_MODE_CULL) {
+      brw_clip_kill_thread(c);
+      return;
+   }
+
+   merge_edgeflags(c);
+
+   /* Need to use the inlist indirection here:
+    */
+   if (c->need_direction)
+      compute_tri_direction(c);
+
+   if (c->key.fill_ccw == BRW_CLIP_FILL_MODE_CULL ||
+       c->key.fill_cw == BRW_CLIP_FILL_MODE_CULL)
+      cull_direction(c);
+
+   if (c->key.offset_ccw ||
+       c->key.offset_cw)
+      compute_offset(c);
+
+   if (c->key.copy_bfc_ccw ||
+       c->key.copy_bfc_cw)
+      copy_bfc(c);
+
+   /* Need to do this whether we clip or not:
+    */
+   if (c->key.contains_flat_varying)
+      brw_clip_tri_flat_shade(c);
+
+   brw_clip_init_clipmask(c);
+   brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
+   brw_IF(p, BRW_EXECUTE_1);
+   {
+      brw_clip_init_planes(c);
+      brw_clip_tri(c);
+      check_nr_verts(c);
+   }
+   brw_ENDIF(p);
+
+   emit_unfilled_primitives(c);
+   brw_clip_kill_thread(c);
+}
diff --git a/src/intel/compiler/brw_clip_util.c b/src/intel/compiler/brw_clip_util.c
new file mode 100644 (file)
index 0000000..e01fbc6
--- /dev/null
@@ -0,0 +1,469 @@
+/*
+ Copyright (C) Intel Corp.  2006.  All Rights Reserved.
+ Intel funded Tungsten Graphics to
+ develop this 3D driver.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice (including the
+ next paragraph) shall be included in all copies or substantial
+ portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ **********************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keithw@vmware.com>
+  */
+
+
+#include "main/macros.h"
+#include "main/enums.h"
+#include "program/program.h"
+
+#include "brw_clip.h"
+
+
+struct brw_reg get_tmp( struct brw_clip_compile *c )
+{
+   struct brw_reg tmp = brw_vec4_grf(c->last_tmp, 0);
+
+   if (++c->last_tmp > c->prog_data.total_grf)
+      c->prog_data.total_grf = c->last_tmp;
+
+   return tmp;
+}
+
+static void release_tmp( struct brw_clip_compile *c, struct brw_reg tmp )
+{
+   if (tmp.nr == c->last_tmp-1)
+      c->last_tmp--;
+}
+
+
+static struct brw_reg make_plane_ud(GLuint x, GLuint y, GLuint z, GLuint w)
+{
+   return brw_imm_ud((w<<24) | (z<<16) | (y<<8) | x);
+}
+
+
+void brw_clip_init_planes( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+
+   if (!c->key.nr_userclip) {
+      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 0), make_plane_ud( 0,    0, 0xff, 1));
+      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 1), make_plane_ud( 0,    0,    1, 1));
+      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 2), make_plane_ud( 0, 0xff,    0, 1));
+      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 3), make_plane_ud( 0,    1,    0, 1));
+      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 4), make_plane_ud(0xff,  0,    0, 1));
+      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 5), make_plane_ud( 1,    0,    0, 1));
+   }
+}
+
+
+
+#define W 3
+
+/* Project 'pos' to screen space (or back again), overwrite with results:
+ */
+void brw_clip_project_position(struct brw_clip_compile *c, struct brw_reg pos )
+{
+   struct brw_codegen *p = &c->func;
+
+   /* calc rhw
+    */
+   brw_math_invert(p, get_element(pos, W), get_element(pos, W));
+
+   /* value.xyz *= value.rhw
+    */
+   brw_set_default_access_mode(p, BRW_ALIGN_16);
+   brw_MUL(p, brw_writemask(pos, WRITEMASK_XYZ), pos,
+           brw_swizzle(pos, BRW_SWIZZLE_WWWW));
+   brw_set_default_access_mode(p, BRW_ALIGN_1);
+}
+
+
+static void brw_clip_project_vertex( struct brw_clip_compile *c,
+                                    struct brw_indirect vert_addr )
+{
+   struct brw_codegen *p = &c->func;
+   struct brw_reg tmp = get_tmp(c);
+   GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS);
+   GLuint ndc_offset = brw_varying_to_offset(&c->vue_map,
+                                             BRW_VARYING_SLOT_NDC);
+
+   /* Fixup position.  Extract from the original vertex and re-project
+    * to screen space:
+    */
+   brw_MOV(p, tmp, deref_4f(vert_addr, hpos_offset));
+   brw_clip_project_position(c, tmp);
+   brw_MOV(p, deref_4f(vert_addr, ndc_offset), tmp);
+
+   release_tmp(c, tmp);
+}
+
+
+
+
+/* Interpolate between two vertices and put the result into a0.0.
+ * Increment a0.0 accordingly.
+ *
+ * Beware that dest_ptr can be equal to v0_ptr!
+ */
+void brw_clip_interp_vertex( struct brw_clip_compile *c,
+                            struct brw_indirect dest_ptr,
+                            struct brw_indirect v0_ptr, /* from */
+                            struct brw_indirect v1_ptr, /* to */
+                            struct brw_reg t0,
+                            bool force_edgeflag)
+{
+   struct brw_codegen *p = &c->func;
+   struct brw_reg t_nopersp, v0_ndc_copy;
+   GLuint slot;
+
+   /* Just copy the vertex header:
+    */
+   /*
+    * After CLIP stage, only first 256 bits of the VUE are read
+    * back on Ironlake, so needn't change it
+    */
+   brw_copy_indirect_to_indirect(p, dest_ptr, v0_ptr, 1);
+
+
+   /* First handle the 3D and NDC interpolation, in case we
+    * need noperspective interpolation. Doing it early has no
+    * performance impact in any case.
+    */
+
+   /* Take a copy of the v0 NDC coordinates, in case dest == v0. */
+   if (c->key.contains_noperspective_varying) {
+      GLuint offset = brw_varying_to_offset(&c->vue_map,
+                                                 BRW_VARYING_SLOT_NDC);
+      v0_ndc_copy = get_tmp(c);
+      brw_MOV(p, v0_ndc_copy, deref_4f(v0_ptr, offset));
+   }
+
+   /* Compute the new 3D position
+    *
+    * dest_hpos = v0_hpos * (1 - t0) + v1_hpos * t0
+    */
+   {
+      GLuint delta = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS);
+      struct brw_reg tmp = get_tmp(c);
+      brw_MUL(p, vec4(brw_null_reg()), deref_4f(v1_ptr, delta), t0);
+      brw_MAC(p, tmp, negate(deref_4f(v0_ptr, delta)), t0);
+      brw_ADD(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta), tmp);
+      release_tmp(c, tmp);
+   }
+
+   /* Recreate the projected (NDC) coordinate in the new vertex header */
+   brw_clip_project_vertex(c, dest_ptr);
+
+   /* If we have noperspective attributes,
+    * we need to compute the screen-space t
+    */
+   if (c->key.contains_noperspective_varying) {
+      GLuint delta = brw_varying_to_offset(&c->vue_map,
+                                                BRW_VARYING_SLOT_NDC);
+      struct brw_reg tmp = get_tmp(c);
+      t_nopersp = get_tmp(c);
+
+      /* t_nopersp = vec4(v1.xy, dest.xy) */
+      brw_MOV(p, t_nopersp, deref_4f(v1_ptr, delta));
+      brw_MOV(p, tmp, deref_4f(dest_ptr, delta));
+      brw_set_default_access_mode(p, BRW_ALIGN_16);
+      brw_MOV(p,
+              brw_writemask(t_nopersp, WRITEMASK_ZW),
+              brw_swizzle(tmp, BRW_SWIZZLE_XYXY));
+
+      /* t_nopersp = vec4(v1.xy, dest.xy) - v0.xyxy */
+      brw_ADD(p, t_nopersp, t_nopersp,
+              negate(brw_swizzle(v0_ndc_copy, BRW_SWIZZLE_XYXY)));
+
+      /* Add the absolute values of the X and Y deltas so that if
+       * the points aren't in the same place on the screen we get
+       * nonzero values to divide.
+       *
+       * After that, we have vert1 - vert0 in t_nopersp.x and
+       * vertnew - vert0 in t_nopersp.y
+       *
+       * t_nopersp = vec2(|v1.x  -v0.x| + |v1.y  -v0.y|,
+       *                  |dest.x-v0.x| + |dest.y-v0.y|)
+       */
+      brw_ADD(p,
+              brw_writemask(t_nopersp, WRITEMASK_XY),
+              brw_abs(brw_swizzle(t_nopersp, BRW_SWIZZLE_XZXZ)),
+              brw_abs(brw_swizzle(t_nopersp, BRW_SWIZZLE_YWYW)));
+      brw_set_default_access_mode(p, BRW_ALIGN_1);
+
+      /* If the points are in the same place, just substitute a
+       * value to avoid divide-by-zero
+       */
+      brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ,
+              vec1(t_nopersp),
+              brw_imm_f(0));
+      brw_IF(p, BRW_EXECUTE_1);
+      brw_MOV(p, t_nopersp, brw_imm_vf4(brw_float_to_vf(1.0),
+                                        brw_float_to_vf(0.0),
+                                        brw_float_to_vf(0.0),
+                                        brw_float_to_vf(0.0)));
+      brw_ENDIF(p);
+
+      /* Now compute t_nopersp = t_nopersp.y/t_nopersp.x and broadcast it. */
+      brw_math_invert(p, get_element(t_nopersp, 0), get_element(t_nopersp, 0));
+      brw_MUL(p, vec1(t_nopersp), vec1(t_nopersp),
+            vec1(suboffset(t_nopersp, 1)));
+      brw_set_default_access_mode(p, BRW_ALIGN_16);
+      brw_MOV(p, t_nopersp, brw_swizzle(t_nopersp, BRW_SWIZZLE_XXXX));
+      brw_set_default_access_mode(p, BRW_ALIGN_1);
+
+      release_tmp(c, tmp);
+      release_tmp(c, v0_ndc_copy);
+   }
+
+   /* Now we can iterate over each attribute
+    * (could be done in pairs?)
+    */
+   for (slot = 0; slot < c->vue_map.num_slots; slot++) {
+      int varying = c->vue_map.slot_to_varying[slot];
+      GLuint delta = brw_vue_slot_to_offset(slot);
+
+      /* HPOS, NDC already handled above */
+      if (varying == VARYING_SLOT_POS || varying == BRW_VARYING_SLOT_NDC)
+         continue;
+
+
+      if (varying == VARYING_SLOT_EDGE) {
+        if (force_edgeflag)
+           brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(1));
+        else
+           brw_MOV(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta));
+      } else if (varying == VARYING_SLOT_PSIZ) {
+         /* PSIZ doesn't need interpolation because it isn't used by the
+          * fragment shader.
+          */
+      } else if (varying < VARYING_SLOT_MAX) {
+        /* This is a true vertex result (and not a special value for the VUE
+         * header), so interpolate:
+         *
+         *        New = attr0 + t*attr1 - t*attr0
+          *
+          * Unless the attribute is flat shaded -- in which case just copy
+          * from one of the sources (doesn't matter which; already copied from pv)
+         */
+         GLuint interp = c->key.interp_mode[slot];
+
+         if (interp != INTERP_MODE_FLAT) {
+            struct brw_reg tmp = get_tmp(c);
+            struct brw_reg t =
+               interp == INTERP_MODE_NOPERSPECTIVE ? t_nopersp : t0;
+
+            brw_MUL(p,
+                  vec4(brw_null_reg()),
+                  deref_4f(v1_ptr, delta),
+                  t);
+
+            brw_MAC(p,
+                  tmp,
+                  negate(deref_4f(v0_ptr, delta)),
+                  t);
+
+            brw_ADD(p,
+                  deref_4f(dest_ptr, delta),
+                  deref_4f(v0_ptr, delta),
+                  tmp);
+
+            release_tmp(c, tmp);
+         }
+         else {
+            brw_MOV(p,
+                  deref_4f(dest_ptr, delta),
+                  deref_4f(v0_ptr, delta));
+         }
+      }
+   }
+
+   if (c->vue_map.num_slots % 2) {
+      GLuint delta = brw_vue_slot_to_offset(c->vue_map.num_slots);
+
+      brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0));
+   }
+
+   if (c->key.contains_noperspective_varying)
+      release_tmp(c, t_nopersp);
+}
+
+void brw_clip_emit_vue(struct brw_clip_compile *c,
+                      struct brw_indirect vert,
+                       enum brw_urb_write_flags flags,
+                      GLuint header)
+{
+   struct brw_codegen *p = &c->func;
+   bool allocate = flags & BRW_URB_WRITE_ALLOCATE;
+
+   brw_clip_ff_sync(c);
+
+   /* Any URB entry that is allocated must subsequently be used or discarded,
+    * so it doesn't make sense to mark EOT and ALLOCATE at the same time.
+    */
+   assert(!(allocate && (flags & BRW_URB_WRITE_EOT)));
+
+   /* Copy the vertex from vertn into m1..mN+1:
+    */
+   brw_copy_from_indirect(p, brw_message_reg(1), vert, c->nr_regs);
+
+   /* Overwrite PrimType and PrimStart in the message header, for
+    * each vertex in turn:
+    */
+   brw_MOV(p, get_element_ud(c->reg.R0, 2), brw_imm_ud(header));
+
+
+   /* Send each vertex as a separate write to the urb.  This
+    * is different to the concept in brw_sf_emit.c, where
+    * subsequent writes are used to build up a single urb
+    * entry.  Each of these writes instantiates a separate
+    * urb entry - (I think... what about 'allocate'?)
+    */
+   brw_urb_WRITE(p,
+                allocate ? c->reg.R0 : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
+                0,
+                c->reg.R0,
+                 flags,
+                c->nr_regs + 1, /* msg length */
+                allocate ? 1 : 0, /* response_length */
+                0,             /* urb offset */
+                BRW_URB_SWIZZLE_NONE);
+}
+
+
+
+void brw_clip_kill_thread(struct brw_clip_compile *c)
+{
+   struct brw_codegen *p = &c->func;
+
+   brw_clip_ff_sync(c);
+   /* Send an empty message to kill the thread and release any
+    * allocated urb entry:
+    */
+   brw_urb_WRITE(p,
+                retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
+                0,
+                c->reg.R0,
+                 BRW_URB_WRITE_UNUSED | BRW_URB_WRITE_EOT_COMPLETE,
+                1,             /* msg len */
+                0,             /* response len */
+                0,
+                BRW_URB_SWIZZLE_NONE);
+}
+
+
+
+
+struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c )
+{
+   return brw_address(c->reg.fixed_planes);
+}
+
+
+struct brw_reg brw_clip_plane_stride( struct brw_clip_compile *c )
+{
+   if (c->key.nr_userclip) {
+      return brw_imm_uw(16);
+   }
+   else {
+      return brw_imm_uw(4);
+   }
+}
+
+
+/* Distribute flatshaded attributes from provoking vertex prior to
+ * clipping.
+ */
+void brw_clip_copy_flatshaded_attributes( struct brw_clip_compile *c,
+                          GLuint to, GLuint from )
+{
+   struct brw_codegen *p = &c->func;
+
+   for (int i = 0; i < c->vue_map.num_slots; i++) {
+      if (c->key.interp_mode[i] == INTERP_MODE_FLAT) {
+         brw_MOV(p,
+                 byte_offset(c->reg.vertex[to], brw_vue_slot_to_offset(i)),
+                 byte_offset(c->reg.vertex[from], brw_vue_slot_to_offset(i)));
+      }
+   }
+}
+
+
+
+void brw_clip_init_clipmask( struct brw_clip_compile *c )
+{
+   struct brw_codegen *p = &c->func;
+   struct brw_reg incoming = get_element_ud(c->reg.R0, 2);
+
+   /* Shift so that lowest outcode bit is rightmost:
+    */
+   brw_SHR(p, c->reg.planemask, incoming, brw_imm_ud(26));
+
+   if (c->key.nr_userclip) {
+      struct brw_reg tmp = retype(vec1(get_tmp(c)), BRW_REGISTER_TYPE_UD);
+
+      /* Rearrange userclip outcodes so that they come directly after
+       * the fixed plane bits.
+       */
+      if (p->devinfo->gen == 5 || p->devinfo->is_g4x)
+         brw_AND(p, tmp, incoming, brw_imm_ud(0xff<<14));
+      else
+         brw_AND(p, tmp, incoming, brw_imm_ud(0x3f<<14));
+
+      brw_SHR(p, tmp, tmp, brw_imm_ud(8));
+      brw_OR(p, c->reg.planemask, c->reg.planemask, tmp);
+
+      release_tmp(c, tmp);
+   }
+}
+
+void brw_clip_ff_sync(struct brw_clip_compile *c)
+{
+    struct brw_codegen *p = &c->func;
+
+    if (p->devinfo->gen == 5) {
+        brw_AND(p, brw_null_reg(), c->reg.ff_sync, brw_imm_ud(0x1));
+        brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_Z);
+        brw_IF(p, BRW_EXECUTE_1);
+        {
+            brw_OR(p, c->reg.ff_sync, c->reg.ff_sync, brw_imm_ud(0x1));
+            brw_ff_sync(p,
+                       c->reg.R0,
+                       0,
+                       c->reg.R0,
+                       1, /* allocate */
+                       1, /* response length */
+                       0 /* eot */);
+        }
+        brw_ENDIF(p);
+        brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
+    }
+}
+
+void brw_clip_init_ff_sync(struct brw_clip_compile *c)
+{
+    struct brw_codegen *p = &c->func;
+
+    if (p->devinfo->gen == 5) {
+        brw_MOV(p, c->reg.ff_sync, brw_imm_ud(0));
+    }
+}
diff --git a/src/intel/compiler/brw_compile_clip.c b/src/intel/compiler/brw_compile_clip.c
new file mode 100644 (file)
index 0000000..83788e4
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright Â© 2006 - 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "brw_clip.h"
+
+#include "common/gen_debug.h"
+
+const unsigned *
+brw_compile_clip(const struct brw_compiler *compiler,
+                 void *mem_ctx,
+                 const struct brw_clip_prog_key *key,
+                 struct brw_clip_prog_data *prog_data,
+                 struct brw_vue_map *vue_map,
+                 unsigned *final_assembly_size)
+{
+   struct brw_clip_compile c;
+   memset(&c, 0, sizeof(c));
+
+   /* Begin the compilation:
+    */
+   brw_init_codegen(compiler->devinfo, &c.func, mem_ctx);
+
+   c.func.single_program_flow = 1;
+
+   c.key = *key;
+   c.vue_map = *vue_map;
+
+   /* nr_regs is the number of registers filled by reading data from the VUE.
+    * This program accesses the entire VUE, so nr_regs needs to be the size of
+    * the VUE (measured in pairs, since two slots are stored in each
+    * register).
+    */
+   c.nr_regs = (c.vue_map.num_slots + 1)/2;
+
+   c.prog_data.clip_mode = c.key.clip_mode; /* XXX */
+
+   /* For some reason the thread is spawned with only 4 channels
+    * unmasked.
+    */
+   brw_set_default_mask_control(&c.func, BRW_MASK_DISABLE);
+
+   /* Would ideally have the option of producing a program which could
+    * do all three:
+    */
+   switch (key->primitive) {
+   case GL_TRIANGLES:
+      if (key->do_unfilled)
+        brw_emit_unfilled_clip( &c );
+      else
+        brw_emit_tri_clip( &c );
+      break;
+   case GL_LINES:
+      brw_emit_line_clip( &c );
+      break;
+   case GL_POINTS:
+      brw_emit_point_clip( &c );
+      break;
+   default:
+      unreachable("not reached");
+   }
+
+   brw_compact_instructions(&c.func, 0, 0, NULL);
+
+   *prog_data = c.prog_data;
+
+   const unsigned *program = brw_get_program(&c.func, final_assembly_size);
+
+   if (unlikely(INTEL_DEBUG & DEBUG_CLIP)) {
+      fprintf(stderr, "clip:\n");
+      brw_disassemble(compiler->devinfo,
+                      program, 0, *final_assembly_size, stderr);
+      fprintf(stderr, "\n");
+   }
+
+   return program;
+}
index 1f7afacfdae5e7b093ec0b004968116befd30baa..95cbfb7c33ea85213c544e86ff4a292415b36c48 100644 (file)
@@ -281,6 +281,47 @@ struct brw_sf_prog_key {
    bool userclip_active:1;
 };
 
+enum brw_clip_mode {
+   BRW_CLIP_MODE_NORMAL             = 0,
+   BRW_CLIP_MODE_CLIP_ALL           = 1,
+   BRW_CLIP_MODE_CLIP_NON_REJECTED  = 2,
+   BRW_CLIP_MODE_REJECT_ALL         = 3,
+   BRW_CLIP_MODE_ACCEPT_ALL         = 4,
+   BRW_CLIP_MODE_KERNEL_CLIP        = 5,
+};
+
+enum brw_clip_fill_mode {
+   BRW_CLIP_FILL_MODE_LINE = 0,
+   BRW_CLIP_FILL_MODE_POINT = 1,
+   BRW_CLIP_FILL_MODE_FILL = 2,
+   BRW_CLIP_FILL_MODE_CULL = 3,
+};
+
+/* Note that if unfilled primitives are being emitted, we have to fix
+ * up polygon offset and flatshading at this point:
+ */
+struct brw_clip_prog_key {
+   uint64_t attrs;
+   bool contains_flat_varying;
+   bool contains_noperspective_varying;
+   unsigned char interp_mode[65]; /* BRW_VARYING_SLOT_COUNT */
+   unsigned primitive:4;
+   unsigned nr_userclip:4;
+   bool pv_first:1;
+   bool do_unfilled:1;
+   enum brw_clip_fill_mode fill_cw:2;  /* includes cull information */
+   enum brw_clip_fill_mode fill_ccw:2; /* includes cull information */
+   bool offset_cw:1;
+   bool offset_ccw:1;
+   bool copy_bfc_cw:1;
+   bool copy_bfc_ccw:1;
+   enum brw_clip_mode clip_mode:3;
+
+   float offset_factor;
+   float offset_units;
+   float offset_clamp;
+};
+
 /* A big lookup table is used to figure out which and how many
  * additional regs will inserted before the main payload in the WM
  * program execution.  These mainly relate to depth and stencil
@@ -905,6 +946,13 @@ struct brw_sf_prog_data {
    unsigned urb_entry_size;
 };
 
+struct brw_clip_prog_data {
+   uint32_t curb_read_length;  /* user planes? */
+   uint32_t clip_mode;
+   uint32_t urb_read_length;
+   uint32_t total_grf;
+};
+
 #define DEFINE_PROG_DATA_DOWNCAST(stage)                       \
 static inline struct brw_##stage##_prog_data *                 \
 brw_##stage##_prog_data(struct brw_stage_prog_data *prog_data) \
@@ -1010,6 +1058,22 @@ brw_compile_sf(const struct brw_compiler *compiler,
                struct brw_vue_map *vue_map,
                unsigned *final_assembly_size);
 
+/**
+ * Compile a clipper shader.
+ *
+ * This is a fixed-function shader determined entirely by the shader key and
+ * a VUE map.
+ *
+ * Returns the final assembly and the program's size.
+ */
+const unsigned *
+brw_compile_clip(const struct brw_compiler *compiler,
+                 void *mem_ctx,
+                 const struct brw_clip_prog_key *key,
+                 struct brw_clip_prog_data *prog_data,
+                 struct brw_vue_map *vue_map,
+                 unsigned *final_assembly_size);
+
 /**
  * Compile a fragment shader.
  *
index bb03214c1cef31909cc260bbcb8442773d98d3d4..37338167c9831eb79ad314eb8dbb988053d64cac 100644 (file)
@@ -7,13 +7,7 @@ i965_FILES = \
        brw_cc.c \
        brw_clear.c \
        brw_clip.c \
-       brw_clip.h \
-       brw_clip_line.c \
-       brw_clip_point.c \
        brw_clip_state.c \
-       brw_clip_tri.c \
-       brw_clip_unfilled.c \
-       brw_clip_util.c \
        brw_compute.c \
        brw_conditional_render.c \
        brw_context.c \
index 34325a719be7014e999824d95fcc847804fb9300..d8805ff4fa54c4c39c823c8213c96d3951108eb6 100644 (file)
 #include "brw_context.h"
 #include "brw_util.h"
 #include "brw_state.h"
-#include "brw_clip.h"
+#include "compiler/brw_eu.h"
 
 #include "util/ralloc.h"
 
-#define FRONT_UNFILLED_BIT  0x1
-#define BACK_UNFILLED_BIT   0x2
-
-
 static void compile_clip_prog( struct brw_context *brw,
                             struct brw_clip_prog_key *key )
 {
-   struct brw_clip_compile c;
-   const GLuint *program;
+   const unsigned *program;
    void *mem_ctx;
-   GLuint program_size;
-
-   memset(&c, 0, sizeof(c));
+   unsigned program_size;
 
    mem_ctx = ralloc_context(NULL);
 
-   /* Begin the compilation:
-    */
-   brw_init_codegen(&brw->screen->devinfo, &c.func, mem_ctx);
-
-   c.func.single_program_flow = 1;
-
-   c.key = *key;
-   c.vue_map = brw->vue_map_geom_out;
-
-   /* nr_regs is the number of registers filled by reading data from the VUE.
-    * This program accesses the entire VUE, so nr_regs needs to be the size of
-    * the VUE (measured in pairs, since two slots are stored in each
-    * register).
-    */
-   c.nr_regs = (c.vue_map.num_slots + 1)/2;
-
-   c.prog_data.clip_mode = c.key.clip_mode; /* XXX */
-
-   /* For some reason the thread is spawned with only 4 channels
-    * unmasked.
-    */
-   brw_set_default_mask_control(&c.func, BRW_MASK_DISABLE);
-
-
-   /* Would ideally have the option of producing a program which could
-    * do all three:
-    */
-   switch (key->primitive) {
-   case GL_TRIANGLES:
-      if (key->do_unfilled)
-        brw_emit_unfilled_clip( &c );
-      else
-        brw_emit_tri_clip( &c );
-      break;
-   case GL_LINES:
-      brw_emit_line_clip( &c );
-      break;
-   case GL_POINTS:
-      brw_emit_point_clip( &c );
-      break;
-   default:
-      unreachable("not reached");
-   }
-
-   brw_compact_instructions(&c.func, 0, 0, NULL);
-
-   /* get the program
-    */
-   program = brw_get_program(&c.func, &program_size);
-
-   if (unlikely(INTEL_DEBUG & DEBUG_CLIP)) {
-      fprintf(stderr, "clip:\n");
-      brw_disassemble(&brw->screen->devinfo, c.func.store,
-                      0, program_size, stderr);
-      fprintf(stderr, "\n");
-   }
+   struct brw_clip_prog_data prog_data;
+   program = brw_compile_clip(brw->screen->compiler, mem_ctx, key, &prog_data,
+                              &brw->vue_map_geom_out, &program_size);
 
    brw_upload_cache(&brw->cache,
                    BRW_CACHE_CLIP_PROG,
-                   &c.key, sizeof(c.key),
+                   key, sizeof(*key),
                    program, program_size,
-                   &c.prog_data, sizeof(c.prog_data),
+                   &prog_data, sizeof(prog_data),
                    &brw->clip.prog_offset, &brw->clip.prog_data);
    ralloc_free(mem_ctx);
 }
@@ -174,18 +114,18 @@ brw_upload_clip_prog(struct brw_context *brw)
       key.nr_userclip = _mesa_logbase2(ctx->Transform.ClipPlanesEnabled) + 1;
 
    if (brw->gen == 5)
-       key.clip_mode = BRW_CLIPMODE_KERNEL_CLIP;
+       key.clip_mode = BRW_CLIP_MODE_KERNEL_CLIP;
    else
-       key.clip_mode = BRW_CLIPMODE_NORMAL;
+       key.clip_mode = BRW_CLIP_MODE_NORMAL;
 
    /* _NEW_POLYGON */
    if (key.primitive == GL_TRIANGLES) {
       if (ctx->Polygon.CullFlag &&
          ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
-        key.clip_mode = BRW_CLIPMODE_REJECT_ALL;
+        key.clip_mode = BRW_CLIP_MODE_REJECT_ALL;
       else {
-        GLuint fill_front = CLIP_CULL;
-        GLuint fill_back = CLIP_CULL;
+        GLuint fill_front = BRW_CLIP_FILL_MODE_CULL;
+        GLuint fill_back = BRW_CLIP_FILL_MODE_CULL;
         GLuint offset_front = 0;
         GLuint offset_back = 0;
 
@@ -193,15 +133,15 @@ brw_upload_clip_prog(struct brw_context *brw)
             ctx->Polygon.CullFaceMode != GL_FRONT) {
            switch (ctx->Polygon.FrontMode) {
            case GL_FILL:
-              fill_front = CLIP_FILL;
+              fill_front = BRW_CLIP_FILL_MODE_FILL;
               offset_front = 0;
               break;
            case GL_LINE:
-              fill_front = CLIP_LINE;
+              fill_front = BRW_CLIP_FILL_MODE_LINE;
               offset_front = ctx->Polygon.OffsetLine;
               break;
            case GL_POINT:
-              fill_front = CLIP_POINT;
+              fill_front = BRW_CLIP_FILL_MODE_POINT;
               offset_front = ctx->Polygon.OffsetPoint;
               break;
            }
@@ -211,15 +151,15 @@ brw_upload_clip_prog(struct brw_context *brw)
             ctx->Polygon.CullFaceMode != GL_BACK) {
            switch (ctx->Polygon.BackMode) {
            case GL_FILL:
-              fill_back = CLIP_FILL;
+              fill_back = BRW_CLIP_FILL_MODE_FILL;
               offset_back = 0;
               break;
            case GL_LINE:
-              fill_back = CLIP_LINE;
+              fill_back = BRW_CLIP_FILL_MODE_LINE;
               offset_back = ctx->Polygon.OffsetLine;
               break;
            case GL_POINT:
-              fill_back = CLIP_POINT;
+              fill_back = BRW_CLIP_FILL_MODE_POINT;
               offset_back = ctx->Polygon.OffsetPoint;
               break;
            }
@@ -232,7 +172,7 @@ brw_upload_clip_prog(struct brw_context *brw)
            /* Most cases the fixed function units will handle.  Cases where
             * one or more polygon faces are unfilled will require help:
             */
-           key.clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED;
+           key.clip_mode = BRW_CLIP_MODE_CLIP_NON_REJECTED;
 
            if (offset_back || offset_front) {
               /* _NEW_POLYGON, _NEW_BUFFERS */
@@ -247,7 +187,7 @@ brw_upload_clip_prog(struct brw_context *brw)
               key.offset_ccw = offset_front;
               key.offset_cw = offset_back;
               if (ctx->Light.Model.TwoSide &&
-                  key.fill_cw != CLIP_CULL)
+                  key.fill_cw != BRW_CLIP_FILL_MODE_CULL)
                  key.copy_bfc_cw = 1;
            } else {
               key.fill_cw = fill_front;
@@ -255,7 +195,7 @@ brw_upload_clip_prog(struct brw_context *brw)
               key.offset_cw = offset_front;
               key.offset_ccw = offset_back;
               if (ctx->Light.Model.TwoSide &&
-                  key.fill_ccw != CLIP_CULL)
+                  key.fill_ccw != BRW_CLIP_FILL_MODE_CULL)
                  key.copy_bfc_ccw = 1;
            }
         }
diff --git a/src/mesa/drivers/dri/i965/brw_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h
deleted file mode 100644 (file)
index 2dc84d8..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- Copyright (C) Intel Corp.  2006.  All Rights Reserved.
- Intel funded Tungsten Graphics to
- develop this 3D driver.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice (including the
- next paragraph) shall be included in all copies or substantial
- portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- **********************************************************************/
- /*
-  * Authors:
-  *   Keith Whitwell <keithw@vmware.com>
-  */
-
-#ifndef BRW_CLIP_H
-#define BRW_CLIP_H
-
-
-#include "brw_context.h"
-#include "compiler/brw_eu.h"
-
-/* Initial 3 verts, plus at most 6 additional verts from intersections
- * with fixed planes, plus at most 8 additional verts from intersections
- * with user clip planes
- */
-#define MAX_VERTS (3+6+8)
-
-/* Note that if unfilled primitives are being emitted, we have to fix
- * up polygon offset and flatshading at this point:
- */
-struct brw_clip_prog_key {
-   GLbitfield64 attrs;
-   bool contains_flat_varying;
-   bool contains_noperspective_varying;
-   unsigned char interp_mode[65]; /* BRW_VARYING_SLOT_COUNT */
-   GLuint primitive:4;
-   GLuint nr_userclip:4;
-   GLuint pv_first:1;
-   GLuint do_unfilled:1;
-   GLuint fill_cw:2;           /* includes cull information */
-   GLuint fill_ccw:2;          /* includes cull information */
-   GLuint offset_cw:1;
-   GLuint offset_ccw:1;
-   GLuint copy_bfc_cw:1;
-   GLuint copy_bfc_ccw:1;
-   GLuint clip_mode:3;
-
-   GLfloat offset_factor;
-   GLfloat offset_units;
-   GLfloat offset_clamp;
-};
-
-
-#define CLIP_LINE   0
-#define CLIP_POINT  1
-#define CLIP_FILL   2
-#define CLIP_CULL   3
-
-
-#define PRIM_MASK  (0x1f)
-
-struct brw_clip_compile {
-   struct brw_codegen func;
-   struct brw_clip_prog_key key;
-   struct brw_clip_prog_data prog_data;
-
-   struct {
-      struct brw_reg R0;
-      struct brw_reg vertex[MAX_VERTS];
-
-      struct brw_reg t;
-      struct brw_reg t0, t1;
-      struct brw_reg dp0, dp1;
-
-      struct brw_reg dpPrev;
-      struct brw_reg dp;
-      struct brw_reg loopcount;
-      struct brw_reg nr_verts;
-      struct brw_reg planemask;
-
-      struct brw_reg inlist;
-      struct brw_reg outlist;
-      struct brw_reg freelist;
-
-      struct brw_reg dir;
-      struct brw_reg tmp0, tmp1;
-      struct brw_reg offset;
-
-      struct brw_reg fixed_planes;
-      struct brw_reg plane_equation;
-
-      struct brw_reg ff_sync;
-
-      /* Bitmask indicating which coordinate attribute should be used for
-       * comparison to each clipping plane. A 0 indicates that VARYING_SLOT_POS
-       * should be used, because it's one of the fixed +/- x/y/z planes that
-       * constitute the bounds of the view volume. A 1 indicates that
-       * VARYING_SLOT_CLIP_VERTEX should be used (if available) since it's a user-
-       * defined clipping plane.
-       */
-      struct brw_reg vertex_src_mask;
-
-      /* Offset into the vertex of the current plane's clipdistance value */
-      struct brw_reg clipdistance_offset;
-   } reg;
-
-   /* Number of registers storing VUE data */
-   GLuint nr_regs;
-
-   GLuint first_tmp;
-   GLuint last_tmp;
-
-   bool need_direction;
-
-   struct brw_vue_map vue_map;
-};
-
-/**
- * True if the given varying is one of the outputs of the vertex shader.
- */
-static inline bool brw_clip_have_varying(struct brw_clip_compile *c,
-                                         GLuint varying)
-{
-   return (c->key.attrs & BITFIELD64_BIT(varying)) ? 1 : 0;
-}
-
-/* Points are only culled, so no need for a clip routine, however it
- * works out easier to have a dummy one.
- */
-void brw_emit_unfilled_clip( struct brw_clip_compile *c );
-void brw_emit_tri_clip( struct brw_clip_compile *c );
-void brw_emit_line_clip( struct brw_clip_compile *c );
-void brw_emit_point_clip( struct brw_clip_compile *c );
-
-/* brw_clip_tri.c, for use by the unfilled clip routine:
- */
-void brw_clip_tri_init_vertices( struct brw_clip_compile *c );
-void brw_clip_tri_flat_shade( struct brw_clip_compile *c );
-void brw_clip_tri( struct brw_clip_compile *c );
-void brw_clip_tri_emit_polygon( struct brw_clip_compile *c );
-void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
-                             GLuint nr_verts );
-
-
-/* Utils:
- */
-
-void brw_clip_interp_vertex( struct brw_clip_compile *c,
-                            struct brw_indirect dest_ptr,
-                            struct brw_indirect v0_ptr, /* from */
-                            struct brw_indirect v1_ptr, /* to */
-                            struct brw_reg t0,
-                            bool force_edgeflag );
-
-void brw_clip_init_planes( struct brw_clip_compile *c );
-
-void brw_clip_emit_vue(struct brw_clip_compile *c,
-                      struct brw_indirect vert,
-                       enum brw_urb_write_flags flags,
-                      GLuint header);
-
-void brw_clip_kill_thread(struct brw_clip_compile *c);
-
-struct brw_reg brw_clip_plane_stride( struct brw_clip_compile *c );
-struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c );
-
-void brw_clip_copy_flatshaded_attributes( struct brw_clip_compile *c,
-                                          GLuint to, GLuint from );
-
-void brw_clip_init_clipmask( struct brw_clip_compile *c );
-
-struct brw_reg get_tmp( struct brw_clip_compile *c );
-
-void brw_clip_project_position(struct brw_clip_compile *c,
-             struct brw_reg pos );
-void brw_clip_ff_sync(struct brw_clip_compile *c);
-void brw_clip_init_ff_sync(struct brw_clip_compile *c);
-#endif
diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c
deleted file mode 100644 (file)
index 788dc96..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- Copyright (C) Intel Corp.  2006.  All Rights Reserved.
- Intel funded Tungsten Graphics to
- develop this 3D driver.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice (including the
- next paragraph) shall be included in all copies or substantial
- portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- **********************************************************************/
- /*
-  * Authors:
-  *   Keith Whitwell <keithw@vmware.com>
-  */
-
-#include "main/macros.h"
-#include "main/enums.h"
-#include "program/program.h"
-
-#include "intel_batchbuffer.h"
-
-#include "brw_defines.h"
-#include "brw_context.h"
-#include "brw_clip.h"
-
-
-
-static void brw_clip_line_alloc_regs( struct brw_clip_compile *c )
-{
-   const struct gen_device_info *devinfo = c->func.devinfo;
-   GLuint i = 0,j;
-
-   /* Register usage is static, precompute here:
-    */
-   c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
-
-   if (c->key.nr_userclip) {
-      c->reg.fixed_planes = brw_vec4_grf(i, 0);
-      i += (6 + c->key.nr_userclip + 1) / 2;
-
-      c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2;
-   }
-   else
-      c->prog_data.curb_read_length = 0;
-
-
-   /* Payload vertices plus space for more generated vertices:
-    */
-   for (j = 0; j < 4; j++) {
-      c->reg.vertex[j] = brw_vec4_grf(i, 0);
-      i += c->nr_regs;
-   }
-
-   c->reg.t           = brw_vec1_grf(i, 0);
-   c->reg.t0          = brw_vec1_grf(i, 1);
-   c->reg.t1          = brw_vec1_grf(i, 2);
-   c->reg.planemask   = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
-   c->reg.plane_equation = brw_vec4_grf(i, 4);
-   i++;
-
-   c->reg.dp0         = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
-   c->reg.dp1         = brw_vec1_grf(i, 4);
-   i++;
-
-   if (!c->key.nr_userclip) {
-      c->reg.fixed_planes = brw_vec8_grf(i, 0);
-      i++;
-   }
-
-   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 (devinfo->gen == 5) {
-      c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
-      i++;
-   }
-
-   c->first_tmp = i;
-   c->last_tmp = i;
-
-   c->prog_data.urb_read_length = c->nr_regs; /* ? */
-   c->prog_data.total_grf = i;
-}
-
-
-/* Line clipping, more or less following the following algorithm:
- *
- *  for (p=0;p<MAX_PLANES;p++) {
- *     if (clipmask & (1 << p)) {
- *        GLfloat dp0 = DOTPROD( vtx0, plane[p] );
- *        GLfloat dp1 = DOTPROD( vtx1, plane[p] );
- *
- *        if (dp1 < 0.0f) {
- *           GLfloat t = dp1 / (dp1 - dp0);
- *           if (t > t1) t1 = t;
- *        } else {
- *           GLfloat t = dp0 / (dp0 - dp1);
- *           if (t > t0) t0 = t;
- *        }
- *
- *        if (t0 + t1 >= 1.0)
- *           return;
- *     }
- *  }
- *
- *  interp( ctx, newvtx0, vtx0, vtx1, t0 );
- *  interp( ctx, newvtx1, vtx1, vtx0, t1 );
- *
- */
-static void clip_and_emit_line( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-   struct brw_indirect vtx0     = brw_indirect(0, 0);
-   struct brw_indirect vtx1      = brw_indirect(1, 0);
-   struct brw_indirect newvtx0   = brw_indirect(2, 0);
-   struct brw_indirect newvtx1   = brw_indirect(3, 0);
-   struct brw_indirect plane_ptr = brw_indirect(4, 0);
-   struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD);
-   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(vtx0),      brw_address(c->reg.vertex[0]));
-   brw_MOV(p, get_addr_reg(vtx1),      brw_address(c->reg.vertex[1]));
-   brw_MOV(p, get_addr_reg(newvtx0),   brw_address(c->reg.vertex[2]));
-   brw_MOV(p, get_addr_reg(newvtx1),   brw_address(c->reg.vertex[3]));
-   brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c));
-
-   /* Note: init t0, t1 together:
-    */
-   brw_MOV(p, vec2(c->reg.t0), brw_imm_f(0));
-
-   brw_clip_init_planes(c);
-   brw_clip_init_clipmask(c);
-
-   /* -ve rhw workaround */
-   if (p->devinfo->has_negative_rhw_bug) {
-      brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
-              brw_imm_ud(1<<20));
-      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
-      brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f));
-      brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-   }
-
-   /* 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)
-       */
-      brw_AND(p, v1_null_ud, c->reg.planemask, brw_imm_ud(1));
-      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
-
-      brw_IF(p, BRW_EXECUTE_1);
-      {
-         brw_AND(p, v1_null_ud, c->reg.vertex_src_mask, brw_imm_ud(1));
-         brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
-         brw_IF(p, BRW_EXECUTE_1);
-         {
-            /* user clip distance: just fetch the correct float from each vertex */
-            struct brw_indirect temp_ptr = brw_indirect(7, 0);
-            brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx0), c->reg.clipdistance_offset);
-            brw_MOV(p, c->reg.dp0, deref_1f(temp_ptr, 0));
-            brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx1), c->reg.clipdistance_offset);
-            brw_MOV(p, c->reg.dp1, deref_1f(temp_ptr, 0));
-         }
-         brw_ELSE(p);
-         {
-            /* fixed plane: fetch the hpos, dp4 against the plane. */
-            if (c->key.nr_userclip)
-               brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
-            else
-               brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
-
-            brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, hpos_offset), c->reg.plane_equation);
-            brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, hpos_offset), c->reg.plane_equation);
-         }
-         brw_ENDIF(p);
-
-         brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, vec1(c->reg.dp1), brw_imm_f(0.0f));
-
-         brw_IF(p, BRW_EXECUTE_1);
-         {
-             /*
-              * Both can be negative on GM965/G965 due to RHW workaround
-              * if so, this object should be rejected.
-              */
-             if (p->devinfo->has_negative_rhw_bug) {
-                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, c->reg.dp0, brw_imm_f(0.0));
-                 brw_IF(p, BRW_EXECUTE_1);
-                 {
-                     brw_clip_kill_thread(c);
-                 }
-                 brw_ENDIF(p);
-             }
-
-             brw_ADD(p, c->reg.t, c->reg.dp1, negate(c->reg.dp0));
-             brw_math_invert(p, c->reg.t, c->reg.t);
-             brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp1);
-
-             brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t1 );
-             brw_MOV(p, c->reg.t1, c->reg.t);
-             brw_inst_set_pred_control(p->devinfo, brw_last_inst,
-                                       BRW_PREDICATE_NORMAL);
-        }
-        brw_ELSE(p);
-        {
-             /* Coming back in.  We know that both cannot be negative
-              * because the line would have been culled in that case.
-              */
-
-             /* If both are positive, do nothing */
-             /* Only on GM965/G965 */
-             if (p->devinfo->has_negative_rhw_bug) {
-                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0));
-                 brw_IF(p, BRW_EXECUTE_1);
-             }
-
-             {
-                 brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1));
-                 brw_math_invert(p, c->reg.t, c->reg.t);
-                 brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0);
-
-                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 );
-                 brw_MOV(p, c->reg.t0, c->reg.t);
-                 brw_inst_set_pred_control(p->devinfo, brw_last_inst,
-                                           BRW_PREDICATE_NORMAL);
-             }
-
-             if (p->devinfo->has_negative_rhw_bug) {
-                 brw_ENDIF(p);
-             }
-         }
-        brw_ENDIF(p);
-      }
-      brw_ENDIF(p);
-
-      /* plane_ptr++;
-       */
-      brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
-
-      /* while (planemask>>=1) != 0
-       */
-      brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
-      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
-      brw_SHR(p, c->reg.vertex_src_mask, c->reg.vertex_src_mask, brw_imm_ud(1));
-      brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-      brw_ADD(p, c->reg.clipdistance_offset, c->reg.clipdistance_offset, brw_imm_w(sizeof(float)));
-      brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-   }
-   brw_WHILE(p);
-   brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-
-   brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1);
-   brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0));
-   brw_IF(p, BRW_EXECUTE_1);
-   {
-      brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, false);
-      brw_clip_interp_vertex(c, newvtx1, vtx1, vtx0, c->reg.t1, false);
-
-      brw_clip_emit_vue(c, newvtx0, BRW_URB_WRITE_ALLOCATE_COMPLETE,
-                        (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT)
-                        | URB_WRITE_PRIM_START);
-      brw_clip_emit_vue(c, newvtx1, BRW_URB_WRITE_EOT_COMPLETE,
-                        (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT)
-                        | URB_WRITE_PRIM_END);
-   }
-   brw_ENDIF(p);
-   brw_clip_kill_thread(c);
-}
-
-
-
-void brw_emit_line_clip( struct brw_clip_compile *c )
-{
-   brw_clip_line_alloc_regs(c);
-   brw_clip_init_ff_sync(c);
-
-   if (c->key.contains_flat_varying) {
-      if (c->key.pv_first)
-         brw_clip_copy_flatshaded_attributes(c, 1, 0);
-      else
-         brw_clip_copy_flatshaded_attributes(c, 0, 1);
-   }
-
-   clip_and_emit_line(c);
-}
diff --git a/src/mesa/drivers/dri/i965/brw_clip_point.c b/src/mesa/drivers/dri/i965/brw_clip_point.c
deleted file mode 100644 (file)
index bdbf969..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- Copyright (C) Intel Corp.  2006.  All Rights Reserved.
- Intel funded Tungsten Graphics to
- develop this 3D driver.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice (including the
- next paragraph) shall be included in all copies or substantial
- portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- **********************************************************************/
- /*
-  * Authors:
-  *   Keith Whitwell <keithw@vmware.com>
-  */
-
-#include "main/macros.h"
-#include "main/enums.h"
-#include "program/program.h"
-
-#include "intel_batchbuffer.h"
-
-#include "brw_defines.h"
-#include "brw_context.h"
-#include "brw_clip.h"
-
-
-/* Point clipping, nothing to do?
- */
-void brw_emit_point_clip( struct brw_clip_compile *c )
-{
-   /* Send an empty message to kill the thread:
-    */
-   brw_clip_tri_alloc_regs(c, 0);
-   brw_clip_init_ff_sync(c);
-
-   brw_clip_kill_thread(c);
-}
diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c
deleted file mode 100644 (file)
index d98e1cc..0000000
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
- Copyright (C) Intel Corp.  2006.  All Rights Reserved.
- Intel funded Tungsten Graphics to
- develop this 3D driver.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice (including the
- next paragraph) shall be included in all copies or substantial
- portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- **********************************************************************/
- /*
-  * Authors:
-  *   Keith Whitwell <keithw@vmware.com>
-  */
-
-#include "main/macros.h"
-#include "main/enums.h"
-#include "program/program.h"
-
-#include "intel_batchbuffer.h"
-
-#include "brw_defines.h"
-#include "brw_context.h"
-#include "brw_clip.h"
-
-static void release_tmps( struct brw_clip_compile *c )
-{
-   c->last_tmp = c->first_tmp;
-}
-
-
-void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
-                             GLuint nr_verts )
-{
-   const struct gen_device_info *devinfo = c->func.devinfo;
-   GLuint i = 0,j;
-
-   /* Register usage is static, precompute here:
-    */
-   c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
-
-   if (c->key.nr_userclip) {
-      c->reg.fixed_planes = brw_vec4_grf(i, 0);
-      i += (6 + c->key.nr_userclip + 1) / 2;
-
-      c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2;
-   }
-   else
-      c->prog_data.curb_read_length = 0;
-
-
-   /* Payload vertices plus space for more generated vertices:
-    */
-   for (j = 0; j < nr_verts; j++) {
-      c->reg.vertex[j] = brw_vec4_grf(i, 0);
-      i += c->nr_regs;
-   }
-
-   if (c->vue_map.num_slots % 2) {
-      /* The VUE has an odd number of slots so the last register is only half
-       * used.  Fill the second half with zero.
-       */
-      for (j = 0; j < 3; j++) {
-        GLuint delta = brw_vue_slot_to_offset(c->vue_map.num_slots);
-
-        brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0));
-      }
-   }
-
-   c->reg.t          = brw_vec1_grf(i, 0);
-   c->reg.loopcount  = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_D);
-   c->reg.nr_verts   = retype(brw_vec1_grf(i, 2), BRW_REGISTER_TYPE_UD);
-   c->reg.planemask  = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
-   c->reg.plane_equation = brw_vec4_grf(i, 4);
-   i++;
-
-   c->reg.dpPrev     = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
-   c->reg.dp         = brw_vec1_grf(i, 4);
-   i++;
-
-   c->reg.inlist     = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
-   i++;
-
-   c->reg.outlist    = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
-   i++;
-
-   c->reg.freelist   = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
-   i++;
-
-   if (!c->key.nr_userclip) {
-      c->reg.fixed_planes = brw_vec8_grf(i, 0);
-      i++;
-   }
-
-   if (c->key.do_unfilled) {
-      c->reg.dir     = brw_vec4_grf(i, 0);
-      c->reg.offset  = brw_vec4_grf(i, 4);
-      i++;
-      c->reg.tmp0    = brw_vec4_grf(i, 0);
-      c->reg.tmp1    = brw_vec4_grf(i, 4);
-      i++;
-   }
-
-   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 (devinfo->gen == 5) {
-      c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
-      i++;
-   }
-
-   c->first_tmp = i;
-   c->last_tmp = i;
-
-   c->prog_data.urb_read_length = c->nr_regs; /* ? */
-   c->prog_data.total_grf = i;
-}
-
-
-
-void brw_clip_tri_init_vertices( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-   struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
-
-   /* Initial list of indices for incoming vertexes:
-    */
-   brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
-   brw_CMP(p,
-          vec1(brw_null_reg()),
-          BRW_CONDITIONAL_EQ,
-          tmp0,
-          brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE));
-
-   /* XXX: Is there an easier way to do this?  Need to reverse every
-    * second tristrip element:  Can ignore sometimes?
-    */
-   brw_IF(p, BRW_EXECUTE_1);
-   {
-      brw_MOV(p, get_element(c->reg.inlist, 0),  brw_address(c->reg.vertex[1]) );
-      brw_MOV(p, get_element(c->reg.inlist, 1),  brw_address(c->reg.vertex[0]) );
-      if (c->need_direction)
-        brw_MOV(p, c->reg.dir, brw_imm_f(-1));
-   }
-   brw_ELSE(p);
-   {
-      brw_MOV(p, get_element(c->reg.inlist, 0),  brw_address(c->reg.vertex[0]) );
-      brw_MOV(p, get_element(c->reg.inlist, 1),  brw_address(c->reg.vertex[1]) );
-      if (c->need_direction)
-        brw_MOV(p, c->reg.dir, brw_imm_f(1));
-   }
-   brw_ENDIF(p);
-
-   brw_MOV(p, get_element(c->reg.inlist, 2),  brw_address(c->reg.vertex[2]) );
-   brw_MOV(p, brw_vec8_grf(c->reg.outlist.nr, 0), brw_imm_f(0));
-   brw_MOV(p, c->reg.nr_verts, brw_imm_ud(3));
-}
-
-
-
-void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-   struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
-
-   brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
-   brw_CMP(p,
-          vec1(brw_null_reg()),
-          BRW_CONDITIONAL_EQ,
-          tmp0,
-          brw_imm_ud(_3DPRIM_POLYGON));
-
-   brw_IF(p, BRW_EXECUTE_1);
-   {
-      brw_clip_copy_flatshaded_attributes(c, 1, 0);
-      brw_clip_copy_flatshaded_attributes(c, 2, 0);
-   }
-   brw_ELSE(p);
-   {
-      if (c->key.pv_first) {
-        brw_CMP(p,
-                vec1(brw_null_reg()),
-                BRW_CONDITIONAL_EQ,
-                tmp0,
-                brw_imm_ud(_3DPRIM_TRIFAN));
-        brw_IF(p, BRW_EXECUTE_1);
-        {
-           brw_clip_copy_flatshaded_attributes(c, 0, 1);
-           brw_clip_copy_flatshaded_attributes(c, 2, 1);
-        }
-        brw_ELSE(p);
-        {
-           brw_clip_copy_flatshaded_attributes(c, 1, 0);
-           brw_clip_copy_flatshaded_attributes(c, 2, 0);
-        }
-        brw_ENDIF(p);
-      }
-      else {
-         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_codegen *p = &c->func;
-
-   dst = vec4(dst);
-   brw_AND(p, vec1(brw_null_reg()), c->reg.vertex_src_mask, brw_imm_ud(1));
-   brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
-   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_CMP(p, brw_null_reg(), cond, vec1(dst), brw_imm_f(0.0f));
-}
-
-
-/* Use mesa's clipping algorithms, translated to GEN4 assembly.
- */
-void brw_clip_tri( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-   struct brw_indirect vtx = brw_indirect(0, 0);
-   struct brw_indirect vtxPrev = brw_indirect(1, 0);
-   struct brw_indirect vtxOut = brw_indirect(2, 0);
-   struct brw_indirect plane_ptr = brw_indirect(3, 0);
-   struct brw_indirect inlist_ptr = brw_indirect(4, 0);
-   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));
-   brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
-
-   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)
-       */
-      brw_AND(p, vec1(brw_null_reg()), c->reg.planemask, brw_imm_ud(1));
-      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
-
-      brw_IF(p, BRW_EXECUTE_1);
-      {
-        /* vtxOut = freelist_ptr++
-         */
-        brw_MOV(p, get_addr_reg(vtxOut),       get_addr_reg(freelist_ptr) );
-        brw_ADD(p, get_addr_reg(freelist_ptr), get_addr_reg(freelist_ptr), brw_imm_uw(c->nr_regs * REG_SIZE));
-
-        if (c->key.nr_userclip)
-           brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
-        else
-           brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
-
-        brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
-        brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0));
-
-        brw_DO(p, BRW_EXECUTE_1);
-        {
-           /* vtx = *input_ptr;
-            */
-           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);
-           /* (prev < 0.0f) */
-           brw_IF(p, BRW_EXECUTE_1);
-           {
-               load_clip_distance(c, vtx, c->reg.dp, hpos_offset, BRW_CONDITIONAL_GE);
-              /* IS_POSITIVE(next)
-               */
-              brw_IF(p, BRW_EXECUTE_1);
-              {
-
-                 /* Coming back in.
-                  */
-                 brw_ADD(p, c->reg.t, c->reg.dpPrev, negate(c->reg.dp));
-                 brw_math_invert(p, c->reg.t, c->reg.t);
-                 brw_MUL(p, c->reg.t, c->reg.t, c->reg.dpPrev);
-
-                 /* If (vtxOut == 0) vtxOut = vtxPrev
-                  */
-                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
-                  brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtxPrev));
-                  brw_inst_set_pred_control(p->devinfo, brw_last_inst,
-                                            BRW_PREDICATE_NORMAL);
-
-                 brw_clip_interp_vertex(c, vtxOut, vtxPrev, vtx, c->reg.t, false);
-
-                 /* *outlist_ptr++ = vtxOut;
-                  * nr_verts++;
-                  * vtxOut = 0;
-                  */
-                 brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
-                 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));
-                 brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
-              }
-              brw_ENDIF(p);
-
-           }
-           brw_ELSE(p);
-           {
-              /* *outlist_ptr++ = vtxPrev;
-               * nr_verts++;
-               */
-              brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxPrev));
-              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);
-              /* (next < 0.0f)
-               */
-              brw_IF(p, BRW_EXECUTE_1);
-              {
-                 /* Going out of bounds.  Avoid division by zero as we
-                  * know dp != dpPrev from DIFFERENT_SIGNS, above.
-                  */
-                 brw_ADD(p, c->reg.t, c->reg.dp, negate(c->reg.dpPrev));
-                 brw_math_invert(p, c->reg.t, c->reg.t);
-                 brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp);
-
-                 /* If (vtxOut == 0) vtxOut = vtx
-                  */
-                 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
-                  brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtx));
-                  brw_inst_set_pred_control(p->devinfo, brw_last_inst,
-                                            BRW_PREDICATE_NORMAL);
-
-                 brw_clip_interp_vertex(c, vtxOut, vtx, vtxPrev, c->reg.t, true);
-
-                 /* *outlist_ptr++ = vtxOut;
-                  * nr_verts++;
-                  * vtxOut = 0;
-                  */
-                 brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
-                 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));
-                 brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
-              }
-              brw_ENDIF(p);
-           }
-           brw_ENDIF(p);
-
-           /* vtxPrev = vtx;
-            * inlist_ptr++;
-            */
-           brw_MOV(p, get_addr_reg(vtxPrev), get_addr_reg(vtx));
-           brw_ADD(p, get_addr_reg(inlist_ptr), get_addr_reg(inlist_ptr), brw_imm_uw(sizeof(short)));
-
-           /* while (--loopcount != 0)
-            */
-           brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
-            brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
-        }
-        brw_WHILE(p);
-         brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-
-        /* vtxPrev = *(outlist_ptr-1)  OR: outlist[nr_verts-1]
-         * inlist = outlist
-         * inlist_ptr = &inlist[0]
-         * outlist_ptr = &outlist[0]
-         */
-        brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_w(-2));
-        brw_MOV(p, get_addr_reg(vtxPrev), deref_1uw(outlist_ptr, 0));
-        brw_MOV(p, brw_vec8_grf(c->reg.inlist.nr, 0), brw_vec8_grf(c->reg.outlist.nr, 0));
-        brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist));
-        brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
-      }
-      brw_ENDIF(p);
-
-      /* plane_ptr++;
-       */
-      brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
-
-      /* nr_verts >= 3
-       */
-      brw_CMP(p,
-             vec1(brw_null_reg()),
-             BRW_CONDITIONAL_GE,
-             c->reg.nr_verts,
-             brw_imm_ud(3));
-      brw_set_default_predicate_control(p, BRW_PREDICATE_NORMAL);
-
-      /* && (planemask>>=1) != 0
-       */
-      brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
-      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
-      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);
-   brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
-}
-
-
-
-void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
-{
-   struct brw_codegen *p = &c->func;
-
-   /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
-    */
-   brw_ADD(p,
-          c->reg.loopcount,
-          c->reg.nr_verts,
-          brw_imm_d(-2));
-   brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_G);
-
-   brw_IF(p, BRW_EXECUTE_1);
-   {
-      struct brw_indirect v0 = brw_indirect(0, 0);
-      struct brw_indirect vptr = brw_indirect(1, 0);
-
-      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, BRW_URB_WRITE_ALLOCATE_COMPLETE,
-                        ((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
-                         | URB_WRITE_PRIM_START));
-
-      brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
-      brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
-
-      brw_DO(p, BRW_EXECUTE_1);
-      {
-        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));
-        brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
-
-        brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
-         brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
-      }
-      brw_WHILE(p);
-      brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-
-      brw_clip_emit_vue(c, v0, BRW_URB_WRITE_EOT_COMPLETE,
-                        ((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
-                         | URB_WRITE_PRIM_END));
-   }
-   brw_ENDIF(p);
-}
-
-static void do_clip_tri( struct brw_clip_compile *c )
-{
-   brw_clip_init_planes(c);
-
-   brw_clip_tri(c);
-}
-
-
-static void maybe_do_clip_tri( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-
-   brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
-   brw_IF(p, BRW_EXECUTE_1);
-   {
-      do_clip_tri(c);
-   }
-   brw_ENDIF(p);
-}
-
-static void brw_clip_test( struct brw_clip_compile *c )
-{
-    struct brw_reg t = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
-    struct brw_reg t1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
-    struct brw_reg t2 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
-    struct brw_reg t3 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
-
-    struct brw_reg v0 = get_tmp(c);
-    struct brw_reg v1 = get_tmp(c);
-    struct brw_reg v2 = get_tmp(c);
-
-    struct brw_indirect vt0 = brw_indirect(0, 0);
-    struct brw_indirect vt1 = brw_indirect(1, 0);
-    struct brw_indirect vt2 = brw_indirect(2, 0);
-
-    struct brw_codegen *p = &c->func;
-    struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
-
-    GLuint hpos_offset = brw_varying_to_offset(&c->vue_map,
-                                                   VARYING_SLOT_POS);
-
-    brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0]));
-    brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1]));
-    brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2]));
-    brw_MOV(p, v0, deref_4f(vt0, hpos_offset));
-    brw_MOV(p, v1, deref_4f(vt1, hpos_offset));
-    brw_MOV(p, v2, deref_4f(vt2, hpos_offset));
-    brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f));
-
-    /* test nearz, xmin, ymin plane */
-    /* clip.xyz < -clip.w */
-    brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, negate(get_element(v0, 3)));
-    brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, negate(get_element(v1, 3)));
-    brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, negate(get_element(v2, 3)));
-
-    /* All vertices are outside of a plane, rejected */
-    brw_AND(p, t, t1, t2);
-    brw_AND(p, t, t, t3);
-    brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
-    brw_OR(p, tmp0, tmp0, get_element(t, 2));
-    brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
-    brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
-    brw_IF(p, BRW_EXECUTE_1);
-    {
-        brw_clip_kill_thread(c);
-    }
-    brw_ENDIF(p);
-    brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
-
-    /* some vertices are inside a plane, some are outside,need to clip */
-    brw_XOR(p, t, t1, t2);
-    brw_XOR(p, t1, t2, t3);
-    brw_OR(p, t, t, t1);
-    brw_AND(p, t, t, brw_imm_ud(0x1));
-    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
-            get_element(t, 0), brw_imm_ud(0));
-    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5)));
-    brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
-            get_element(t, 1), brw_imm_ud(0));
-    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3)));
-    brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
-            get_element(t, 2), brw_imm_ud(0));
-    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1)));
-    brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-
-    /* test farz, xmax, ymax plane */
-    /* clip.xyz > clip.w */
-    brw_CMP(p, t1, BRW_CONDITIONAL_G, v0, get_element(v0, 3));
-    brw_CMP(p, t2, BRW_CONDITIONAL_G, v1, get_element(v1, 3));
-    brw_CMP(p, t3, BRW_CONDITIONAL_G, v2, get_element(v2, 3));
-
-    /* All vertices are outside of a plane, rejected */
-    brw_AND(p, t, t1, t2);
-    brw_AND(p, t, t, t3);
-    brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
-    brw_OR(p, tmp0, tmp0, get_element(t, 2));
-    brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
-    brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
-    brw_IF(p, BRW_EXECUTE_1);
-    {
-        brw_clip_kill_thread(c);
-    }
-    brw_ENDIF(p);
-    brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
-
-    /* some vertices are inside a plane, some are outside,need to clip */
-    brw_XOR(p, t, t1, t2);
-    brw_XOR(p, t1, t2, t3);
-    brw_OR(p, t, t, t1);
-    brw_AND(p, t, t, brw_imm_ud(0x1));
-    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
-            get_element(t, 0), brw_imm_ud(0));
-    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4)));
-    brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
-            get_element(t, 1), brw_imm_ud(0));
-    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2)));
-    brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
-            get_element(t, 2), brw_imm_ud(0));
-    brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0)));
-    brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-
-    release_tmps(c);
-}
-
-
-void brw_emit_tri_clip( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-   brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
-   brw_clip_tri_init_vertices(c);
-   brw_clip_init_clipmask(c);
-   brw_clip_init_ff_sync(c);
-
-   /* if -ve rhw workaround bit is set,
-      do cliptest */
-   if (p->devinfo->has_negative_rhw_bug) {
-      brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
-              brw_imm_ud(1<<20));
-      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
-      brw_IF(p, BRW_EXECUTE_1);
-      {
-         brw_clip_test(c);
-      }
-      brw_ENDIF(p);
-   }
-   /* Can't push into do_clip_tri because with polygon (or quad)
-    * flatshading, need to apply the flatshade here because we don't
-    * respect the PV when converting to trifan for emit:
-    */
-   if (c->key.contains_flat_varying)
-      brw_clip_tri_flat_shade(c);
-
-   if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) ||
-       (c->key.clip_mode == BRW_CLIPMODE_KERNEL_CLIP))
-      do_clip_tri(c);
-   else
-      maybe_do_clip_tri(c);
-
-   brw_clip_tri_emit_polygon(c);
-
-   /* Send an empty message to kill the thread:
-    */
-   brw_clip_kill_thread(c);
-}
diff --git a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
deleted file mode 100644 (file)
index 65ccf33..0000000
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- Copyright (C) Intel Corp.  2006.  All Rights Reserved.
- Intel funded Tungsten Graphics to
- develop this 3D driver.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice (including the
- next paragraph) shall be included in all copies or substantial
- portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- **********************************************************************/
- /*
-  * Authors:
-  *   Keith Whitwell <keithw@vmware.com>
-  */
-
-#include "main/macros.h"
-#include "main/enums.h"
-#include "program/program.h"
-
-#include "intel_batchbuffer.h"
-
-#include "brw_defines.h"
-#include "brw_context.h"
-#include "brw_clip.h"
-
-
-
-/* This is performed against the original triangles, so no indirection
- * required:
-BZZZT!
- */
-static void compute_tri_direction( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-   struct brw_reg e = c->reg.tmp0;
-   struct brw_reg f = c->reg.tmp1;
-   GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS);
-   struct brw_reg v0 = byte_offset(c->reg.vertex[0], hpos_offset);
-   struct brw_reg v1 = byte_offset(c->reg.vertex[1], hpos_offset);
-   struct brw_reg v2 = byte_offset(c->reg.vertex[2], hpos_offset);
-
-
-   struct brw_reg v0n = get_tmp(c);
-   struct brw_reg v1n = get_tmp(c);
-   struct brw_reg v2n = get_tmp(c);
-
-   /* Convert to NDC.
-    * NOTE: We can't modify the original vertex coordinates,
-    * as it may impact further operations.
-    * So, we have to keep normalized coordinates in temp registers.
-    *
-    * TBD-KC
-    * Try to optimize unnecessary MOV's.
-    */
-   brw_MOV(p, v0n, v0);
-   brw_MOV(p, v1n, v1);
-   brw_MOV(p, v2n, v2);
-
-   brw_clip_project_position(c, v0n);
-   brw_clip_project_position(c, v1n);
-   brw_clip_project_position(c, v2n);
-
-   /* Calculate the vectors of two edges of the triangle:
-    */
-   brw_ADD(p, e, v0n, negate(v2n));
-   brw_ADD(p, f, v1n, negate(v2n));
-
-   /* Take their crossproduct:
-    */
-   brw_set_default_access_mode(p, BRW_ALIGN_16);
-   brw_MUL(p, vec4(brw_null_reg()), brw_swizzle(e, BRW_SWIZZLE_YZXW),
-           brw_swizzle(f, BRW_SWIZZLE_ZXYW));
-   brw_MAC(p, vec4(e),  negate(brw_swizzle(e, BRW_SWIZZLE_ZXYW)),
-           brw_swizzle(f, BRW_SWIZZLE_YZXW));
-   brw_set_default_access_mode(p, BRW_ALIGN_1);
-
-   brw_MUL(p, c->reg.dir, c->reg.dir, vec4(e));
-}
-
-
-static void cull_direction( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-   GLuint conditional;
-
-   assert (!(c->key.fill_ccw == CLIP_CULL &&
-            c->key.fill_cw == CLIP_CULL));
-
-   if (c->key.fill_ccw == CLIP_CULL)
-      conditional = BRW_CONDITIONAL_GE;
-   else
-      conditional = BRW_CONDITIONAL_L;
-
-   brw_CMP(p,
-          vec1(brw_null_reg()),
-          conditional,
-          get_element(c->reg.dir, 2),
-          brw_imm_f(0));
-
-   brw_IF(p, BRW_EXECUTE_1);
-   {
-      brw_clip_kill_thread(c);
-   }
-   brw_ENDIF(p);
-}
-
-
-
-static void copy_bfc( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-   GLuint conditional;
-
-   /* Do we have any colors to copy?
-    */
-   if (!(brw_clip_have_varying(c, VARYING_SLOT_COL0) &&
-         brw_clip_have_varying(c, VARYING_SLOT_BFC0)) &&
-       !(brw_clip_have_varying(c, VARYING_SLOT_COL1) &&
-         brw_clip_have_varying(c, VARYING_SLOT_BFC1)))
-      return;
-
-   /* In some weird degenerate cases we can end up testing the
-    * direction twice, once for culling and once for bfc copying.  Oh
-    * well, that's what you get for setting weird GL state.
-    */
-   if (c->key.copy_bfc_ccw)
-      conditional = BRW_CONDITIONAL_GE;
-   else
-      conditional = BRW_CONDITIONAL_L;
-
-   brw_CMP(p,
-          vec1(brw_null_reg()),
-          conditional,
-          get_element(c->reg.dir, 2),
-          brw_imm_f(0));
-
-   brw_IF(p, BRW_EXECUTE_1);
-   {
-      GLuint i;
-
-      for (i = 0; i < 3; i++) {
-        if (brw_clip_have_varying(c, VARYING_SLOT_COL0) &&
-             brw_clip_have_varying(c, VARYING_SLOT_BFC0))
-           brw_MOV(p,
-                   byte_offset(c->reg.vertex[i],
-                                brw_varying_to_offset(&c->vue_map,
-                                                      VARYING_SLOT_COL0)),
-                   byte_offset(c->reg.vertex[i],
-                                brw_varying_to_offset(&c->vue_map,
-                                                      VARYING_SLOT_BFC0)));
-
-        if (brw_clip_have_varying(c, VARYING_SLOT_COL1) &&
-             brw_clip_have_varying(c, VARYING_SLOT_BFC1))
-           brw_MOV(p,
-                   byte_offset(c->reg.vertex[i],
-                                brw_varying_to_offset(&c->vue_map,
-                                                      VARYING_SLOT_COL1)),
-                   byte_offset(c->reg.vertex[i],
-                                brw_varying_to_offset(&c->vue_map,
-                                                      VARYING_SLOT_BFC1)));
-      }
-   }
-   brw_ENDIF(p);
-}
-
-
-
-
-/*
-  GLfloat iz   = 1.0 / dir.z;
-  GLfloat ac   = dir.x * iz;
-  GLfloat bc   = dir.y * iz;
-  offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
-  offset += MAX2( abs(ac), abs(bc) ) * ctx->Polygon.OffsetFactor;
-  if (ctx->Polygon.OffsetClamp && isfinite(ctx->Polygon.OffsetClamp)) {
-    if (ctx->Polygon.OffsetClamp < 0)
-      offset = MAX2( offset, ctx->Polygon.OffsetClamp );
-    else
-      offset = MIN2( offset, ctx->Polygon.OffsetClamp );
-  }
-  offset *= MRD;
-*/
-static void compute_offset( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-   struct brw_reg off = c->reg.offset;
-   struct brw_reg dir = c->reg.dir;
-
-   brw_math_invert(p, get_element(off, 2), get_element(dir, 2));
-   brw_MUL(p, vec2(off), vec2(dir), get_element(off, 2));
-
-   brw_CMP(p,
-          vec1(brw_null_reg()),
-          BRW_CONDITIONAL_GE,
-          brw_abs(get_element(off, 0)),
-          brw_abs(get_element(off, 1)));
-
-   brw_SEL(p, vec1(off),
-           brw_abs(get_element(off, 0)), brw_abs(get_element(off, 1)));
-   brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-
-   brw_MUL(p, vec1(off), vec1(off), brw_imm_f(c->key.offset_factor));
-   brw_ADD(p, vec1(off), vec1(off), brw_imm_f(c->key.offset_units));
-   if (c->key.offset_clamp && isfinite(c->key.offset_clamp)) {
-      brw_CMP(p,
-              vec1(brw_null_reg()),
-              c->key.offset_clamp < 0 ? BRW_CONDITIONAL_GE : BRW_CONDITIONAL_L,
-              vec1(off),
-              brw_imm_f(c->key.offset_clamp));
-      brw_SEL(p, vec1(off), vec1(off), brw_imm_f(c->key.offset_clamp));
-   }
-}
-
-
-static void merge_edgeflags( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-   struct brw_reg tmp0 = get_element_ud(c->reg.tmp0, 0);
-
-   brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
-   brw_CMP(p,
-          vec1(brw_null_reg()),
-          BRW_CONDITIONAL_EQ,
-          tmp0,
-          brw_imm_ud(_3DPRIM_POLYGON));
-
-   /* Get away with using reg.vertex because we know that this is not
-    * a _3DPRIM_TRISTRIP_REVERSE:
-    */
-   brw_IF(p, BRW_EXECUTE_1);
-   {
-      brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<8));
-      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_EQ);
-      brw_MOV(p, byte_offset(c->reg.vertex[0],
-                             brw_varying_to_offset(&c->vue_map,
-                                                   VARYING_SLOT_EDGE)),
-              brw_imm_f(0));
-      brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-
-      brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<9));
-      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_EQ);
-      brw_MOV(p, byte_offset(c->reg.vertex[2],
-                             brw_varying_to_offset(&c->vue_map,
-                                                   VARYING_SLOT_EDGE)),
-              brw_imm_f(0));
-      brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-   }
-   brw_ENDIF(p);
-}
-
-
-
-static void apply_one_offset( struct brw_clip_compile *c,
-                         struct brw_indirect vert )
-{
-   struct brw_codegen *p = &c->func;
-   GLuint ndc_offset = brw_varying_to_offset(&c->vue_map,
-                                             BRW_VARYING_SLOT_NDC);
-   struct brw_reg z = deref_1f(vert, ndc_offset +
-                              2 * type_sz(BRW_REGISTER_TYPE_F));
-
-   brw_ADD(p, z, z, vec1(c->reg.offset));
-}
-
-
-
-/***********************************************************************
- * Output clipped polygon as an unfilled primitive:
- */
-static void emit_lines(struct brw_clip_compile *c,
-                      bool do_offset)
-{
-   struct brw_codegen *p = &c->func;
-   struct brw_indirect v0 = brw_indirect(0, 0);
-   struct brw_indirect v1 = brw_indirect(1, 0);
-   struct brw_indirect v0ptr = brw_indirect(2, 0);
-   struct brw_indirect v1ptr = brw_indirect(3, 0);
-
-   /* Need a separate loop for offset:
-    */
-   if (do_offset) {
-      brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
-      brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist));
-
-      brw_DO(p, BRW_EXECUTE_1);
-      {
-        brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
-        brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2));
-
-        apply_one_offset(c, v0);
-
-        brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
-         brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_G);
-      }
-      brw_WHILE(p);
-      brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-   }
-
-   /* v1ptr = &inlist[nr_verts]
-    * *v1ptr = v0
-    */
-   brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
-   brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist));
-   brw_ADD(p, get_addr_reg(v1ptr), get_addr_reg(v0ptr), retype(c->reg.nr_verts, BRW_REGISTER_TYPE_UW));
-   brw_ADD(p, get_addr_reg(v1ptr), get_addr_reg(v1ptr), retype(c->reg.nr_verts, BRW_REGISTER_TYPE_UW));
-   brw_MOV(p, deref_1uw(v1ptr, 0), deref_1uw(v0ptr, 0));
-
-   brw_DO(p, BRW_EXECUTE_1);
-   {
-      brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
-      brw_MOV(p, get_addr_reg(v1), deref_1uw(v0ptr, 2));
-      brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2));
-
-      /* draw edge if edgeflag != 0 */
-      brw_CMP(p,
-             vec1(brw_null_reg()), BRW_CONDITIONAL_NZ,
-             deref_1f(v0, brw_varying_to_offset(&c->vue_map,
-                                                 VARYING_SLOT_EDGE)),
-             brw_imm_f(0));
-      brw_IF(p, BRW_EXECUTE_1);
-      {
-        brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE,
-                           (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT)
-                           | URB_WRITE_PRIM_START);
-        brw_clip_emit_vue(c, v1, BRW_URB_WRITE_ALLOCATE_COMPLETE,
-                           (_3DPRIM_LINESTRIP << URB_WRITE_PRIM_TYPE_SHIFT)
-                           | URB_WRITE_PRIM_END);
-      }
-      brw_ENDIF(p);
-
-      brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
-      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
-   }
-   brw_WHILE(p);
-   brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-}
-
-
-
-static void emit_points(struct brw_clip_compile *c,
-                       bool do_offset )
-{
-   struct brw_codegen *p = &c->func;
-
-   struct brw_indirect v0 = brw_indirect(0, 0);
-   struct brw_indirect v0ptr = brw_indirect(2, 0);
-
-   brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
-   brw_MOV(p, get_addr_reg(v0ptr), brw_address(c->reg.inlist));
-
-   brw_DO(p, BRW_EXECUTE_1);
-   {
-      brw_MOV(p, get_addr_reg(v0), deref_1uw(v0ptr, 0));
-      brw_ADD(p, get_addr_reg(v0ptr), get_addr_reg(v0ptr), brw_imm_uw(2));
-
-      /* draw if edgeflag != 0
-       */
-      brw_CMP(p,
-             vec1(brw_null_reg()), BRW_CONDITIONAL_NZ,
-             deref_1f(v0, brw_varying_to_offset(&c->vue_map,
-                                                 VARYING_SLOT_EDGE)),
-             brw_imm_f(0));
-      brw_IF(p, BRW_EXECUTE_1);
-      {
-        if (do_offset)
-           apply_one_offset(c, v0);
-
-        brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE,
-                           (_3DPRIM_POINTLIST << URB_WRITE_PRIM_TYPE_SHIFT)
-                           | URB_WRITE_PRIM_START | URB_WRITE_PRIM_END);
-      }
-      brw_ENDIF(p);
-
-      brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
-      brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_NZ);
-   }
-   brw_WHILE(p);
-   brw_inst_set_pred_control(p->devinfo, brw_last_inst, BRW_PREDICATE_NORMAL);
-}
-
-
-
-
-
-
-
-static void emit_primitives( struct brw_clip_compile *c,
-                            GLuint mode,
-                            bool do_offset )
-{
-   switch (mode) {
-   case CLIP_FILL:
-      brw_clip_tri_emit_polygon(c);
-      break;
-
-   case CLIP_LINE:
-      emit_lines(c, do_offset);
-      break;
-
-   case CLIP_POINT:
-      emit_points(c, do_offset);
-      break;
-
-   case CLIP_CULL:
-      unreachable("not reached");
-   }
-}
-
-
-
-static void emit_unfilled_primitives( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-
-   /* Direction culling has already been done.
-    */
-   if (c->key.fill_ccw != c->key.fill_cw &&
-       c->key.fill_ccw != CLIP_CULL &&
-       c->key.fill_cw != CLIP_CULL)
-   {
-      brw_CMP(p,
-             vec1(brw_null_reg()),
-             BRW_CONDITIONAL_GE,
-             get_element(c->reg.dir, 2),
-             brw_imm_f(0));
-
-      brw_IF(p, BRW_EXECUTE_1);
-      {
-        emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw);
-      }
-      brw_ELSE(p);
-      {
-        emit_primitives(c, c->key.fill_cw, c->key.offset_cw);
-      }
-      brw_ENDIF(p);
-   }
-   else if (c->key.fill_cw != CLIP_CULL) {
-      emit_primitives(c, c->key.fill_cw, c->key.offset_cw);
-   }
-   else if (c->key.fill_ccw != CLIP_CULL) {
-      emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw);
-   }
-}
-
-
-
-
-static void check_nr_verts( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-
-   brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.nr_verts, brw_imm_d(3));
-   brw_IF(p, BRW_EXECUTE_1);
-   {
-      brw_clip_kill_thread(c);
-   }
-   brw_ENDIF(p);
-}
-
-
-void brw_emit_unfilled_clip( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-
-   c->need_direction = ((c->key.offset_ccw || c->key.offset_cw) ||
-                       (c->key.fill_ccw != c->key.fill_cw) ||
-                       c->key.fill_ccw == CLIP_CULL ||
-                       c->key.fill_cw == CLIP_CULL ||
-                       c->key.copy_bfc_cw ||
-                       c->key.copy_bfc_ccw);
-
-   brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
-   brw_clip_tri_init_vertices(c);
-   brw_clip_init_ff_sync(c);
-
-   assert(brw_clip_have_varying(c, VARYING_SLOT_EDGE));
-
-   if (c->key.fill_ccw == CLIP_CULL &&
-       c->key.fill_cw == CLIP_CULL) {
-      brw_clip_kill_thread(c);
-      return;
-   }
-
-   merge_edgeflags(c);
-
-   /* Need to use the inlist indirection here:
-    */
-   if (c->need_direction)
-      compute_tri_direction(c);
-
-   if (c->key.fill_ccw == CLIP_CULL ||
-       c->key.fill_cw == CLIP_CULL)
-      cull_direction(c);
-
-   if (c->key.offset_ccw ||
-       c->key.offset_cw)
-      compute_offset(c);
-
-   if (c->key.copy_bfc_ccw ||
-       c->key.copy_bfc_cw)
-      copy_bfc(c);
-
-   /* Need to do this whether we clip or not:
-    */
-   if (c->key.contains_flat_varying)
-      brw_clip_tri_flat_shade(c);
-
-   brw_clip_init_clipmask(c);
-   brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
-   brw_IF(p, BRW_EXECUTE_1);
-   {
-      brw_clip_init_planes(c);
-      brw_clip_tri(c);
-      check_nr_verts(c);
-   }
-   brw_ENDIF(p);
-
-   emit_unfilled_primitives(c);
-   brw_clip_kill_thread(c);
-}
diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c b/src/mesa/drivers/dri/i965/brw_clip_util.c
deleted file mode 100644 (file)
index e0fdd3d..0000000
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- Copyright (C) Intel Corp.  2006.  All Rights Reserved.
- Intel funded Tungsten Graphics to
- develop this 3D driver.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice (including the
- next paragraph) shall be included in all copies or substantial
- portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- **********************************************************************/
- /*
-  * Authors:
-  *   Keith Whitwell <keithw@vmware.com>
-  */
-
-
-#include "main/macros.h"
-#include "main/enums.h"
-#include "program/program.h"
-
-#include "intel_batchbuffer.h"
-
-#include "brw_defines.h"
-#include "brw_context.h"
-#include "brw_clip.h"
-
-
-
-
-struct brw_reg get_tmp( struct brw_clip_compile *c )
-{
-   struct brw_reg tmp = brw_vec4_grf(c->last_tmp, 0);
-
-   if (++c->last_tmp > c->prog_data.total_grf)
-      c->prog_data.total_grf = c->last_tmp;
-
-   return tmp;
-}
-
-static void release_tmp( struct brw_clip_compile *c, struct brw_reg tmp )
-{
-   if (tmp.nr == c->last_tmp-1)
-      c->last_tmp--;
-}
-
-
-static struct brw_reg make_plane_ud(GLuint x, GLuint y, GLuint z, GLuint w)
-{
-   return brw_imm_ud((w<<24) | (z<<16) | (y<<8) | x);
-}
-
-
-void brw_clip_init_planes( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-
-   if (!c->key.nr_userclip) {
-      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 0), make_plane_ud( 0,    0, 0xff, 1));
-      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 1), make_plane_ud( 0,    0,    1, 1));
-      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 2), make_plane_ud( 0, 0xff,    0, 1));
-      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 3), make_plane_ud( 0,    1,    0, 1));
-      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 4), make_plane_ud(0xff,  0,    0, 1));
-      brw_MOV(p, get_element_ud(c->reg.fixed_planes, 5), make_plane_ud( 1,    0,    0, 1));
-   }
-}
-
-
-
-#define W 3
-
-/* Project 'pos' to screen space (or back again), overwrite with results:
- */
-void brw_clip_project_position(struct brw_clip_compile *c, struct brw_reg pos )
-{
-   struct brw_codegen *p = &c->func;
-
-   /* calc rhw
-    */
-   brw_math_invert(p, get_element(pos, W), get_element(pos, W));
-
-   /* value.xyz *= value.rhw
-    */
-   brw_set_default_access_mode(p, BRW_ALIGN_16);
-   brw_MUL(p, brw_writemask(pos, WRITEMASK_XYZ), pos,
-           brw_swizzle(pos, BRW_SWIZZLE_WWWW));
-   brw_set_default_access_mode(p, BRW_ALIGN_1);
-}
-
-
-static void brw_clip_project_vertex( struct brw_clip_compile *c,
-                                    struct brw_indirect vert_addr )
-{
-   struct brw_codegen *p = &c->func;
-   struct brw_reg tmp = get_tmp(c);
-   GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS);
-   GLuint ndc_offset = brw_varying_to_offset(&c->vue_map,
-                                             BRW_VARYING_SLOT_NDC);
-
-   /* Fixup position.  Extract from the original vertex and re-project
-    * to screen space:
-    */
-   brw_MOV(p, tmp, deref_4f(vert_addr, hpos_offset));
-   brw_clip_project_position(c, tmp);
-   brw_MOV(p, deref_4f(vert_addr, ndc_offset), tmp);
-
-   release_tmp(c, tmp);
-}
-
-
-
-
-/* Interpolate between two vertices and put the result into a0.0.
- * Increment a0.0 accordingly.
- *
- * Beware that dest_ptr can be equal to v0_ptr!
- */
-void brw_clip_interp_vertex( struct brw_clip_compile *c,
-                            struct brw_indirect dest_ptr,
-                            struct brw_indirect v0_ptr, /* from */
-                            struct brw_indirect v1_ptr, /* to */
-                            struct brw_reg t0,
-                            bool force_edgeflag)
-{
-   struct brw_codegen *p = &c->func;
-   struct brw_reg t_nopersp, v0_ndc_copy;
-   GLuint slot;
-
-   /* Just copy the vertex header:
-    */
-   /*
-    * After CLIP stage, only first 256 bits of the VUE are read
-    * back on Ironlake, so needn't change it
-    */
-   brw_copy_indirect_to_indirect(p, dest_ptr, v0_ptr, 1);
-
-
-   /* First handle the 3D and NDC interpolation, in case we
-    * need noperspective interpolation. Doing it early has no
-    * performance impact in any case.
-    */
-
-   /* Take a copy of the v0 NDC coordinates, in case dest == v0. */
-   if (c->key.contains_noperspective_varying) {
-      GLuint offset = brw_varying_to_offset(&c->vue_map,
-                                                 BRW_VARYING_SLOT_NDC);
-      v0_ndc_copy = get_tmp(c);
-      brw_MOV(p, v0_ndc_copy, deref_4f(v0_ptr, offset));
-   }
-
-   /* Compute the new 3D position
-    *
-    * dest_hpos = v0_hpos * (1 - t0) + v1_hpos * t0
-    */
-   {
-      GLuint delta = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS);
-      struct brw_reg tmp = get_tmp(c);
-      brw_MUL(p, vec4(brw_null_reg()), deref_4f(v1_ptr, delta), t0);
-      brw_MAC(p, tmp, negate(deref_4f(v0_ptr, delta)), t0);
-      brw_ADD(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta), tmp);
-      release_tmp(c, tmp);
-   }
-
-   /* Recreate the projected (NDC) coordinate in the new vertex header */
-   brw_clip_project_vertex(c, dest_ptr);
-
-   /* If we have noperspective attributes,
-    * we need to compute the screen-space t
-    */
-   if (c->key.contains_noperspective_varying) {
-      GLuint delta = brw_varying_to_offset(&c->vue_map,
-                                                BRW_VARYING_SLOT_NDC);
-      struct brw_reg tmp = get_tmp(c);
-      t_nopersp = get_tmp(c);
-
-      /* t_nopersp = vec4(v1.xy, dest.xy) */
-      brw_MOV(p, t_nopersp, deref_4f(v1_ptr, delta));
-      brw_MOV(p, tmp, deref_4f(dest_ptr, delta));
-      brw_set_default_access_mode(p, BRW_ALIGN_16);
-      brw_MOV(p,
-              brw_writemask(t_nopersp, WRITEMASK_ZW),
-              brw_swizzle(tmp, BRW_SWIZZLE_XYXY));
-
-      /* t_nopersp = vec4(v1.xy, dest.xy) - v0.xyxy */
-      brw_ADD(p, t_nopersp, t_nopersp,
-              negate(brw_swizzle(v0_ndc_copy, BRW_SWIZZLE_XYXY)));
-
-      /* Add the absolute values of the X and Y deltas so that if
-       * the points aren't in the same place on the screen we get
-       * nonzero values to divide.
-       *
-       * After that, we have vert1 - vert0 in t_nopersp.x and
-       * vertnew - vert0 in t_nopersp.y
-       *
-       * t_nopersp = vec2(|v1.x  -v0.x| + |v1.y  -v0.y|,
-       *                  |dest.x-v0.x| + |dest.y-v0.y|)
-       */
-      brw_ADD(p,
-              brw_writemask(t_nopersp, WRITEMASK_XY),
-              brw_abs(brw_swizzle(t_nopersp, BRW_SWIZZLE_XZXZ)),
-              brw_abs(brw_swizzle(t_nopersp, BRW_SWIZZLE_YWYW)));
-      brw_set_default_access_mode(p, BRW_ALIGN_1);
-
-      /* If the points are in the same place, just substitute a
-       * value to avoid divide-by-zero
-       */
-      brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ,
-              vec1(t_nopersp),
-              brw_imm_f(0));
-      brw_IF(p, BRW_EXECUTE_1);
-      brw_MOV(p, t_nopersp, brw_imm_vf4(brw_float_to_vf(1.0),
-                                        brw_float_to_vf(0.0),
-                                        brw_float_to_vf(0.0),
-                                        brw_float_to_vf(0.0)));
-      brw_ENDIF(p);
-
-      /* Now compute t_nopersp = t_nopersp.y/t_nopersp.x and broadcast it. */
-      brw_math_invert(p, get_element(t_nopersp, 0), get_element(t_nopersp, 0));
-      brw_MUL(p, vec1(t_nopersp), vec1(t_nopersp),
-            vec1(suboffset(t_nopersp, 1)));
-      brw_set_default_access_mode(p, BRW_ALIGN_16);
-      brw_MOV(p, t_nopersp, brw_swizzle(t_nopersp, BRW_SWIZZLE_XXXX));
-      brw_set_default_access_mode(p, BRW_ALIGN_1);
-
-      release_tmp(c, tmp);
-      release_tmp(c, v0_ndc_copy);
-   }
-
-   /* Now we can iterate over each attribute
-    * (could be done in pairs?)
-    */
-   for (slot = 0; slot < c->vue_map.num_slots; slot++) {
-      int varying = c->vue_map.slot_to_varying[slot];
-      GLuint delta = brw_vue_slot_to_offset(slot);
-
-      /* HPOS, NDC already handled above */
-      if (varying == VARYING_SLOT_POS || varying == BRW_VARYING_SLOT_NDC)
-         continue;
-
-
-      if (varying == VARYING_SLOT_EDGE) {
-        if (force_edgeflag)
-           brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(1));
-        else
-           brw_MOV(p, deref_4f(dest_ptr, delta), deref_4f(v0_ptr, delta));
-      } else if (varying == VARYING_SLOT_PSIZ) {
-         /* PSIZ doesn't need interpolation because it isn't used by the
-          * fragment shader.
-          */
-      } else if (varying < VARYING_SLOT_MAX) {
-        /* This is a true vertex result (and not a special value for the VUE
-         * header), so interpolate:
-         *
-         *        New = attr0 + t*attr1 - t*attr0
-          *
-          * Unless the attribute is flat shaded -- in which case just copy
-          * from one of the sources (doesn't matter which; already copied from pv)
-         */
-         GLuint interp = c->key.interp_mode[slot];
-
-         if (interp != INTERP_MODE_FLAT) {
-            struct brw_reg tmp = get_tmp(c);
-            struct brw_reg t =
-               interp == INTERP_MODE_NOPERSPECTIVE ? t_nopersp : t0;
-
-            brw_MUL(p,
-                  vec4(brw_null_reg()),
-                  deref_4f(v1_ptr, delta),
-                  t);
-
-            brw_MAC(p,
-                  tmp,
-                  negate(deref_4f(v0_ptr, delta)),
-                  t);
-
-            brw_ADD(p,
-                  deref_4f(dest_ptr, delta),
-                  deref_4f(v0_ptr, delta),
-                  tmp);
-
-            release_tmp(c, tmp);
-         }
-         else {
-            brw_MOV(p,
-                  deref_4f(dest_ptr, delta),
-                  deref_4f(v0_ptr, delta));
-         }
-      }
-   }
-
-   if (c->vue_map.num_slots % 2) {
-      GLuint delta = brw_vue_slot_to_offset(c->vue_map.num_slots);
-
-      brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0));
-   }
-
-   if (c->key.contains_noperspective_varying)
-      release_tmp(c, t_nopersp);
-}
-
-void brw_clip_emit_vue(struct brw_clip_compile *c,
-                      struct brw_indirect vert,
-                       enum brw_urb_write_flags flags,
-                      GLuint header)
-{
-   struct brw_codegen *p = &c->func;
-   bool allocate = flags & BRW_URB_WRITE_ALLOCATE;
-
-   brw_clip_ff_sync(c);
-
-   /* Any URB entry that is allocated must subsequently be used or discarded,
-    * so it doesn't make sense to mark EOT and ALLOCATE at the same time.
-    */
-   assert(!(allocate && (flags & BRW_URB_WRITE_EOT)));
-
-   /* Copy the vertex from vertn into m1..mN+1:
-    */
-   brw_copy_from_indirect(p, brw_message_reg(1), vert, c->nr_regs);
-
-   /* Overwrite PrimType and PrimStart in the message header, for
-    * each vertex in turn:
-    */
-   brw_MOV(p, get_element_ud(c->reg.R0, 2), brw_imm_ud(header));
-
-
-   /* Send each vertex as a separate write to the urb.  This
-    * is different to the concept in brw_sf_emit.c, where
-    * subsequent writes are used to build up a single urb
-    * entry.  Each of these writes instantiates a separate
-    * urb entry - (I think... what about 'allocate'?)
-    */
-   brw_urb_WRITE(p,
-                allocate ? c->reg.R0 : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
-                0,
-                c->reg.R0,
-                 flags,
-                c->nr_regs + 1, /* msg length */
-                allocate ? 1 : 0, /* response_length */
-                0,             /* urb offset */
-                BRW_URB_SWIZZLE_NONE);
-}
-
-
-
-void brw_clip_kill_thread(struct brw_clip_compile *c)
-{
-   struct brw_codegen *p = &c->func;
-
-   brw_clip_ff_sync(c);
-   /* Send an empty message to kill the thread and release any
-    * allocated urb entry:
-    */
-   brw_urb_WRITE(p,
-                retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
-                0,
-                c->reg.R0,
-                 BRW_URB_WRITE_UNUSED | BRW_URB_WRITE_EOT_COMPLETE,
-                1,             /* msg len */
-                0,             /* response len */
-                0,
-                BRW_URB_SWIZZLE_NONE);
-}
-
-
-
-
-struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c )
-{
-   return brw_address(c->reg.fixed_planes);
-}
-
-
-struct brw_reg brw_clip_plane_stride( struct brw_clip_compile *c )
-{
-   if (c->key.nr_userclip) {
-      return brw_imm_uw(16);
-   }
-   else {
-      return brw_imm_uw(4);
-   }
-}
-
-
-/* Distribute flatshaded attributes from provoking vertex prior to
- * clipping.
- */
-void brw_clip_copy_flatshaded_attributes( struct brw_clip_compile *c,
-                          GLuint to, GLuint from )
-{
-   struct brw_codegen *p = &c->func;
-
-   for (int i = 0; i < c->vue_map.num_slots; i++) {
-      if (c->key.interp_mode[i] == INTERP_MODE_FLAT) {
-         brw_MOV(p,
-                 byte_offset(c->reg.vertex[to], brw_vue_slot_to_offset(i)),
-                 byte_offset(c->reg.vertex[from], brw_vue_slot_to_offset(i)));
-      }
-   }
-}
-
-
-
-void brw_clip_init_clipmask( struct brw_clip_compile *c )
-{
-   struct brw_codegen *p = &c->func;
-   struct brw_reg incoming = get_element_ud(c->reg.R0, 2);
-
-   /* Shift so that lowest outcode bit is rightmost:
-    */
-   brw_SHR(p, c->reg.planemask, incoming, brw_imm_ud(26));
-
-   if (c->key.nr_userclip) {
-      struct brw_reg tmp = retype(vec1(get_tmp(c)), BRW_REGISTER_TYPE_UD);
-
-      /* Rearrange userclip outcodes so that they come directly after
-       * the fixed plane bits.
-       */
-      if (p->devinfo->gen == 5 || p->devinfo->is_g4x)
-         brw_AND(p, tmp, incoming, brw_imm_ud(0xff<<14));
-      else
-         brw_AND(p, tmp, incoming, brw_imm_ud(0x3f<<14));
-
-      brw_SHR(p, tmp, tmp, brw_imm_ud(8));
-      brw_OR(p, c->reg.planemask, c->reg.planemask, tmp);
-
-      release_tmp(c, tmp);
-   }
-}
-
-void brw_clip_ff_sync(struct brw_clip_compile *c)
-{
-    struct brw_codegen *p = &c->func;
-
-    if (p->devinfo->gen == 5) {
-        brw_AND(p, brw_null_reg(), c->reg.ff_sync, brw_imm_ud(0x1));
-        brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_Z);
-        brw_IF(p, BRW_EXECUTE_1);
-        {
-            brw_OR(p, c->reg.ff_sync, c->reg.ff_sync, brw_imm_ud(0x1));
-            brw_ff_sync(p,
-                       c->reg.R0,
-                       0,
-                       c->reg.R0,
-                       1, /* allocate */
-                       1, /* response length */
-                       0 /* eot */);
-        }
-        brw_ENDIF(p);
-        brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
-    }
-}
-
-void brw_clip_init_ff_sync(struct brw_clip_compile *c)
-{
-    struct brw_codegen *p = &c->func;
-
-    if (p->devinfo->gen == 5) {
-        brw_MOV(p, c->reg.ff_sync, brw_imm_ud(0));
-    }
-}
index 5e7273891705ab034d5c286e06dad18aa8d19306..22a84e6197ca011c1c0409140a019fbaf934d7d6 100644 (file)
@@ -325,13 +325,6 @@ struct brw_program {
 };
 
 
-struct brw_clip_prog_data {
-   GLuint curb_read_length;    /* user planes? */
-   GLuint clip_mode;
-   GLuint urb_read_length;
-   GLuint total_grf;
-};
-
 struct brw_ff_gs_prog_data {
    GLuint urb_read_length;
    GLuint total_grf;
index 7ce47ac75b98b89305032274610ae7dc09ddd431..ace83ef57af6437316879464d0297613dd0b6941 100644 (file)
 #define BRW_CLIP_API_OGL     0
 #define BRW_CLIP_API_DX      1
 
-#define BRW_CLIPMODE_NORMAL              0
-#define BRW_CLIPMODE_CLIP_ALL            1
-#define BRW_CLIPMODE_CLIP_NON_REJECTED   2
-#define BRW_CLIPMODE_REJECT_ALL          3
-#define BRW_CLIPMODE_ACCEPT_ALL          4
-#define BRW_CLIPMODE_KERNEL_CLIP         5
-
 #define BRW_CLIP_NDCSPACE     0
 #define BRW_CLIP_SCREENSPACE  1