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