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@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 
release_tmps(struct brw_clip_compile * c)44 static void release_tmps( struct brw_clip_compile *c )
45 {
46    c->last_tmp = c->first_tmp;
47 }
48 
49 
brw_clip_tri_alloc_regs(struct brw_clip_compile * c,GLuint nr_verts)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 
brw_clip_tri_init_vertices(struct brw_clip_compile * c)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 
brw_clip_tri_flat_shade(struct brw_clip_compile * c)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  */
brw_clip_tri(struct brw_clip_compile * c)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 
brw_clip_tri_emit_polygon(struct brw_clip_compile * c)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 
do_clip_tri(struct brw_clip_compile * c)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 
maybe_do_clip_tri(struct brw_clip_compile * c)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 
brw_clip_test(struct brw_clip_compile * c)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 
brw_emit_tri_clip(struct brw_clip_compile * c)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