Home | History | Annotate | Download | only in i965
      1 /*
      2  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
      3  Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
      4  develop this 3D driver.
      5 
      6  Permission is hereby granted, free of charge, to any person obtaining
      7  a copy of this software and associated documentation files (the
      8  "Software"), to deal in the Software without restriction, including
      9  without limitation the rights to use, copy, modify, merge, publish,
     10  distribute, sublicense, and/or sell copies of the Software, and to
     11  permit persons to whom the Software is furnished to do so, subject to
     12  the following conditions:
     13 
     14  The above copyright notice and this permission notice (including the
     15  next paragraph) shall be included in all copies or substantial
     16  portions of the Software.
     17 
     18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     19  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     21  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
     22  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     23  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     24  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25 
     26  **********************************************************************/
     27  /*
     28   * Authors:
     29   *   Keith Whitwell <keith (at) tungstengraphics.com>
     30   */
     31 
     32 #include "main/glheader.h"
     33 #include "main/macros.h"
     34 #include "main/enums.h"
     35 #include "program/program.h"
     36 
     37 #include "intel_batchbuffer.h"
     38 
     39 #include "brw_defines.h"
     40 #include "brw_context.h"
     41 #include "brw_eu.h"
     42 #include "brw_clip.h"
     43 
     44 static void release_tmps( struct brw_clip_compile *c )
     45 {
     46    c->last_tmp = c->first_tmp;
     47 }
     48 
     49 
     50 void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
     51 			      GLuint nr_verts )
     52 {
     53    struct intel_context *intel = &c->func.brw->intel;
     54    GLuint i = 0,j;
     55 
     56    /* Register usage is static, precompute here:
     57     */
     58    c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
     59 
     60    if (c->key.nr_userclip) {
     61       c->reg.fixed_planes = brw_vec4_grf(i, 0);
     62       i += (6 + c->key.nr_userclip + 1) / 2;
     63 
     64       c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2;
     65    }
     66    else
     67       c->prog_data.curb_read_length = 0;
     68 
     69 
     70    /* Payload vertices plus space for more generated vertices:
     71     */
     72    for (j = 0; j < nr_verts; j++) {
     73       c->reg.vertex[j] = brw_vec4_grf(i, 0);
     74       i += c->nr_regs;
     75    }
     76 
     77    if (c->vue_map.num_slots % 2) {
     78       /* The VUE has an odd number of slots so the last register is only half
     79        * used.  Fill the second half with zero.
     80        */
     81       for (j = 0; j < 3; j++) {
     82 	 GLuint delta = brw_vue_slot_to_offset(c->vue_map.num_slots);
     83 
     84 	 brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0));
     85       }
     86    }
     87 
     88    c->reg.t          = brw_vec1_grf(i, 0);
     89    c->reg.loopcount  = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_D);
     90    c->reg.nr_verts   = retype(brw_vec1_grf(i, 2), BRW_REGISTER_TYPE_UD);
     91    c->reg.planemask  = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
     92    c->reg.plane_equation = brw_vec4_grf(i, 4);
     93    i++;
     94 
     95    c->reg.dpPrev     = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
     96    c->reg.dp         = brw_vec1_grf(i, 4);
     97    i++;
     98 
     99    c->reg.inlist     = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
    100    i++;
    101 
    102    c->reg.outlist    = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
    103    i++;
    104 
    105    c->reg.freelist   = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
    106    i++;
    107 
    108    if (!c->key.nr_userclip) {
    109       c->reg.fixed_planes = brw_vec8_grf(i, 0);
    110       i++;
    111    }
    112 
    113    if (c->key.do_unfilled) {
    114       c->reg.dir     = brw_vec4_grf(i, 0);
    115       c->reg.offset  = brw_vec4_grf(i, 4);
    116       i++;
    117       c->reg.tmp0    = brw_vec4_grf(i, 0);
    118       c->reg.tmp1    = brw_vec4_grf(i, 4);
    119       i++;
    120    }
    121 
    122    if (intel->needs_ff_sync) {
    123       c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
    124       i++;
    125    }
    126 
    127    c->first_tmp = i;
    128    c->last_tmp = i;
    129 
    130    c->prog_data.urb_read_length = c->nr_regs; /* ? */
    131    c->prog_data.total_grf = i;
    132 }
    133 
    134 
    135 
    136 void brw_clip_tri_init_vertices( struct brw_clip_compile *c )
    137 {
    138    struct brw_compile *p = &c->func;
    139    struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
    140 
    141    /* Initial list of indices for incoming vertexes:
    142     */
    143    brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
    144    brw_CMP(p,
    145 	   vec1(brw_null_reg()),
    146 	   BRW_CONDITIONAL_EQ,
    147 	   tmp0,
    148 	   brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE));
    149 
    150    /* XXX: Is there an easier way to do this?  Need to reverse every
    151     * second tristrip element:  Can ignore sometimes?
    152     */
    153    brw_IF(p, BRW_EXECUTE_1);
    154    {
    155       brw_MOV(p, get_element(c->reg.inlist, 0),  brw_address(c->reg.vertex[1]) );
    156       brw_MOV(p, get_element(c->reg.inlist, 1),  brw_address(c->reg.vertex[0]) );
    157       if (c->need_direction)
    158 	 brw_MOV(p, c->reg.dir, brw_imm_f(-1));
    159    }
    160    brw_ELSE(p);
    161    {
    162       brw_MOV(p, get_element(c->reg.inlist, 0),  brw_address(c->reg.vertex[0]) );
    163       brw_MOV(p, get_element(c->reg.inlist, 1),  brw_address(c->reg.vertex[1]) );
    164       if (c->need_direction)
    165 	 brw_MOV(p, c->reg.dir, brw_imm_f(1));
    166    }
    167    brw_ENDIF(p);
    168 
    169    brw_MOV(p, get_element(c->reg.inlist, 2),  brw_address(c->reg.vertex[2]) );
    170    brw_MOV(p, brw_vec8_grf(c->reg.outlist.nr, 0), brw_imm_f(0));
    171    brw_MOV(p, c->reg.nr_verts, brw_imm_ud(3));
    172 }
    173 
    174 
    175 
    176 void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
    177 {
    178    struct brw_compile *p = &c->func;
    179    struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
    180 
    181    brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
    182    brw_CMP(p,
    183 	   vec1(brw_null_reg()),
    184 	   BRW_CONDITIONAL_EQ,
    185 	   tmp0,
    186 	   brw_imm_ud(_3DPRIM_POLYGON));
    187 
    188    brw_IF(p, BRW_EXECUTE_1);
    189    {
    190       brw_clip_copy_colors(c, 1, 0);
    191       brw_clip_copy_colors(c, 2, 0);
    192    }
    193    brw_ELSE(p);
    194    {
    195       if (c->key.pv_first) {
    196 	 brw_CMP(p,
    197 		 vec1(brw_null_reg()),
    198 		 BRW_CONDITIONAL_EQ,
    199 		 tmp0,
    200 		 brw_imm_ud(_3DPRIM_TRIFAN));
    201 	 brw_IF(p, BRW_EXECUTE_1);
    202 	 {
    203 	    brw_clip_copy_colors(c, 0, 1);
    204 	    brw_clip_copy_colors(c, 2, 1);
    205 	 }
    206 	 brw_ELSE(p);
    207 	 {
    208 	    brw_clip_copy_colors(c, 1, 0);
    209 	    brw_clip_copy_colors(c, 2, 0);
    210 	 }
    211 	 brw_ENDIF(p);
    212       }
    213       else {
    214          brw_clip_copy_colors(c, 0, 2);
    215          brw_clip_copy_colors(c, 1, 2);
    216       }
    217    }
    218    brw_ENDIF(p);
    219 }
    220 
    221 
    222 
    223 /* Use mesa's clipping algorithms, translated to GEN4 assembly.
    224  */
    225 void brw_clip_tri( struct brw_clip_compile *c )
    226 {
    227    struct brw_compile *p = &c->func;
    228    struct brw_indirect vtx = brw_indirect(0, 0);
    229    struct brw_indirect vtxPrev = brw_indirect(1, 0);
    230    struct brw_indirect vtxOut = brw_indirect(2, 0);
    231    struct brw_indirect plane_ptr = brw_indirect(3, 0);
    232    struct brw_indirect inlist_ptr = brw_indirect(4, 0);
    233    struct brw_indirect outlist_ptr = brw_indirect(5, 0);
    234    struct brw_indirect freelist_ptr = brw_indirect(6, 0);
    235    GLuint hpos_offset = brw_vert_result_to_offset(&c->vue_map,
    236                                                   VERT_RESULT_HPOS);
    237 
    238    brw_MOV(p, get_addr_reg(vtxPrev),     brw_address(c->reg.vertex[2]) );
    239    brw_MOV(p, get_addr_reg(plane_ptr),   brw_clip_plane0_address(c));
    240    brw_MOV(p, get_addr_reg(inlist_ptr),  brw_address(c->reg.inlist));
    241    brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
    242 
    243    brw_MOV(p, get_addr_reg(freelist_ptr), brw_address(c->reg.vertex[3]) );
    244 
    245    brw_DO(p, BRW_EXECUTE_1);
    246    {
    247       /* if (planemask & 1)
    248        */
    249       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
    250       brw_AND(p, vec1(brw_null_reg()), c->reg.planemask, brw_imm_ud(1));
    251 
    252       brw_IF(p, BRW_EXECUTE_1);
    253       {
    254 	 /* vtxOut = freelist_ptr++
    255 	  */
    256 	 brw_MOV(p, get_addr_reg(vtxOut),       get_addr_reg(freelist_ptr) );
    257 	 brw_ADD(p, get_addr_reg(freelist_ptr), get_addr_reg(freelist_ptr), brw_imm_uw(c->nr_regs * REG_SIZE));
    258 
    259 	 if (c->key.nr_userclip)
    260 	    brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
    261 	 else
    262 	    brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
    263 
    264 	 brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
    265 	 brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0));
    266 
    267 	 brw_DO(p, BRW_EXECUTE_1);
    268 	 {
    269 	    /* vtx = *input_ptr;
    270 	     */
    271 	    brw_MOV(p, get_addr_reg(vtx), deref_1uw(inlist_ptr, 0));
    272 
    273 	    /* IS_NEGATIVE(prev) */
    274 	    brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
    275 	    brw_DP4(p, vec4(c->reg.dpPrev), deref_4f(vtxPrev, hpos_offset), c->reg.plane_equation);
    276 	    brw_IF(p, BRW_EXECUTE_1);
    277 	    {
    278 	       /* IS_POSITIVE(next)
    279 		*/
    280 	       brw_set_conditionalmod(p, BRW_CONDITIONAL_GE);
    281 	       brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, hpos_offset), c->reg.plane_equation);
    282 	       brw_IF(p, BRW_EXECUTE_1);
    283 	       {
    284 
    285 		  /* Coming back in.
    286 		   */
    287 		  brw_ADD(p, c->reg.t, c->reg.dpPrev, negate(c->reg.dp));
    288 		  brw_math_invert(p, c->reg.t, c->reg.t);
    289 		  brw_MUL(p, c->reg.t, c->reg.t, c->reg.dpPrev);
    290 
    291 		  /* If (vtxOut == 0) vtxOut = vtxPrev
    292 		   */
    293 		  brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
    294 		  brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtxPrev) );
    295 		  brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    296 
    297 		  brw_clip_interp_vertex(c, vtxOut, vtxPrev, vtx, c->reg.t, false);
    298 
    299 		  /* *outlist_ptr++ = vtxOut;
    300 		   * nr_verts++;
    301 		   * vtxOut = 0;
    302 		   */
    303 		  brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
    304 		  brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
    305 		  brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
    306 		  brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
    307 	       }
    308 	       brw_ENDIF(p);
    309 
    310 	    }
    311 	    brw_ELSE(p);
    312 	    {
    313 	       /* *outlist_ptr++ = vtxPrev;
    314 		* nr_verts++;
    315 		*/
    316 	       brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxPrev));
    317 	       brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
    318 	       brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
    319 
    320 	       /* IS_NEGATIVE(next)
    321 		*/
    322 	       brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
    323 	       brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, hpos_offset), c->reg.plane_equation);
    324 	       brw_IF(p, BRW_EXECUTE_1);
    325 	       {
    326 		  /* Going out of bounds.  Avoid division by zero as we
    327 		   * know dp != dpPrev from DIFFERENT_SIGNS, above.
    328 		   */
    329 		  brw_ADD(p, c->reg.t, c->reg.dp, negate(c->reg.dpPrev));
    330 		  brw_math_invert(p, c->reg.t, c->reg.t);
    331 		  brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp);
    332 
    333 		  /* If (vtxOut == 0) vtxOut = vtx
    334 		   */
    335 		  brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
    336 		  brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtx) );
    337 		  brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    338 
    339 		  brw_clip_interp_vertex(c, vtxOut, vtx, vtxPrev, c->reg.t, true);
    340 
    341 		  /* *outlist_ptr++ = vtxOut;
    342 		   * nr_verts++;
    343 		   * vtxOut = 0;
    344 		   */
    345 		  brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
    346 		  brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
    347 		  brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
    348 		  brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
    349 	       }
    350 	       brw_ENDIF(p);
    351 	    }
    352 	    brw_ENDIF(p);
    353 
    354 	    /* vtxPrev = vtx;
    355 	     * inlist_ptr++;
    356 	     */
    357 	    brw_MOV(p, get_addr_reg(vtxPrev), get_addr_reg(vtx));
    358 	    brw_ADD(p, get_addr_reg(inlist_ptr), get_addr_reg(inlist_ptr), brw_imm_uw(sizeof(short)));
    359 
    360 	    /* while (--loopcount != 0)
    361 	     */
    362 	    brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
    363 	    brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
    364 	 }
    365 	 brw_WHILE(p);
    366 
    367 	 /* vtxPrev = *(outlist_ptr-1)  OR: outlist[nr_verts-1]
    368 	  * inlist = outlist
    369 	  * inlist_ptr = &inlist[0]
    370 	  * outlist_ptr = &outlist[0]
    371 	  */
    372 	 brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_w(-2));
    373 	 brw_MOV(p, get_addr_reg(vtxPrev), deref_1uw(outlist_ptr, 0));
    374 	 brw_MOV(p, brw_vec8_grf(c->reg.inlist.nr, 0), brw_vec8_grf(c->reg.outlist.nr, 0));
    375 	 brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist));
    376 	 brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
    377       }
    378       brw_ENDIF(p);
    379 
    380       /* plane_ptr++;
    381        */
    382       brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
    383 
    384       /* nr_verts >= 3
    385        */
    386       brw_CMP(p,
    387 	      vec1(brw_null_reg()),
    388 	      BRW_CONDITIONAL_GE,
    389 	      c->reg.nr_verts,
    390 	      brw_imm_ud(3));
    391 
    392       /* && (planemask>>=1) != 0
    393        */
    394       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
    395       brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
    396    }
    397    brw_WHILE(p);
    398 }
    399 
    400 
    401 
    402 void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
    403 {
    404    struct brw_compile *p = &c->func;
    405 
    406    /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
    407     */
    408    brw_set_conditionalmod(p, BRW_CONDITIONAL_G);
    409    brw_ADD(p,
    410 	   c->reg.loopcount,
    411 	   c->reg.nr_verts,
    412 	   brw_imm_d(-2));
    413 
    414    brw_IF(p, BRW_EXECUTE_1);
    415    {
    416       struct brw_indirect v0 = brw_indirect(0, 0);
    417       struct brw_indirect vptr = brw_indirect(1, 0);
    418 
    419       brw_MOV(p, get_addr_reg(vptr), brw_address(c->reg.inlist));
    420       brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
    421 
    422       brw_clip_emit_vue(c, v0, 1, 0,
    423                         ((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
    424                          | URB_WRITE_PRIM_START));
    425 
    426       brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
    427       brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
    428 
    429       brw_DO(p, BRW_EXECUTE_1);
    430       {
    431 	 brw_clip_emit_vue(c, v0, 1, 0,
    432                            (_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT));
    433 
    434 	 brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
    435 	 brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
    436 
    437 	 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
    438 	 brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
    439       }
    440       brw_WHILE(p);
    441 
    442       brw_clip_emit_vue(c, v0, 0, 1,
    443                         ((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
    444                          | URB_WRITE_PRIM_END));
    445    }
    446    brw_ENDIF(p);
    447 }
    448 
    449 static void do_clip_tri( struct brw_clip_compile *c )
    450 {
    451    brw_clip_init_planes(c);
    452 
    453    brw_clip_tri(c);
    454 }
    455 
    456 
    457 static void maybe_do_clip_tri( struct brw_clip_compile *c )
    458 {
    459    struct brw_compile *p = &c->func;
    460 
    461    brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
    462    brw_IF(p, BRW_EXECUTE_1);
    463    {
    464       do_clip_tri(c);
    465    }
    466    brw_ENDIF(p);
    467 }
    468 
    469 static void brw_clip_test( struct brw_clip_compile *c )
    470 {
    471     struct brw_reg t = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
    472     struct brw_reg t1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
    473     struct brw_reg t2 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
    474     struct brw_reg t3 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
    475 
    476     struct brw_reg v0 = get_tmp(c);
    477     struct brw_reg v1 = get_tmp(c);
    478     struct brw_reg v2 = get_tmp(c);
    479 
    480     struct brw_indirect vt0 = brw_indirect(0, 0);
    481     struct brw_indirect vt1 = brw_indirect(1, 0);
    482     struct brw_indirect vt2 = brw_indirect(2, 0);
    483 
    484     struct brw_compile *p = &c->func;
    485     struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
    486 
    487     GLuint hpos_offset = brw_vert_result_to_offset(&c->vue_map,
    488                                                    VERT_RESULT_HPOS);
    489 
    490     brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0]));
    491     brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1]));
    492     brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2]));
    493     brw_MOV(p, v0, deref_4f(vt0, hpos_offset));
    494     brw_MOV(p, v1, deref_4f(vt1, hpos_offset));
    495     brw_MOV(p, v2, deref_4f(vt2, hpos_offset));
    496     brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f));
    497 
    498     /* test nearz, xmin, ymin plane */
    499     /* clip.xyz < -clip.w */
    500     brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, negate(get_element(v0, 3)));
    501     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    502     brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, negate(get_element(v1, 3)));
    503     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    504     brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, negate(get_element(v2, 3)));
    505     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    506 
    507     /* All vertices are outside of a plane, rejected */
    508     brw_AND(p, t, t1, t2);
    509     brw_AND(p, t, t, t3);
    510     brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
    511     brw_OR(p, tmp0, tmp0, get_element(t, 2));
    512     brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
    513     brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
    514     brw_IF(p, BRW_EXECUTE_1);
    515     {
    516         brw_clip_kill_thread(c);
    517     }
    518     brw_ENDIF(p);
    519     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    520 
    521     /* some vertices are inside a plane, some are outside,need to clip */
    522     brw_XOR(p, t, t1, t2);
    523     brw_XOR(p, t1, t2, t3);
    524     brw_OR(p, t, t, t1);
    525     brw_AND(p, t, t, brw_imm_ud(0x1));
    526     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
    527             get_element(t, 0), brw_imm_ud(0));
    528     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5)));
    529     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    530     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
    531             get_element(t, 1), brw_imm_ud(0));
    532     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3)));
    533     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    534     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
    535             get_element(t, 2), brw_imm_ud(0));
    536     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1)));
    537     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    538 
    539     /* test farz, xmax, ymax plane */
    540     /* clip.xyz > clip.w */
    541     brw_CMP(p, t1, BRW_CONDITIONAL_G, v0, get_element(v0, 3));
    542     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    543     brw_CMP(p, t2, BRW_CONDITIONAL_G, v1, get_element(v1, 3));
    544     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    545     brw_CMP(p, t3, BRW_CONDITIONAL_G, v2, get_element(v2, 3));
    546     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    547 
    548     /* All vertices are outside of a plane, rejected */
    549     brw_AND(p, t, t1, t2);
    550     brw_AND(p, t, t, t3);
    551     brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
    552     brw_OR(p, tmp0, tmp0, get_element(t, 2));
    553     brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
    554     brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
    555     brw_IF(p, BRW_EXECUTE_1);
    556     {
    557         brw_clip_kill_thread(c);
    558     }
    559     brw_ENDIF(p);
    560     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    561 
    562     /* some vertices are inside a plane, some are outside,need to clip */
    563     brw_XOR(p, t, t1, t2);
    564     brw_XOR(p, t1, t2, t3);
    565     brw_OR(p, t, t, t1);
    566     brw_AND(p, t, t, brw_imm_ud(0x1));
    567     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
    568             get_element(t, 0), brw_imm_ud(0));
    569     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4)));
    570     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    571     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
    572             get_element(t, 1), brw_imm_ud(0));
    573     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2)));
    574     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    575     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
    576             get_element(t, 2), brw_imm_ud(0));
    577     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0)));
    578     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    579 
    580     release_tmps(c);
    581 }
    582 
    583 
    584 void brw_emit_tri_clip( struct brw_clip_compile *c )
    585 {
    586    struct brw_compile *p = &c->func;
    587    struct brw_context *brw = p->brw;
    588    brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
    589    brw_clip_tri_init_vertices(c);
    590    brw_clip_init_clipmask(c);
    591    brw_clip_init_ff_sync(c);
    592 
    593    /* if -ve rhw workaround bit is set,
    594       do cliptest */
    595    if (brw->has_negative_rhw_bug) {
    596       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
    597       brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
    598               brw_imm_ud(1<<20));
    599       brw_IF(p, BRW_EXECUTE_1);
    600       {
    601          brw_clip_test(c);
    602       }
    603       brw_ENDIF(p);
    604    }
    605    /* Can't push into do_clip_tri because with polygon (or quad)
    606     * flatshading, need to apply the flatshade here because we don't
    607     * respect the PV when converting to trifan for emit:
    608     */
    609    if (c->key.do_flat_shading)
    610       brw_clip_tri_flat_shade(c);
    611 
    612    if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) ||
    613        (c->key.clip_mode == BRW_CLIPMODE_KERNEL_CLIP))
    614       do_clip_tri(c);
    615    else
    616       maybe_do_clip_tri(c);
    617 
    618    brw_clip_tri_emit_polygon(c);
    619 
    620    /* Send an empty message to kill the thread:
    621     */
    622    brw_clip_kill_thread(c);
    623 }
    624