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 "main/glheader.h"
33 #include "main/macros.h"
34 #include "main/enums.h"
35 #include "shader/program.h"
37 #include "intel_batchbuffer.h"
39 #include "brw_defines.h"
40 #include "brw_context.h"
45 static void release_tmps( struct brw_clip_compile
*c
)
47 c
->last_tmp
= c
->first_tmp
;
51 void brw_clip_tri_alloc_regs( struct brw_clip_compile
*c
,
56 /* Register usage is static, precompute here:
58 c
->reg
.R0
= retype(brw_vec8_grf(i
, 0), BRW_REGISTER_TYPE_UD
); i
++;
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;
64 c
->prog_data
.curb_read_length
= (6 + c
->key
.nr_userclip
+ 1) / 2;
67 c
->prog_data
.curb_read_length
= 0;
70 /* Payload vertices plus space for more generated vertices:
72 for (j
= 0; j
< nr_verts
; j
++) {
73 c
->reg
.vertex
[j
] = brw_vec4_grf(i
, 0);
77 if (c
->nr_attrs
& 1) {
78 for (j
= 0; j
< 3; j
++) {
79 GLuint delta
= c
->nr_attrs
*16 + 32;
80 brw_MOV(&c
->func
, byte_offset(c
->reg
.vertex
[j
], delta
), brw_imm_f(0));
84 c
->reg
.t
= brw_vec1_grf(i
, 0);
85 c
->reg
.loopcount
= retype(brw_vec1_grf(i
, 1), BRW_REGISTER_TYPE_D
);
86 c
->reg
.nr_verts
= retype(brw_vec1_grf(i
, 2), BRW_REGISTER_TYPE_UD
);
87 c
->reg
.planemask
= retype(brw_vec1_grf(i
, 3), BRW_REGISTER_TYPE_UD
);
88 c
->reg
.plane_equation
= brw_vec4_grf(i
, 4);
91 c
->reg
.dpPrev
= brw_vec1_grf(i
, 0); /* fixme - dp4 will clobber r.1,2,3 */
92 c
->reg
.dp
= brw_vec1_grf(i
, 4);
95 c
->reg
.inlist
= brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, i
, 0);
98 c
->reg
.outlist
= brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, i
, 0);
101 c
->reg
.freelist
= brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, i
, 0);
104 if (!c
->key
.nr_userclip
) {
105 c
->reg
.fixed_planes
= brw_vec8_grf(i
, 0);
109 if (c
->key
.do_unfilled
) {
110 c
->reg
.dir
= brw_vec4_grf(i
, 0);
111 c
->reg
.offset
= brw_vec4_grf(i
, 4);
113 c
->reg
.tmp0
= brw_vec4_grf(i
, 0);
114 c
->reg
.tmp1
= brw_vec4_grf(i
, 4);
121 c
->prog_data
.urb_read_length
= c
->nr_regs
; /* ? */
122 c
->prog_data
.total_grf
= i
;
127 void brw_clip_tri_init_vertices( struct brw_clip_compile
*c
)
129 struct brw_compile
*p
= &c
->func
;
130 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
131 struct brw_instruction
*is_rev
;
133 /* Initial list of indices for incoming vertexes:
135 brw_AND(p
, tmp0
, get_element_ud(c
->reg
.R0
, 2), brw_imm_ud(PRIM_MASK
));
137 vec1(brw_null_reg()),
140 brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE
));
142 /* XXX: Is there an easier way to do this? Need to reverse every
143 * second tristrip element: Can ignore sometimes?
145 is_rev
= brw_IF(p
, BRW_EXECUTE_1
);
147 brw_MOV(p
, get_element(c
->reg
.inlist
, 0), brw_address(c
->reg
.vertex
[1]) );
148 brw_MOV(p
, get_element(c
->reg
.inlist
, 1), brw_address(c
->reg
.vertex
[0]) );
149 if (c
->need_direction
)
150 brw_MOV(p
, c
->reg
.dir
, brw_imm_f(-1));
152 is_rev
= brw_ELSE(p
, is_rev
);
154 brw_MOV(p
, get_element(c
->reg
.inlist
, 0), brw_address(c
->reg
.vertex
[0]) );
155 brw_MOV(p
, get_element(c
->reg
.inlist
, 1), brw_address(c
->reg
.vertex
[1]) );
156 if (c
->need_direction
)
157 brw_MOV(p
, c
->reg
.dir
, brw_imm_f(1));
159 brw_ENDIF(p
, is_rev
);
161 brw_MOV(p
, get_element(c
->reg
.inlist
, 2), brw_address(c
->reg
.vertex
[2]) );
162 brw_MOV(p
, brw_vec8_grf(c
->reg
.outlist
.nr
, 0), brw_imm_f(0));
163 brw_MOV(p
, c
->reg
.nr_verts
, brw_imm_ud(3));
168 void brw_clip_tri_flat_shade( struct brw_clip_compile
*c
)
170 struct brw_compile
*p
= &c
->func
;
171 struct brw_instruction
*is_poly
;
172 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
174 brw_AND(p
, tmp0
, get_element_ud(c
->reg
.R0
, 2), brw_imm_ud(PRIM_MASK
));
176 vec1(brw_null_reg()),
179 brw_imm_ud(_3DPRIM_POLYGON
));
181 is_poly
= brw_IF(p
, BRW_EXECUTE_1
);
183 brw_clip_copy_colors(c
, 1, 0);
184 brw_clip_copy_colors(c
, 2, 0);
186 is_poly
= brw_ELSE(p
, is_poly
);
188 brw_clip_copy_colors(c
, 0, 2);
189 brw_clip_copy_colors(c
, 1, 2);
191 brw_ENDIF(p
, is_poly
);
196 /* Use mesa's clipping algorithms, translated to GEN4 assembly.
198 void brw_clip_tri( struct brw_clip_compile
*c
)
200 struct brw_compile
*p
= &c
->func
;
201 struct brw_indirect vtx
= brw_indirect(0, 0);
202 struct brw_indirect vtxPrev
= brw_indirect(1, 0);
203 struct brw_indirect vtxOut
= brw_indirect(2, 0);
204 struct brw_indirect plane_ptr
= brw_indirect(3, 0);
205 struct brw_indirect inlist_ptr
= brw_indirect(4, 0);
206 struct brw_indirect outlist_ptr
= brw_indirect(5, 0);
207 struct brw_indirect freelist_ptr
= brw_indirect(6, 0);
208 struct brw_instruction
*plane_loop
;
209 struct brw_instruction
*plane_active
;
210 struct brw_instruction
*vertex_loop
;
211 struct brw_instruction
*next_test
;
212 struct brw_instruction
*prev_test
;
214 brw_MOV(p
, get_addr_reg(vtxPrev
), brw_address(c
->reg
.vertex
[2]) );
215 brw_MOV(p
, get_addr_reg(plane_ptr
), brw_clip_plane0_address(c
));
216 brw_MOV(p
, get_addr_reg(inlist_ptr
), brw_address(c
->reg
.inlist
));
217 brw_MOV(p
, get_addr_reg(outlist_ptr
), brw_address(c
->reg
.outlist
));
219 brw_MOV(p
, get_addr_reg(freelist_ptr
), brw_address(c
->reg
.vertex
[3]) );
221 plane_loop
= brw_DO(p
, BRW_EXECUTE_1
);
223 /* if (planemask & 1)
225 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
226 brw_AND(p
, vec1(brw_null_reg()), c
->reg
.planemask
, brw_imm_ud(1));
228 plane_active
= brw_IF(p
, BRW_EXECUTE_1
);
230 /* vtxOut = freelist_ptr++
232 brw_MOV(p
, get_addr_reg(vtxOut
), get_addr_reg(freelist_ptr
) );
233 brw_ADD(p
, get_addr_reg(freelist_ptr
), get_addr_reg(freelist_ptr
), brw_imm_uw(c
->nr_regs
* REG_SIZE
));
235 if (c
->key
.nr_userclip
)
236 brw_MOV(p
, c
->reg
.plane_equation
, deref_4f(plane_ptr
, 0));
238 brw_MOV(p
, c
->reg
.plane_equation
, deref_4b(plane_ptr
, 0));
240 brw_MOV(p
, c
->reg
.loopcount
, c
->reg
.nr_verts
);
241 brw_MOV(p
, c
->reg
.nr_verts
, brw_imm_ud(0));
243 vertex_loop
= brw_DO(p
, BRW_EXECUTE_1
);
247 brw_MOV(p
, get_addr_reg(vtx
), deref_1uw(inlist_ptr
, 0));
249 /* IS_NEGATIVE(prev) */
250 brw_set_conditionalmod(p
, BRW_CONDITIONAL_L
);
251 brw_DP4(p
, vec4(c
->reg
.dpPrev
), deref_4f(vtxPrev
, c
->offset
[VERT_RESULT_HPOS
]), c
->reg
.plane_equation
);
252 prev_test
= brw_IF(p
, BRW_EXECUTE_1
);
256 brw_set_conditionalmod(p
, BRW_CONDITIONAL_GE
);
257 brw_DP4(p
, vec4(c
->reg
.dp
), deref_4f(vtx
, c
->offset
[VERT_RESULT_HPOS
]), c
->reg
.plane_equation
);
258 next_test
= brw_IF(p
, BRW_EXECUTE_1
);
263 brw_ADD(p
, c
->reg
.t
, c
->reg
.dpPrev
, negate(c
->reg
.dp
));
264 brw_math_invert(p
, c
->reg
.t
, c
->reg
.t
);
265 brw_MUL(p
, c
->reg
.t
, c
->reg
.t
, c
->reg
.dpPrev
);
267 /* If (vtxOut == 0) vtxOut = vtxPrev
269 brw_CMP(p
, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
270 brw_MOV(p
, get_addr_reg(vtxOut
), get_addr_reg(vtxPrev
) );
271 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
273 brw_clip_interp_vertex(c
, vtxOut
, vtxPrev
, vtx
, c
->reg
.t
, GL_FALSE
);
275 /* *outlist_ptr++ = vtxOut;
279 brw_MOV(p
, deref_1uw(outlist_ptr
, 0), get_addr_reg(vtxOut
));
280 brw_ADD(p
, get_addr_reg(outlist_ptr
), get_addr_reg(outlist_ptr
), brw_imm_uw(sizeof(short)));
281 brw_ADD(p
, c
->reg
.nr_verts
, c
->reg
.nr_verts
, brw_imm_ud(1));
282 brw_MOV(p
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
284 brw_ENDIF(p
, next_test
);
287 prev_test
= brw_ELSE(p
, prev_test
);
289 /* *outlist_ptr++ = vtxPrev;
292 brw_MOV(p
, deref_1uw(outlist_ptr
, 0), get_addr_reg(vtxPrev
));
293 brw_ADD(p
, get_addr_reg(outlist_ptr
), get_addr_reg(outlist_ptr
), brw_imm_uw(sizeof(short)));
294 brw_ADD(p
, c
->reg
.nr_verts
, c
->reg
.nr_verts
, brw_imm_ud(1));
298 brw_set_conditionalmod(p
, BRW_CONDITIONAL_L
);
299 brw_DP4(p
, vec4(c
->reg
.dp
), deref_4f(vtx
, c
->offset
[VERT_RESULT_HPOS
]), c
->reg
.plane_equation
);
300 next_test
= brw_IF(p
, BRW_EXECUTE_1
);
302 /* Going out of bounds. Avoid division by zero as we
303 * know dp != dpPrev from DIFFERENT_SIGNS, above.
305 brw_ADD(p
, c
->reg
.t
, c
->reg
.dp
, negate(c
->reg
.dpPrev
));
306 brw_math_invert(p
, c
->reg
.t
, c
->reg
.t
);
307 brw_MUL(p
, c
->reg
.t
, c
->reg
.t
, c
->reg
.dp
);
309 /* If (vtxOut == 0) vtxOut = vtx
311 brw_CMP(p
, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
312 brw_MOV(p
, get_addr_reg(vtxOut
), get_addr_reg(vtx
) );
313 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
315 brw_clip_interp_vertex(c
, vtxOut
, vtx
, vtxPrev
, c
->reg
.t
, GL_TRUE
);
317 /* *outlist_ptr++ = vtxOut;
321 brw_MOV(p
, deref_1uw(outlist_ptr
, 0), get_addr_reg(vtxOut
));
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 brw_MOV(p
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
326 brw_ENDIF(p
, next_test
);
328 brw_ENDIF(p
, prev_test
);
333 brw_MOV(p
, get_addr_reg(vtxPrev
), get_addr_reg(vtx
));
334 brw_ADD(p
, get_addr_reg(inlist_ptr
), get_addr_reg(inlist_ptr
), brw_imm_uw(sizeof(short)));
336 /* while (--loopcount != 0)
338 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
339 brw_ADD(p
, c
->reg
.loopcount
, c
->reg
.loopcount
, brw_imm_d(-1));
341 brw_WHILE(p
, vertex_loop
);
343 /* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1]
345 * inlist_ptr = &inlist[0]
346 * outlist_ptr = &outlist[0]
348 brw_ADD(p
, get_addr_reg(outlist_ptr
), get_addr_reg(outlist_ptr
), brw_imm_w(-2));
349 brw_MOV(p
, get_addr_reg(vtxPrev
), deref_1uw(outlist_ptr
, 0));
350 brw_MOV(p
, brw_vec8_grf(c
->reg
.inlist
.nr
, 0), brw_vec8_grf(c
->reg
.outlist
.nr
, 0));
351 brw_MOV(p
, get_addr_reg(inlist_ptr
), brw_address(c
->reg
.inlist
));
352 brw_MOV(p
, get_addr_reg(outlist_ptr
), brw_address(c
->reg
.outlist
));
354 brw_ENDIF(p
, plane_active
);
358 brw_ADD(p
, get_addr_reg(plane_ptr
), get_addr_reg(plane_ptr
), brw_clip_plane_stride(c
));
363 vec1(brw_null_reg()),
368 /* && (planemask>>=1) != 0
370 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
371 brw_SHR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud(1));
373 brw_WHILE(p
, plane_loop
);
378 void brw_clip_tri_emit_polygon(struct brw_clip_compile
*c
)
380 struct brw_compile
*p
= &c
->func
;
381 struct brw_instruction
*loop
, *if_insn
;
383 /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
385 brw_set_conditionalmod(p
, BRW_CONDITIONAL_G
);
391 if_insn
= brw_IF(p
, BRW_EXECUTE_1
);
393 struct brw_indirect v0
= brw_indirect(0, 0);
394 struct brw_indirect vptr
= brw_indirect(1, 0);
396 brw_MOV(p
, get_addr_reg(vptr
), brw_address(c
->reg
.inlist
));
397 brw_MOV(p
, get_addr_reg(v0
), deref_1uw(vptr
, 0));
399 brw_clip_emit_vue(c
, v0
, 1, 0, ((_3DPRIM_TRIFAN
<< 2) | R02_PRIM_START
));
401 brw_ADD(p
, get_addr_reg(vptr
), get_addr_reg(vptr
), brw_imm_uw(2));
402 brw_MOV(p
, get_addr_reg(v0
), deref_1uw(vptr
, 0));
404 loop
= brw_DO(p
, BRW_EXECUTE_1
);
406 brw_clip_emit_vue(c
, v0
, 1, 0, (_3DPRIM_TRIFAN
<< 2));
408 brw_ADD(p
, get_addr_reg(vptr
), get_addr_reg(vptr
), brw_imm_uw(2));
409 brw_MOV(p
, get_addr_reg(v0
), deref_1uw(vptr
, 0));
411 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
412 brw_ADD(p
, c
->reg
.loopcount
, c
->reg
.loopcount
, brw_imm_d(-1));
416 brw_clip_emit_vue(c
, v0
, 0, 1, ((_3DPRIM_TRIFAN
<< 2) | R02_PRIM_END
));
418 brw_ENDIF(p
, if_insn
);
421 static void do_clip_tri( struct brw_clip_compile
*c
)
423 brw_clip_init_planes(c
);
429 static void maybe_do_clip_tri( struct brw_clip_compile
*c
)
431 struct brw_compile
*p
= &c
->func
;
432 struct brw_instruction
*do_clip
;
434 brw_CMP(p
, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ
, c
->reg
.planemask
, brw_imm_ud(0));
435 do_clip
= brw_IF(p
, BRW_EXECUTE_1
);
439 brw_ENDIF(p
, do_clip
);
442 static void brw_clip_test( struct brw_clip_compile
*c
)
444 struct brw_reg t
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
445 struct brw_reg t1
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
446 struct brw_reg t2
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
447 struct brw_reg t3
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
449 struct brw_reg v0
= get_tmp(c
);
450 struct brw_reg v1
= get_tmp(c
);
451 struct brw_reg v2
= get_tmp(c
);
453 struct brw_indirect vt0
= brw_indirect(0, 0);
454 struct brw_indirect vt1
= brw_indirect(1, 0);
455 struct brw_indirect vt2
= brw_indirect(2, 0);
457 struct brw_compile
*p
= &c
->func
;
458 struct brw_instruction
*is_outside
;
459 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
461 brw_MOV(p
, get_addr_reg(vt0
), brw_address(c
->reg
.vertex
[0]));
462 brw_MOV(p
, get_addr_reg(vt1
), brw_address(c
->reg
.vertex
[1]));
463 brw_MOV(p
, get_addr_reg(vt2
), brw_address(c
->reg
.vertex
[2]));
464 brw_MOV(p
, v0
, deref_4f(vt0
, c
->offset
[VERT_RESULT_HPOS
]));
465 brw_MOV(p
, v1
, deref_4f(vt1
, c
->offset
[VERT_RESULT_HPOS
]));
466 brw_MOV(p
, v2
, deref_4f(vt2
, c
->offset
[VERT_RESULT_HPOS
]));
467 brw_AND(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud(~0x3f));
469 /* test nearz, xmin, ymin plane */
470 /* clip.xyz < -clip.w */
471 brw_CMP(p
, t1
, BRW_CONDITIONAL_L
, v0
, negate(get_element(v0
, 3)));
472 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
473 brw_CMP(p
, t2
, BRW_CONDITIONAL_L
, v1
, negate(get_element(v1
, 3)));
474 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
475 brw_CMP(p
, t3
, BRW_CONDITIONAL_L
, v2
, negate(get_element(v2
, 3)));
476 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
478 /* All vertices are outside of a plane, rejected */
479 brw_AND(p
, t
, t1
, t2
);
480 brw_AND(p
, t
, t
, t3
);
481 brw_OR(p
, tmp0
, get_element(t
, 0), get_element(t
, 1));
482 brw_OR(p
, tmp0
, tmp0
, get_element(t
, 2));
483 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
484 brw_AND(p
, brw_null_reg(), tmp0
, brw_imm_ud(0x1));
485 is_outside
= brw_IF(p
, BRW_EXECUTE_1
);
487 brw_clip_kill_thread(c
);
489 brw_ENDIF(p
, is_outside
);
490 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
492 /* some vertices are inside a plane, some are outside,need to clip */
493 brw_XOR(p
, t
, t1
, t2
);
494 brw_XOR(p
, t1
, t2
, t3
);
496 brw_AND(p
, t
, t
, brw_imm_ud(0x1));
497 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
498 get_element(t
, 0), brw_imm_ud(0));
499 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<5)));
500 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
501 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
502 get_element(t
, 1), brw_imm_ud(0));
503 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<3)));
504 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
505 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
506 get_element(t
, 2), brw_imm_ud(0));
507 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<1)));
508 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
510 /* test farz, xmax, ymax plane */
511 /* clip.xyz > clip.w */
512 brw_CMP(p
, t1
, BRW_CONDITIONAL_G
, v0
, get_element(v0
, 3));
513 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
514 brw_CMP(p
, t2
, BRW_CONDITIONAL_G
, v1
, get_element(v1
, 3));
515 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
516 brw_CMP(p
, t3
, BRW_CONDITIONAL_G
, v2
, get_element(v2
, 3));
517 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
519 /* All vertices are outside of a plane, rejected */
520 brw_AND(p
, t
, t1
, t2
);
521 brw_AND(p
, t
, t
, t3
);
522 brw_OR(p
, tmp0
, get_element(t
, 0), get_element(t
, 1));
523 brw_OR(p
, tmp0
, tmp0
, get_element(t
, 2));
524 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
525 brw_AND(p
, brw_null_reg(), tmp0
, brw_imm_ud(0x1));
526 is_outside
= brw_IF(p
, BRW_EXECUTE_1
);
528 brw_clip_kill_thread(c
);
530 brw_ENDIF(p
, is_outside
);
531 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
533 /* some vertices are inside a plane, some are outside,need to clip */
534 brw_XOR(p
, t
, t1
, t2
);
535 brw_XOR(p
, t1
, t2
, t3
);
537 brw_AND(p
, t
, t
, brw_imm_ud(0x1));
538 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
539 get_element(t
, 0), brw_imm_ud(0));
540 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<4)));
541 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
542 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
543 get_element(t
, 1), brw_imm_ud(0));
544 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<2)));
545 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
546 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
547 get_element(t
, 2), brw_imm_ud(0));
548 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<0)));
549 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
555 void brw_emit_tri_clip( struct brw_clip_compile
*c
)
557 struct brw_instruction
*neg_rhw
;
558 struct brw_compile
*p
= &c
->func
;
559 brw_clip_tri_alloc_regs(c
, 3 + c
->key
.nr_userclip
+ 6);
560 brw_clip_tri_init_vertices(c
);
561 brw_clip_init_clipmask(c
);
563 /* if -ve rhw workaround bit is set,
565 if (!BRW_IS_G4X(p
->brw
)) {
566 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
567 brw_AND(p
, brw_null_reg(), get_element_ud(c
->reg
.R0
, 2),
569 neg_rhw
= brw_IF(p
, BRW_EXECUTE_1
);
573 brw_ENDIF(p
, neg_rhw
);
575 /* Can't push into do_clip_tri because with polygon (or quad)
576 * flatshading, need to apply the flatshade here because we don't
577 * respect the PV when converting to trifan for emit:
579 if (c
->key
.do_flat_shading
)
580 brw_clip_tri_flat_shade(c
);
582 if (c
->key
.clip_mode
== BRW_CLIPMODE_NORMAL
)
585 maybe_do_clip_tri(c
);
587 brw_clip_tri_emit_polygon(c
);
589 /* Send an empty message to kill the thread:
591 brw_clip_kill_thread(c
);