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