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