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