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