Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / i965 / brw_clip_tri.c
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
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->nr_attrs & 1) {
78       for (j = 0; j < 3; j++) {
79          GLuint delta = c->offset[c->idx_to_attr[c->nr_attrs - 1]] + ATTR_SIZE;
80
81          brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0));
82       }
83    }
84
85    c->reg.t          = brw_vec1_grf(i, 0);
86    c->reg.loopcount  = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_D);
87    c->reg.nr_verts   = retype(brw_vec1_grf(i, 2), BRW_REGISTER_TYPE_UD);
88    c->reg.planemask  = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
89    c->reg.plane_equation = brw_vec4_grf(i, 4);
90    i++;
91
92    c->reg.dpPrev     = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
93    c->reg.dp         = brw_vec1_grf(i, 4);
94    i++;
95
96    c->reg.inlist     = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
97    i++;
98
99    c->reg.outlist    = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
100    i++;
101
102    c->reg.freelist   = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
103    i++;
104
105    if (!c->key.nr_userclip) {
106       c->reg.fixed_planes = brw_vec8_grf(i, 0); 
107       i++;
108    }
109
110    if (c->key.do_unfilled) {
111       c->reg.dir     = brw_vec4_grf(i, 0);
112       c->reg.offset  = brw_vec4_grf(i, 4);
113       i++;
114       c->reg.tmp0    = brw_vec4_grf(i, 0);
115       c->reg.tmp1    = brw_vec4_grf(i, 4);
116       i++;
117    }
118
119    if (intel->needs_ff_sync) {
120       c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
121       i++;
122    }
123
124    c->first_tmp = i;
125    c->last_tmp = i;
126
127    c->prog_data.urb_read_length = c->nr_regs; /* ? */
128    c->prog_data.total_grf = i;
129 }
130
131
132
133 void brw_clip_tri_init_vertices( struct brw_clip_compile *c )
134 {
135    struct brw_compile *p = &c->func;
136    struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
137
138    /* Initial list of indices for incoming vertexes:
139     */
140    brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); 
141    brw_CMP(p, 
142            vec1(brw_null_reg()), 
143            BRW_CONDITIONAL_EQ, 
144            tmp0,
145            brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE));
146
147    /* XXX: Is there an easier way to do this?  Need to reverse every
148     * second tristrip element:  Can ignore sometimes?
149     */
150    brw_IF(p, BRW_EXECUTE_1);
151    {   
152       brw_MOV(p, get_element(c->reg.inlist, 0),  brw_address(c->reg.vertex[1]) );
153       brw_MOV(p, get_element(c->reg.inlist, 1),  brw_address(c->reg.vertex[0]) );
154       if (c->need_direction)
155          brw_MOV(p, c->reg.dir, brw_imm_f(-1));
156    }
157    brw_ELSE(p);
158    {
159       brw_MOV(p, get_element(c->reg.inlist, 0),  brw_address(c->reg.vertex[0]) );
160       brw_MOV(p, get_element(c->reg.inlist, 1),  brw_address(c->reg.vertex[1]) );
161       if (c->need_direction)
162          brw_MOV(p, c->reg.dir, brw_imm_f(1));
163    }
164    brw_ENDIF(p);
165
166    brw_MOV(p, get_element(c->reg.inlist, 2),  brw_address(c->reg.vertex[2]) );
167    brw_MOV(p, brw_vec8_grf(c->reg.outlist.nr, 0), brw_imm_f(0));
168    brw_MOV(p, c->reg.nr_verts, brw_imm_ud(3));
169 }
170
171
172
173 void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
174 {
175    struct brw_compile *p = &c->func;
176    struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
177
178    brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); 
179    brw_CMP(p, 
180            vec1(brw_null_reg()), 
181            BRW_CONDITIONAL_EQ, 
182            tmp0,
183            brw_imm_ud(_3DPRIM_POLYGON));
184
185    brw_IF(p, BRW_EXECUTE_1);
186    {
187       brw_clip_copy_colors(c, 1, 0);
188       brw_clip_copy_colors(c, 2, 0);
189    }
190    brw_ELSE(p);
191    {
192       if (c->key.pv_first) {
193          brw_CMP(p,
194                  vec1(brw_null_reg()),
195                  BRW_CONDITIONAL_EQ,
196                  tmp0,
197                  brw_imm_ud(_3DPRIM_TRIFAN));
198          brw_IF(p, BRW_EXECUTE_1);
199          {
200             brw_clip_copy_colors(c, 0, 1);
201             brw_clip_copy_colors(c, 2, 1);
202          }
203          brw_ELSE(p);
204          {
205             brw_clip_copy_colors(c, 1, 0);
206             brw_clip_copy_colors(c, 2, 0);
207          }
208          brw_ENDIF(p);
209       }
210       else {
211          brw_clip_copy_colors(c, 0, 2);
212          brw_clip_copy_colors(c, 1, 2);
213       }
214    }
215    brw_ENDIF(p);
216 }
217
218
219
220 /* Use mesa's clipping algorithms, translated to GEN4 assembly.
221  */
222 void brw_clip_tri( struct brw_clip_compile *c )
223 {
224    struct brw_compile *p = &c->func;
225    struct brw_indirect vtx = brw_indirect(0, 0);
226    struct brw_indirect vtxPrev = brw_indirect(1, 0);
227    struct brw_indirect vtxOut = brw_indirect(2, 0);
228    struct brw_indirect plane_ptr = brw_indirect(3, 0);
229    struct brw_indirect inlist_ptr = brw_indirect(4, 0);
230    struct brw_indirect outlist_ptr = brw_indirect(5, 0);
231    struct brw_indirect freelist_ptr = brw_indirect(6, 0);
232    struct brw_instruction *plane_loop;
233    struct brw_instruction *vertex_loop;
234    
235    brw_MOV(p, get_addr_reg(vtxPrev),     brw_address(c->reg.vertex[2]) );
236    brw_MOV(p, get_addr_reg(plane_ptr),   brw_clip_plane0_address(c));
237    brw_MOV(p, get_addr_reg(inlist_ptr),  brw_address(c->reg.inlist));
238    brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
239
240    brw_MOV(p, get_addr_reg(freelist_ptr), brw_address(c->reg.vertex[3]) );
241
242    plane_loop = brw_DO(p, BRW_EXECUTE_1);
243    {
244       /* if (planemask & 1)
245        */
246       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
247       brw_AND(p, vec1(brw_null_reg()), c->reg.planemask, brw_imm_ud(1));
248       
249       brw_IF(p, BRW_EXECUTE_1);
250       {
251          /* vtxOut = freelist_ptr++ 
252           */
253          brw_MOV(p, get_addr_reg(vtxOut),       get_addr_reg(freelist_ptr) );
254          brw_ADD(p, get_addr_reg(freelist_ptr), get_addr_reg(freelist_ptr), brw_imm_uw(c->nr_regs * REG_SIZE));
255
256          if (c->key.nr_userclip)
257             brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
258          else
259             brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
260             
261          brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
262          brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0));
263
264          vertex_loop = brw_DO(p, BRW_EXECUTE_1);
265          {
266             /* vtx = *input_ptr;
267              */
268             brw_MOV(p, get_addr_reg(vtx), deref_1uw(inlist_ptr, 0));
269
270             /* IS_NEGATIVE(prev) */
271             brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
272             brw_DP4(p, vec4(c->reg.dpPrev), deref_4f(vtxPrev, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
273             brw_IF(p, BRW_EXECUTE_1);
274             {
275                /* IS_POSITIVE(next)
276                 */
277                brw_set_conditionalmod(p, BRW_CONDITIONAL_GE);
278                brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
279                brw_IF(p, BRW_EXECUTE_1);
280                {
281
282                   /* Coming back in.
283                    */
284                   brw_ADD(p, c->reg.t, c->reg.dpPrev, negate(c->reg.dp));
285                   brw_math_invert(p, c->reg.t, c->reg.t);
286                   brw_MUL(p, c->reg.t, c->reg.t, c->reg.dpPrev);
287
288                   /* If (vtxOut == 0) vtxOut = vtxPrev
289                    */
290                   brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
291                   brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtxPrev) );
292                   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
293
294                   brw_clip_interp_vertex(c, vtxOut, vtxPrev, vtx, c->reg.t, GL_FALSE);
295
296                   /* *outlist_ptr++ = vtxOut;
297                    * nr_verts++; 
298                    * vtxOut = 0;
299                    */
300                   brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
301                   brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
302                   brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
303                   brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
304                }
305                brw_ENDIF(p);
306                
307             }
308             brw_ELSE(p);
309             {
310                /* *outlist_ptr++ = vtxPrev;
311                 * nr_verts++;
312                 */
313                brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxPrev));
314                brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
315                brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
316
317                /* IS_NEGATIVE(next)
318                 */
319                brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
320                brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
321                brw_IF(p, BRW_EXECUTE_1);
322                {
323                   /* Going out of bounds.  Avoid division by zero as we
324                    * know dp != dpPrev from DIFFERENT_SIGNS, above.
325                    */
326                   brw_ADD(p, c->reg.t, c->reg.dp, negate(c->reg.dpPrev));
327                   brw_math_invert(p, c->reg.t, c->reg.t);
328                   brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp);
329
330                   /* If (vtxOut == 0) vtxOut = vtx
331                    */
332                   brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
333                   brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtx) );
334                   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
335
336                   brw_clip_interp_vertex(c, vtxOut, vtx, vtxPrev, c->reg.t, GL_TRUE);             
337
338                   /* *outlist_ptr++ = vtxOut;
339                    * nr_verts++; 
340                    * vtxOut = 0;
341                    */
342                   brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
343                   brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
344                   brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
345                   brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
346                }               
347                brw_ENDIF(p);
348             }
349             brw_ENDIF(p);
350             
351             /* vtxPrev = vtx;
352              * inlist_ptr++;
353              */
354             brw_MOV(p, get_addr_reg(vtxPrev), get_addr_reg(vtx));
355             brw_ADD(p, get_addr_reg(inlist_ptr), get_addr_reg(inlist_ptr), brw_imm_uw(sizeof(short)));
356
357             /* while (--loopcount != 0)
358              */
359             brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
360             brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
361          } 
362          brw_WHILE(p, vertex_loop);
363
364          /* vtxPrev = *(outlist_ptr-1)  OR: outlist[nr_verts-1]
365           * inlist = outlist
366           * inlist_ptr = &inlist[0]
367           * outlist_ptr = &outlist[0]
368           */
369          brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_w(-2));
370          brw_MOV(p, get_addr_reg(vtxPrev), deref_1uw(outlist_ptr, 0));
371          brw_MOV(p, brw_vec8_grf(c->reg.inlist.nr, 0), brw_vec8_grf(c->reg.outlist.nr, 0));
372          brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist));
373          brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
374       }
375       brw_ENDIF(p);
376       
377       /* plane_ptr++;
378        */
379       brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
380
381       /* nr_verts >= 3 
382        */
383       brw_CMP(p,
384               vec1(brw_null_reg()),
385               BRW_CONDITIONAL_GE,
386               c->reg.nr_verts,
387               brw_imm_ud(3));
388    
389       /* && (planemask>>=1) != 0
390        */
391       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
392       brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
393    }
394    brw_WHILE(p, plane_loop);
395 }
396
397
398
399 void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
400 {
401    struct brw_compile *p = &c->func;
402    struct brw_instruction *loop;
403
404    /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
405     */
406    brw_set_conditionalmod(p, BRW_CONDITIONAL_G);
407    brw_ADD(p,
408            c->reg.loopcount,
409            c->reg.nr_verts,
410            brw_imm_d(-2));
411
412    brw_IF(p, BRW_EXECUTE_1);
413    {
414       struct brw_indirect v0 = brw_indirect(0, 0);
415       struct brw_indirect vptr = brw_indirect(1, 0);
416
417       brw_MOV(p, get_addr_reg(vptr), brw_address(c->reg.inlist));
418       brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
419
420       brw_clip_emit_vue(c, v0, 1, 0, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_START));
421       
422       brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
423       brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
424
425       loop = brw_DO(p, BRW_EXECUTE_1);
426       {
427          brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_TRIFAN << 2));
428   
429          brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
430          brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
431
432          brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
433          brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
434       }
435       brw_WHILE(p, loop);
436
437       brw_clip_emit_vue(c, v0, 0, 1, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_END));
438    }
439    brw_ENDIF(p);
440 }
441
442 static void do_clip_tri( struct brw_clip_compile *c )
443 {
444    brw_clip_init_planes(c);
445
446    brw_clip_tri(c);
447 }
448
449
450 static void maybe_do_clip_tri( struct brw_clip_compile *c )
451 {
452    struct brw_compile *p = &c->func;
453
454    brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
455    brw_IF(p, BRW_EXECUTE_1);
456    {
457       do_clip_tri(c);
458    }
459    brw_ENDIF(p);
460 }
461
462 static void brw_clip_test( struct brw_clip_compile *c )
463 {
464     struct brw_reg t = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
465     struct brw_reg t1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
466     struct brw_reg t2 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
467     struct brw_reg t3 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
468
469     struct brw_reg v0 = get_tmp(c);
470     struct brw_reg v1 = get_tmp(c);
471     struct brw_reg v2 = get_tmp(c);
472
473     struct brw_indirect vt0 = brw_indirect(0, 0);
474     struct brw_indirect vt1 = brw_indirect(1, 0);
475     struct brw_indirect vt2 = brw_indirect(2, 0);
476
477     struct brw_compile *p = &c->func;
478     struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
479
480     brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0]));
481     brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1]));
482     brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2]));
483     brw_MOV(p, v0, deref_4f(vt0, c->offset[VERT_RESULT_HPOS]));
484     brw_MOV(p, v1, deref_4f(vt1, c->offset[VERT_RESULT_HPOS]));
485     brw_MOV(p, v2, deref_4f(vt2, c->offset[VERT_RESULT_HPOS]));
486     brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f));
487
488     /* test nearz, xmin, ymin plane */
489     /* clip.xyz < -clip.w */
490     brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, negate(get_element(v0, 3))); 
491     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
492     brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, negate(get_element(v1, 3))); 
493     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
494     brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, negate(get_element(v2, 3))); 
495     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
496
497     /* All vertices are outside of a plane, rejected */
498     brw_AND(p, t, t1, t2);
499     brw_AND(p, t, t, t3);
500     brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
501     brw_OR(p, tmp0, tmp0, get_element(t, 2));
502     brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
503     brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
504     brw_IF(p, BRW_EXECUTE_1);
505     {
506         brw_clip_kill_thread(c);
507     }
508     brw_ENDIF(p);
509     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
510
511     /* some vertices are inside a plane, some are outside,need to clip */
512     brw_XOR(p, t, t1, t2);
513     brw_XOR(p, t1, t2, t3);
514     brw_OR(p, t, t, t1);
515     brw_AND(p, t, t, brw_imm_ud(0x1));
516     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
517             get_element(t, 0), brw_imm_ud(0));
518     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5)));
519     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
520     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
521             get_element(t, 1), brw_imm_ud(0));
522     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3)));
523     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
524     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
525             get_element(t, 2), brw_imm_ud(0));
526     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1)));
527     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
528
529     /* test farz, xmax, ymax plane */
530     /* clip.xyz > clip.w */
531     brw_CMP(p, t1, BRW_CONDITIONAL_G, v0, get_element(v0, 3)); 
532     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
533     brw_CMP(p, t2, BRW_CONDITIONAL_G, v1, get_element(v1, 3)); 
534     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
535     brw_CMP(p, t3, BRW_CONDITIONAL_G, v2, get_element(v2, 3)); 
536     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
537
538     /* All vertices are outside of a plane, rejected */
539     brw_AND(p, t, t1, t2);
540     brw_AND(p, t, t, t3);
541     brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
542     brw_OR(p, tmp0, tmp0, get_element(t, 2));
543     brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
544     brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
545     brw_IF(p, BRW_EXECUTE_1);
546     {
547         brw_clip_kill_thread(c);
548     }
549     brw_ENDIF(p);
550     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
551
552     /* some vertices are inside a plane, some are outside,need to clip */
553     brw_XOR(p, t, t1, t2);
554     brw_XOR(p, t1, t2, t3);
555     brw_OR(p, t, t, t1);
556     brw_AND(p, t, t, brw_imm_ud(0x1));
557     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
558             get_element(t, 0), brw_imm_ud(0));
559     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4)));
560     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
561     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
562             get_element(t, 1), brw_imm_ud(0));
563     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2)));
564     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
565     brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
566             get_element(t, 2), brw_imm_ud(0));
567     brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0)));
568     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
569
570     release_tmps(c);
571 }
572
573
574 void brw_emit_tri_clip( struct brw_clip_compile *c )
575 {
576    struct brw_compile *p = &c->func;
577    struct brw_context *brw = p->brw;
578    brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
579    brw_clip_tri_init_vertices(c);
580    brw_clip_init_clipmask(c);
581    brw_clip_init_ff_sync(c);
582
583    /* if -ve rhw workaround bit is set, 
584       do cliptest */
585    if (brw->has_negative_rhw_bug) {
586       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
587       brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), 
588               brw_imm_ud(1<<20));
589       brw_IF(p, BRW_EXECUTE_1);
590       {
591          brw_clip_test(c);
592       }
593       brw_ENDIF(p);
594    }
595    /* Can't push into do_clip_tri because with polygon (or quad)
596     * flatshading, need to apply the flatshade here because we don't
597     * respect the PV when converting to trifan for emit:
598     */
599    if (c->key.do_flat_shading) 
600       brw_clip_tri_flat_shade(c); 
601       
602    if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) ||
603        (c->key.clip_mode == BRW_CLIPMODE_KERNEL_CLIP))
604       do_clip_tri(c);
605    else 
606       maybe_do_clip_tri(c);
607
608    brw_clip_tri_emit_polygon(c);
609
610    /* Send an empty message to kill the thread:
611     */
612    brw_clip_kill_thread(c);
613 }