cb58d1da9fef3709c1965e46397a2c5869828387
[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->offset[c->idx_to_attr[c->nr_attrs - 1]] + ATTR_SIZE;
80
81 brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0));
82 }
83 }
84
85 c->reg.t = brw_vec1_grf(i, 0);
86 c->reg.loopcount = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_D);
87 c->reg.nr_verts = retype(brw_vec1_grf(i, 2), BRW_REGISTER_TYPE_UD);
88 c->reg.planemask = retype(brw_vec1_grf(i, 3), BRW_REGISTER_TYPE_UD);
89 c->reg.plane_equation = brw_vec4_grf(i, 4);
90 i++;
91
92 c->reg.dpPrev = brw_vec1_grf(i, 0); /* fixme - dp4 will clobber r.1,2,3 */
93 c->reg.dp = brw_vec1_grf(i, 4);
94 i++;
95
96 c->reg.inlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
97 i++;
98
99 c->reg.outlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
100 i++;
101
102 c->reg.freelist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
103 i++;
104
105 if (!c->key.nr_userclip) {
106 c->reg.fixed_planes = brw_vec8_grf(i, 0);
107 i++;
108 }
109
110 if (c->key.do_unfilled) {
111 c->reg.dir = brw_vec4_grf(i, 0);
112 c->reg.offset = brw_vec4_grf(i, 4);
113 i++;
114 c->reg.tmp0 = brw_vec4_grf(i, 0);
115 c->reg.tmp1 = brw_vec4_grf(i, 4);
116 i++;
117 }
118
119 if (intel->needs_ff_sync) {
120 c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
121 i++;
122 }
123
124 c->first_tmp = i;
125 c->last_tmp = i;
126
127 c->prog_data.urb_read_length = c->nr_regs; /* ? */
128 c->prog_data.total_grf = i;
129 }
130
131
132
133 void brw_clip_tri_init_vertices( struct brw_clip_compile *c )
134 {
135 struct brw_compile *p = &c->func;
136 struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
137 struct brw_instruction *is_rev;
138
139 /* Initial list of indices for incoming vertexes:
140 */
141 brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
142 brw_CMP(p,
143 vec1(brw_null_reg()),
144 BRW_CONDITIONAL_EQ,
145 tmp0,
146 brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE));
147
148 /* XXX: Is there an easier way to do this? Need to reverse every
149 * second tristrip element: Can ignore sometimes?
150 */
151 is_rev = brw_IF(p, BRW_EXECUTE_1);
152 {
153 brw_MOV(p, get_element(c->reg.inlist, 0), brw_address(c->reg.vertex[1]) );
154 brw_MOV(p, get_element(c->reg.inlist, 1), brw_address(c->reg.vertex[0]) );
155 if (c->need_direction)
156 brw_MOV(p, c->reg.dir, brw_imm_f(-1));
157 }
158 is_rev = brw_ELSE(p, is_rev);
159 {
160 brw_MOV(p, get_element(c->reg.inlist, 0), brw_address(c->reg.vertex[0]) );
161 brw_MOV(p, get_element(c->reg.inlist, 1), brw_address(c->reg.vertex[1]) );
162 if (c->need_direction)
163 brw_MOV(p, c->reg.dir, brw_imm_f(1));
164 }
165 brw_ENDIF(p, is_rev);
166
167 brw_MOV(p, get_element(c->reg.inlist, 2), brw_address(c->reg.vertex[2]) );
168 brw_MOV(p, brw_vec8_grf(c->reg.outlist.nr, 0), brw_imm_f(0));
169 brw_MOV(p, c->reg.nr_verts, brw_imm_ud(3));
170 }
171
172
173
174 void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
175 {
176 struct brw_compile *p = &c->func;
177 struct brw_instruction *is_poly, *is_trifan;
178 struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
179
180 brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
181 brw_CMP(p,
182 vec1(brw_null_reg()),
183 BRW_CONDITIONAL_EQ,
184 tmp0,
185 brw_imm_ud(_3DPRIM_POLYGON));
186
187 is_poly = brw_IF(p, BRW_EXECUTE_1);
188 {
189 brw_clip_copy_colors(c, 1, 0);
190 brw_clip_copy_colors(c, 2, 0);
191 }
192 is_poly = brw_ELSE(p, is_poly);
193 {
194 if (c->key.pv_first) {
195 brw_CMP(p,
196 vec1(brw_null_reg()),
197 BRW_CONDITIONAL_EQ,
198 tmp0,
199 brw_imm_ud(_3DPRIM_TRIFAN));
200 is_trifan = brw_IF(p, BRW_EXECUTE_1);
201 {
202 brw_clip_copy_colors(c, 0, 1);
203 brw_clip_copy_colors(c, 2, 1);
204 }
205 is_trifan = brw_ELSE(p, is_trifan);
206 {
207 brw_clip_copy_colors(c, 1, 0);
208 brw_clip_copy_colors(c, 2, 0);
209 }
210 brw_ENDIF(p, is_trifan);
211 }
212 else {
213 brw_clip_copy_colors(c, 0, 2);
214 brw_clip_copy_colors(c, 1, 2);
215 }
216 }
217 brw_ENDIF(p, is_poly);
218 }
219
220
221
222 /* Use mesa's clipping algorithms, translated to GEN4 assembly.
223 */
224 void brw_clip_tri( struct brw_clip_compile *c )
225 {
226 struct brw_compile *p = &c->func;
227 struct brw_indirect vtx = brw_indirect(0, 0);
228 struct brw_indirect vtxPrev = brw_indirect(1, 0);
229 struct brw_indirect vtxOut = brw_indirect(2, 0);
230 struct brw_indirect plane_ptr = brw_indirect(3, 0);
231 struct brw_indirect inlist_ptr = brw_indirect(4, 0);
232 struct brw_indirect outlist_ptr = brw_indirect(5, 0);
233 struct brw_indirect freelist_ptr = brw_indirect(6, 0);
234 struct brw_instruction *plane_loop;
235 struct brw_instruction *plane_active;
236 struct brw_instruction *vertex_loop;
237 struct brw_instruction *next_test;
238 struct brw_instruction *prev_test;
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 plane_active = 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, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
278 prev_test = 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, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
284 next_test = 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, GL_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, next_test);
311
312 }
313 prev_test = brw_ELSE(p, prev_test);
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, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
326 next_test = 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, GL_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, next_test);
353 }
354 brw_ENDIF(p, prev_test);
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, plane_active);
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, *if_insn;
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 if_insn = 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, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_START));
426
427 brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
428 brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
429
430 loop = brw_DO(p, BRW_EXECUTE_1);
431 {
432 brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_TRIFAN << 2));
433
434 brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
435 brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
436
437 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
438 brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
439 }
440 brw_WHILE(p, loop);
441
442 brw_clip_emit_vue(c, v0, 0, 1, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_END));
443 }
444 brw_ENDIF(p, if_insn);
445 }
446
447 static void do_clip_tri( struct brw_clip_compile *c )
448 {
449 brw_clip_init_planes(c);
450
451 brw_clip_tri(c);
452 }
453
454
455 static void maybe_do_clip_tri( struct brw_clip_compile *c )
456 {
457 struct brw_compile *p = &c->func;
458 struct brw_instruction *do_clip;
459
460 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
461 do_clip = brw_IF(p, BRW_EXECUTE_1);
462 {
463 do_clip_tri(c);
464 }
465 brw_ENDIF(p, do_clip);
466 }
467
468 static void brw_clip_test( struct brw_clip_compile *c )
469 {
470 struct brw_reg t = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
471 struct brw_reg t1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
472 struct brw_reg t2 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
473 struct brw_reg t3 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
474
475 struct brw_reg v0 = get_tmp(c);
476 struct brw_reg v1 = get_tmp(c);
477 struct brw_reg v2 = get_tmp(c);
478
479 struct brw_indirect vt0 = brw_indirect(0, 0);
480 struct brw_indirect vt1 = brw_indirect(1, 0);
481 struct brw_indirect vt2 = brw_indirect(2, 0);
482
483 struct brw_compile *p = &c->func;
484 struct brw_instruction *is_outside;
485 struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
486
487 brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0]));
488 brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1]));
489 brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2]));
490 brw_MOV(p, v0, deref_4f(vt0, c->offset[VERT_RESULT_HPOS]));
491 brw_MOV(p, v1, deref_4f(vt1, c->offset[VERT_RESULT_HPOS]));
492 brw_MOV(p, v2, deref_4f(vt2, c->offset[VERT_RESULT_HPOS]));
493 brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f));
494
495 /* test nearz, xmin, ymin plane */
496 /* clip.xyz < -clip.w */
497 brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, negate(get_element(v0, 3)));
498 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
499 brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, negate(get_element(v1, 3)));
500 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
501 brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, negate(get_element(v2, 3)));
502 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
503
504 /* All vertices are outside of a plane, rejected */
505 brw_AND(p, t, t1, t2);
506 brw_AND(p, t, t, t3);
507 brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
508 brw_OR(p, tmp0, tmp0, get_element(t, 2));
509 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
510 brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
511 is_outside = brw_IF(p, BRW_EXECUTE_1);
512 {
513 brw_clip_kill_thread(c);
514 }
515 brw_ENDIF(p, is_outside);
516 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
517
518 /* some vertices are inside a plane, some are outside,need to clip */
519 brw_XOR(p, t, t1, t2);
520 brw_XOR(p, t1, t2, t3);
521 brw_OR(p, t, t, t1);
522 brw_AND(p, t, t, brw_imm_ud(0x1));
523 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
524 get_element(t, 0), brw_imm_ud(0));
525 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5)));
526 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
527 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
528 get_element(t, 1), brw_imm_ud(0));
529 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3)));
530 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
531 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
532 get_element(t, 2), brw_imm_ud(0));
533 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1)));
534 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
535
536 /* test farz, xmax, ymax plane */
537 /* clip.xyz > clip.w */
538 brw_CMP(p, t1, BRW_CONDITIONAL_G, v0, get_element(v0, 3));
539 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
540 brw_CMP(p, t2, BRW_CONDITIONAL_G, v1, get_element(v1, 3));
541 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
542 brw_CMP(p, t3, BRW_CONDITIONAL_G, v2, get_element(v2, 3));
543 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
544
545 /* All vertices are outside of a plane, rejected */
546 brw_AND(p, t, t1, t2);
547 brw_AND(p, t, t, t3);
548 brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
549 brw_OR(p, tmp0, tmp0, get_element(t, 2));
550 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
551 brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
552 is_outside = brw_IF(p, BRW_EXECUTE_1);
553 {
554 brw_clip_kill_thread(c);
555 }
556 brw_ENDIF(p, is_outside);
557 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
558
559 /* some vertices are inside a plane, some are outside,need to clip */
560 brw_XOR(p, t, t1, t2);
561 brw_XOR(p, t1, t2, t3);
562 brw_OR(p, t, t, t1);
563 brw_AND(p, t, t, brw_imm_ud(0x1));
564 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
565 get_element(t, 0), brw_imm_ud(0));
566 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4)));
567 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
568 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
569 get_element(t, 1), brw_imm_ud(0));
570 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2)));
571 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
572 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
573 get_element(t, 2), brw_imm_ud(0));
574 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0)));
575 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
576
577 release_tmps(c);
578 }
579
580
581 void brw_emit_tri_clip( struct brw_clip_compile *c )
582 {
583 struct brw_instruction *neg_rhw;
584 struct brw_compile *p = &c->func;
585 struct brw_context *brw = p->brw;
586 brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
587 brw_clip_tri_init_vertices(c);
588 brw_clip_init_clipmask(c);
589 brw_clip_init_ff_sync(c);
590
591 /* if -ve rhw workaround bit is set,
592 do cliptest */
593 if (brw->has_negative_rhw_bug) {
594 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
595 brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
596 brw_imm_ud(1<<20));
597 neg_rhw = brw_IF(p, BRW_EXECUTE_1);
598 {
599 brw_clip_test(c);
600 }
601 brw_ENDIF(p, neg_rhw);
602 }
603 /* Can't push into do_clip_tri because with polygon (or quad)
604 * flatshading, need to apply the flatshade here because we don't
605 * respect the PV when converting to trifan for emit:
606 */
607 if (c->key.do_flat_shading)
608 brw_clip_tri_flat_shade(c);
609
610 if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) ||
611 (c->key.clip_mode == BRW_CLIPMODE_KERNEL_CLIP))
612 do_clip_tri(c);
613 else
614 maybe_do_clip_tri(c);
615
616 brw_clip_tri_emit_polygon(c);
617
618 /* Send an empty message to kill the thread:
619 */
620 brw_clip_kill_thread(c);
621 }