f1fc6e1e9da875d47faa377cb70616ff375435ca
[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 "glheader.h"
33 #include "macros.h"
34 #include "enums.h"
35
36 #include "shader/program.h"
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 struct brw_reg get_tmp( struct brw_clip_compile *c )
46 {
47 struct brw_reg tmp = brw_vec4_grf(c->last_tmp, 0);
48
49 if (++c->last_tmp > c->prog_data.total_grf)
50 c->prog_data.total_grf = c->last_tmp;
51
52 return tmp;
53 }
54
55 static void release_tmps( struct brw_clip_compile *c )
56 {
57 c->last_tmp = c->first_tmp;
58 }
59
60
61 void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
62 GLuint nr_verts )
63 {
64 GLuint i = 0,j;
65
66 /* Register usage is static, precompute here:
67 */
68 c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
69
70 if (c->key.nr_userclip) {
71 c->reg.fixed_planes = brw_vec4_grf(i, 0);
72 i += (6 + c->key.nr_userclip + 1) / 2;
73
74 c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2;
75 }
76 else
77 c->prog_data.curb_read_length = 0;
78
79
80 /* Payload vertices plus space for more generated vertices:
81 */
82 for (j = 0; j < nr_verts; j++) {
83 c->reg.vertex[j] = brw_vec4_grf(i, 0);
84 i += c->nr_regs;
85 }
86
87 if (c->nr_attrs & 1) {
88 for (j = 0; j < 3; j++) {
89 GLuint delta = c->nr_attrs*16 + 32;
90 brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0));
91 }
92 }
93
94 c->reg.t = brw_vec1_grf(i, 0);
95 c->reg.loopcount = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_D);
96 c->reg.nr_verts = retype(brw_vec1_grf(i, 2), BRW_REGISTER_TYPE_UD);
97 c->reg.planemask = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
98 c->reg.plane_equation = brw_vec4_grf(i, 4);
99 i++;
100
101 c->reg.dpPrev = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
102 c->reg.dp = brw_vec1_grf(i, 4);
103 i++;
104
105 c->reg.inlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
106 i++;
107
108 c->reg.outlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
109 i++;
110
111 c->reg.freelist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
112 i++;
113
114 if (!c->key.nr_userclip) {
115 c->reg.fixed_planes = brw_vec8_grf(i, 0);
116 i++;
117 }
118
119 if (c->key.do_unfilled) {
120 c->reg.dir = brw_vec4_grf(i, 0);
121 c->reg.offset = brw_vec4_grf(i, 4);
122 i++;
123 c->reg.tmp0 = brw_vec4_grf(i, 0);
124 c->reg.tmp1 = brw_vec4_grf(i, 4);
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 brw_clip_copy_colors(c, 0, 2);
199 brw_clip_copy_colors(c, 1, 2);
200 }
201 brw_ENDIF(p, is_poly);
202 }
203
204
205
206 /* Use mesa's clipping algorithms, translated to GEN4 assembly.
207 */
208 void brw_clip_tri( struct brw_clip_compile *c )
209 {
210 struct brw_compile *p = &c->func;
211 struct brw_indirect vtx = brw_indirect(0, 0);
212 struct brw_indirect vtxPrev = brw_indirect(1, 0);
213 struct brw_indirect vtxOut = brw_indirect(2, 0);
214 struct brw_indirect plane_ptr = brw_indirect(3, 0);
215 struct brw_indirect inlist_ptr = brw_indirect(4, 0);
216 struct brw_indirect outlist_ptr = brw_indirect(5, 0);
217 struct brw_indirect freelist_ptr = brw_indirect(6, 0);
218 struct brw_instruction *plane_loop;
219 struct brw_instruction *plane_active;
220 struct brw_instruction *vertex_loop;
221 struct brw_instruction *next_test;
222 struct brw_instruction *prev_test;
223
224 brw_MOV(p, get_addr_reg(vtxPrev), brw_address(c->reg.vertex[2]) );
225 brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c));
226 brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist));
227 brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
228
229 brw_MOV(p, get_addr_reg(freelist_ptr), brw_address(c->reg.vertex[3]) );
230
231 plane_loop = brw_DO(p, BRW_EXECUTE_1);
232 {
233 /* if (planemask & 1)
234 */
235 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
236 brw_AND(p, vec1(brw_null_reg()), c->reg.planemask, brw_imm_ud(1));
237
238 plane_active = brw_IF(p, BRW_EXECUTE_1);
239 {
240 /* vtxOut = freelist_ptr++
241 */
242 brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(freelist_ptr) );
243 brw_ADD(p, get_addr_reg(freelist_ptr), get_addr_reg(freelist_ptr), brw_imm_uw(c->nr_regs * REG_SIZE));
244
245 if (c->key.nr_userclip)
246 brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
247 else
248 brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
249
250 brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
251 brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0));
252
253 vertex_loop = brw_DO(p, BRW_EXECUTE_1);
254 {
255 /* vtx = *input_ptr;
256 */
257 brw_MOV(p, get_addr_reg(vtx), deref_1uw(inlist_ptr, 0));
258
259 /* IS_NEGATIVE(prev) */
260 brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
261 brw_DP4(p, vec4(c->reg.dpPrev), deref_4f(vtxPrev, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
262 prev_test = brw_IF(p, BRW_EXECUTE_1);
263 {
264 /* IS_POSITIVE(next)
265 */
266 brw_set_conditionalmod(p, BRW_CONDITIONAL_GE);
267 brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
268 next_test = brw_IF(p, BRW_EXECUTE_1);
269 {
270
271 /* Coming back in.
272 */
273 brw_ADD(p, c->reg.t, c->reg.dpPrev, negate(c->reg.dp));
274 brw_math_invert(p, c->reg.t, c->reg.t);
275 brw_MUL(p, c->reg.t, c->reg.t, c->reg.dpPrev);
276
277 /* If (vtxOut == 0) vtxOut = vtxPrev
278 */
279 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
280 brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtxPrev) );
281 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
282
283 brw_clip_interp_vertex(c, vtxOut, vtxPrev, vtx, c->reg.t, GL_FALSE);
284
285 /* *outlist_ptr++ = vtxOut;
286 * nr_verts++;
287 * vtxOut = 0;
288 */
289 brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
290 brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
291 brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
292 brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
293 }
294 brw_ENDIF(p, next_test);
295
296 }
297 prev_test = brw_ELSE(p, prev_test);
298 {
299 /* *outlist_ptr++ = vtxPrev;
300 * nr_verts++;
301 */
302 brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxPrev));
303 brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
304 brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
305
306 /* IS_NEGATIVE(next)
307 */
308 brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
309 brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
310 next_test = brw_IF(p, BRW_EXECUTE_1);
311 {
312 /* Going out of bounds. Avoid division by zero as we
313 * know dp != dpPrev from DIFFERENT_SIGNS, above.
314 */
315 brw_ADD(p, c->reg.t, c->reg.dp, negate(c->reg.dpPrev));
316 brw_math_invert(p, c->reg.t, c->reg.t);
317 brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp);
318
319 /* If (vtxOut == 0) vtxOut = vtx
320 */
321 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
322 brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtx) );
323 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
324
325 brw_clip_interp_vertex(c, vtxOut, vtx, vtxPrev, c->reg.t, GL_TRUE);
326
327 /* *outlist_ptr++ = vtxOut;
328 * nr_verts++;
329 * vtxOut = 0;
330 */
331 brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
332 brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
333 brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
334 brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
335 }
336 brw_ENDIF(p, next_test);
337 }
338 brw_ENDIF(p, prev_test);
339
340 /* vtxPrev = vtx;
341 * inlist_ptr++;
342 */
343 brw_MOV(p, get_addr_reg(vtxPrev), get_addr_reg(vtx));
344 brw_ADD(p, get_addr_reg(inlist_ptr), get_addr_reg(inlist_ptr), brw_imm_uw(sizeof(short)));
345
346 /* while (--loopcount != 0)
347 */
348 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
349 brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
350 }
351 brw_WHILE(p, vertex_loop);
352
353 /* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1]
354 * inlist = outlist
355 * inlist_ptr = &inlist[0]
356 * outlist_ptr = &outlist[0]
357 */
358 brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_w(-2));
359 brw_MOV(p, get_addr_reg(vtxPrev), deref_1uw(outlist_ptr, 0));
360 brw_MOV(p, brw_vec8_grf(c->reg.inlist.nr, 0), brw_vec8_grf(c->reg.outlist.nr, 0));
361 brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist));
362 brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
363 }
364 brw_ENDIF(p, plane_active);
365
366 /* plane_ptr++;
367 */
368 brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
369
370 /* nr_verts >= 3
371 */
372 brw_CMP(p,
373 vec1(brw_null_reg()),
374 BRW_CONDITIONAL_GE,
375 c->reg.nr_verts,
376 brw_imm_ud(3));
377
378 /* && (planemask>>=1) != 0
379 */
380 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
381 brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
382 }
383 brw_WHILE(p, plane_loop);
384 }
385
386
387
388 void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
389 {
390 struct brw_compile *p = &c->func;
391 struct brw_instruction *loop, *if_insn;
392
393 /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
394 */
395 brw_set_conditionalmod(p, BRW_CONDITIONAL_G);
396 brw_ADD(p,
397 c->reg.loopcount,
398 c->reg.nr_verts,
399 brw_imm_d(-2));
400
401 if_insn = brw_IF(p, BRW_EXECUTE_1);
402 {
403 struct brw_indirect v0 = brw_indirect(0, 0);
404 struct brw_indirect vptr = brw_indirect(1, 0);
405
406 brw_MOV(p, get_addr_reg(vptr), brw_address(c->reg.inlist));
407 brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
408
409 brw_clip_emit_vue(c, v0, 1, 0, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_START));
410
411 brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
412 brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
413
414 loop = brw_DO(p, BRW_EXECUTE_1);
415 {
416 brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_TRIFAN << 2));
417
418 brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
419 brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
420
421 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
422 brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
423 }
424 brw_WHILE(p, loop);
425
426 brw_clip_emit_vue(c, v0, 0, 1, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_END));
427 }
428 brw_ENDIF(p, if_insn);
429 }
430
431 static void do_clip_tri( struct brw_clip_compile *c )
432 {
433 brw_clip_init_planes(c);
434
435 brw_clip_tri(c);
436 }
437
438
439 static void maybe_do_clip_tri( struct brw_clip_compile *c )
440 {
441 struct brw_compile *p = &c->func;
442 struct brw_instruction *do_clip;
443
444 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
445 do_clip = brw_IF(p, BRW_EXECUTE_1);
446 {
447 do_clip_tri(c);
448 }
449 brw_ENDIF(p, do_clip);
450 }
451
452 static void brw_clip_test( struct brw_clip_compile *c )
453 {
454 struct brw_reg t = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
455 struct brw_reg t1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
456 struct brw_reg t2 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
457 struct brw_reg t3 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
458
459 struct brw_reg v0 = get_tmp(c);
460 struct brw_reg v1 = get_tmp(c);
461 struct brw_reg v2 = get_tmp(c);
462
463 struct brw_indirect vt0 = brw_indirect(0, 0);
464 struct brw_indirect vt1 = brw_indirect(1, 0);
465 struct brw_indirect vt2 = brw_indirect(2, 0);
466
467 struct brw_compile *p = &c->func;
468
469 brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0]));
470 brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1]));
471 brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2]));
472 brw_MOV(p, v0, deref_4f(vt0, c->offset[VERT_RESULT_HPOS]));
473 brw_MOV(p, v1, deref_4f(vt1, c->offset[VERT_RESULT_HPOS]));
474 brw_MOV(p, v2, deref_4f(vt2, c->offset[VERT_RESULT_HPOS]));
475
476 /* test nearz, xmin, ymin plane */
477 brw_CMP(p, t1, BRW_CONDITIONAL_LE, negate(v0), get_element(v0, 3));
478 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
479 brw_CMP(p, t2, BRW_CONDITIONAL_LE, negate(v1), get_element(v1, 3));
480 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
481 brw_CMP(p, t3, BRW_CONDITIONAL_LE, negate(v2), get_element(v2, 3));
482 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
483 brw_XOR(p, t, t1, t2);
484 brw_XOR(p, t1, t2, t3);
485 brw_OR(p, t, t, t1);
486
487 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
488 get_element(t, 0), brw_imm_ud(0));
489 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5)));
490 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
491 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
492 get_element(t, 1), brw_imm_ud(0));
493 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3)));
494 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
495 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
496 get_element(t, 2), brw_imm_ud(0));
497 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1)));
498 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
499
500 /* test farz, xmax, ymax plane */
501 brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, get_element(v0, 3));
502 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
503 brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, get_element(v1, 3));
504 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
505 brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, get_element(v2, 3));
506 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
507
508 brw_XOR(p, t, t1, t2);
509 brw_XOR(p, t1, t2, t3);
510 brw_OR(p, t, t, t1);
511
512 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
513 get_element(t, 0), brw_imm_ud(0));
514 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4)));
515 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
516 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
517 get_element(t, 1), brw_imm_ud(0));
518 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2)));
519 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
520 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
521 get_element(t, 2), brw_imm_ud(0));
522 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0)));
523 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
524
525 release_tmps(c);
526 }
527
528
529 void brw_emit_tri_clip( struct brw_clip_compile *c )
530 {
531 struct brw_instruction *neg_rhw;
532 struct brw_compile *p = &c->func;
533 brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
534 brw_clip_tri_init_vertices(c);
535 brw_clip_init_clipmask(c);
536
537 /* if -ve rhw workaround bit is set,
538 do cliptest */
539 if (!BRW_IS_IGD(p->brw)) {
540 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
541 brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
542 brw_imm_ud(1<<20));
543 neg_rhw = brw_IF(p, BRW_EXECUTE_1);
544 {
545 brw_clip_test(c);
546 }
547 brw_ENDIF(p, neg_rhw);
548 }
549 /* Can't push into do_clip_tri because with polygon (or quad)
550 * flatshading, need to apply the flatshade here because we don't
551 * respect the PV when converting to trifan for emit:
552 */
553 if (c->key.do_flat_shading)
554 brw_clip_tri_flat_shade(c);
555
556 if (c->key.clip_mode == BRW_CLIPMODE_NORMAL)
557 do_clip_tri(c);
558 else
559 maybe_do_clip_tri(c);
560
561 brw_clip_tri_emit_polygon(c);
562
563 /* Send an empty message to kill the thread:
564 */
565 brw_clip_kill_thread(c);
566 }