2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
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:
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.
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.
26 **********************************************************************/
29 * Keith Whitwell <keith@tungstengraphics.com>
32 #include "brw_defines.h"
33 #include "brw_context.h"
37 static void release_tmps( struct brw_clip_compile
*c
)
39 c
->last_tmp
= c
->first_tmp
;
43 void brw_clip_tri_alloc_regs( struct brw_clip_compile
*c
,
47 struct brw_context
*brw
= c
->func
.brw
;
49 /* Register usage is static, precompute here:
51 c
->reg
.R0
= retype(brw_vec8_grf(i
, 0), BRW_REGISTER_TYPE_UD
); i
++;
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;
57 c
->prog_data
.curb_read_length
= (6 + c
->key
.nr_userclip
+ 1) / 2;
60 c
->prog_data
.curb_read_length
= 0;
63 /* Payload vertices plus space for more generated vertices:
65 for (j
= 0; j
< nr_verts
; j
++) {
66 c
->reg
.vertex
[j
] = brw_vec4_grf(i
, 0);
70 if (c
->key
.nr_attrs
& 1) {
71 for (j
= 0; j
< 3; j
++) {
72 GLuint delta
= c
->key
.nr_attrs
*16 + 32;
75 delta
= c
->key
.nr_attrs
* 16 + 32 * 3;
77 brw_MOV(&c
->func
, byte_offset(c
->reg
.vertex
[j
], delta
), brw_imm_f(0));
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);
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);
92 c
->reg
.inlist
= brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, i
, 0);
95 c
->reg
.outlist
= brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, i
, 0);
98 c
->reg
.freelist
= brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, i
, 0);
101 if (!c
->key
.nr_userclip
) {
102 c
->reg
.fixed_planes
= brw_vec8_grf(i
, 0);
106 if (c
->key
.do_unfilled
) {
107 c
->reg
.dir
= brw_vec4_grf(i
, 0);
108 c
->reg
.offset
= brw_vec4_grf(i
, 4);
110 c
->reg
.tmp0
= brw_vec4_grf(i
, 0);
111 c
->reg
.tmp1
= brw_vec4_grf(i
, 4);
115 if (brw
->needs_ff_sync
) {
116 c
->reg
.ff_sync
= retype(brw_vec1_grf(i
, 0), BRW_REGISTER_TYPE_UD
);
123 c
->prog_data
.urb_read_length
= c
->nr_regs
; /* ? */
124 c
->prog_data
.total_grf
= i
;
129 void brw_clip_tri_init_vertices( struct brw_clip_compile
*c
)
131 struct brw_compile
*p
= &c
->func
;
132 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
133 struct brw_instruction
*is_rev
;
135 /* Initial list of indices for incoming vertexes:
137 brw_AND(p
, tmp0
, get_element_ud(c
->reg
.R0
, 2), brw_imm_ud(PRIM_MASK
));
139 vec1(brw_null_reg()),
142 brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE
));
144 /* XXX: Is there an easier way to do this? Need to reverse every
145 * second tristrip element: Can ignore sometimes?
147 is_rev
= brw_IF(p
, BRW_EXECUTE_1
);
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));
154 is_rev
= brw_ELSE(p
, is_rev
);
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));
161 brw_ENDIF(p
, is_rev
);
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));
170 void brw_clip_tri_flat_shade( struct brw_clip_compile
*c
)
172 struct brw_compile
*p
= &c
->func
;
173 struct brw_instruction
*is_poly
;
174 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
176 brw_AND(p
, tmp0
, get_element_ud(c
->reg
.R0
, 2), brw_imm_ud(PRIM_MASK
));
178 vec1(brw_null_reg()),
181 brw_imm_ud(_3DPRIM_POLYGON
));
183 is_poly
= brw_IF(p
, BRW_EXECUTE_1
);
185 brw_clip_copy_colors(c
, 1, 0);
186 brw_clip_copy_colors(c
, 2, 0);
188 is_poly
= brw_ELSE(p
, is_poly
);
190 brw_clip_copy_colors(c
, 0, 2);
191 brw_clip_copy_colors(c
, 1, 2);
193 brw_ENDIF(p
, is_poly
);
198 /* Use mesa's clipping algorithms, translated to GEN4 assembly.
200 void brw_clip_tri( struct brw_clip_compile
*c
)
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
;
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
));
221 brw_MOV(p
, get_addr_reg(freelist_ptr
), brw_address(c
->reg
.vertex
[3]) );
223 plane_loop
= brw_DO(p
, BRW_EXECUTE_1
);
225 /* if (planemask & 1)
227 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
228 brw_AND(p
, vec1(brw_null_reg()), c
->reg
.planemask
, brw_imm_ud(1));
230 plane_active
= brw_IF(p
, BRW_EXECUTE_1
);
232 /* vtxOut = freelist_ptr++
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
));
237 if (c
->key
.nr_userclip
)
238 brw_MOV(p
, c
->reg
.plane_equation
, deref_4f(plane_ptr
, 0));
240 brw_MOV(p
, c
->reg
.plane_equation
, deref_4b(plane_ptr
, 0));
242 brw_MOV(p
, c
->reg
.loopcount
, c
->reg
.nr_verts
);
243 brw_MOV(p
, c
->reg
.nr_verts
, brw_imm_ud(0));
245 vertex_loop
= brw_DO(p
, BRW_EXECUTE_1
);
249 brw_MOV(p
, get_addr_reg(vtx
), deref_1uw(inlist_ptr
, 0));
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
);
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
);
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
);
269 /* If (vtxOut == 0) vtxOut = vtxPrev
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
);
275 brw_clip_interp_vertex(c
, vtxOut
, vtxPrev
, vtx
, c
->reg
.t
, GL_FALSE
);
277 /* *outlist_ptr++ = vtxOut;
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) );
286 brw_ENDIF(p
, next_test
);
289 prev_test
= brw_ELSE(p
, prev_test
);
291 /* *outlist_ptr++ = vtxPrev;
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));
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
);
304 /* Going out of bounds. Avoid division by zero as we
305 * know dp != dpPrev from DIFFERENT_SIGNS, above.
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
);
311 /* If (vtxOut == 0) vtxOut = vtx
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
);
317 brw_clip_interp_vertex(c
, vtxOut
, vtx
, vtxPrev
, c
->reg
.t
, GL_TRUE
);
319 /* *outlist_ptr++ = vtxOut;
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) );
328 brw_ENDIF(p
, next_test
);
330 brw_ENDIF(p
, prev_test
);
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)));
338 /* while (--loopcount != 0)
340 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
341 brw_ADD(p
, c
->reg
.loopcount
, c
->reg
.loopcount
, brw_imm_d(-1));
343 brw_WHILE(p
, vertex_loop
);
345 /* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1]
347 * inlist_ptr = &inlist[0]
348 * outlist_ptr = &outlist[0]
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
));
356 brw_ENDIF(p
, plane_active
);
360 brw_ADD(p
, get_addr_reg(plane_ptr
), get_addr_reg(plane_ptr
), brw_clip_plane_stride(c
));
365 vec1(brw_null_reg()),
370 /* && (planemask>>=1) != 0
372 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
373 brw_SHR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud(1));
375 brw_WHILE(p
, plane_loop
);
380 void brw_clip_tri_emit_polygon(struct brw_clip_compile
*c
)
382 struct brw_compile
*p
= &c
->func
;
383 struct brw_instruction
*loop
, *if_insn
;
385 /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
387 brw_set_conditionalmod(p
, BRW_CONDITIONAL_G
);
393 if_insn
= brw_IF(p
, BRW_EXECUTE_1
);
395 struct brw_indirect v0
= brw_indirect(0, 0);
396 struct brw_indirect vptr
= brw_indirect(1, 0);
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));
401 brw_clip_emit_vue(c
, v0
, 1, 0, ((_3DPRIM_TRIFAN
<< 2) | R02_PRIM_START
));
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));
406 loop
= brw_DO(p
, BRW_EXECUTE_1
);
408 brw_clip_emit_vue(c
, v0
, 1, 0, (_3DPRIM_TRIFAN
<< 2));
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));
413 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
414 brw_ADD(p
, c
->reg
.loopcount
, c
->reg
.loopcount
, brw_imm_d(-1));
418 brw_clip_emit_vue(c
, v0
, 0, 1, ((_3DPRIM_TRIFAN
<< 2) | R02_PRIM_END
));
420 brw_ENDIF(p
, if_insn
);
423 static void do_clip_tri( struct brw_clip_compile
*c
)
425 brw_clip_init_planes(c
);
431 static void maybe_do_clip_tri( struct brw_clip_compile
*c
)
433 struct brw_compile
*p
= &c
->func
;
434 struct brw_instruction
*do_clip
;
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
);
441 brw_ENDIF(p
, do_clip
);
444 static void brw_clip_test( struct brw_clip_compile
*c
)
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
);
451 struct brw_reg v0
= get_tmp(c
);
452 struct brw_reg v1
= get_tmp(c
);
453 struct brw_reg v2
= get_tmp(c
);
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);
459 struct brw_compile
*p
= &c
->func
;
460 struct brw_instruction
*is_outside
;
461 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
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));
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
);
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
);
489 brw_clip_kill_thread(c
);
491 brw_ENDIF(p
, is_outside
);
492 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
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
);
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
);
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
);
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
);
530 brw_clip_kill_thread(c
);
532 brw_ENDIF(p
, is_outside
);
533 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
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
);
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
);
557 void brw_emit_tri_clip( struct brw_clip_compile
*c
)
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
);
566 /* if -ve rhw workaround bit is set,
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),
572 neg_rhw
= brw_IF(p
, BRW_EXECUTE_1
);
576 brw_ENDIF(p
, neg_rhw
);
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:
582 if (c
->key
.do_flat_shading
)
583 brw_clip_tri_flat_shade(c
);
585 if ((c
->key
.clip_mode
== BRW_CLIPMODE_NORMAL
) ||
586 (c
->key
.clip_mode
== BRW_CLIPMODE_KERNEL_CLIP
))
589 maybe_do_clip_tri(c
);
591 brw_clip_tri_emit_polygon(c
);
593 /* Send an empty message to kill the thread:
595 brw_clip_kill_thread(c
);