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