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 "program/program.h"
37 #include "intel_batchbuffer.h"
39 #include "brw_defines.h"
40 #include "brw_context.h"
44 static void release_tmps( struct brw_clip_compile
*c
)
46 c
->last_tmp
= c
->first_tmp
;
50 void brw_clip_tri_alloc_regs( struct brw_clip_compile
*c
,
53 struct intel_context
*intel
= &c
->func
.brw
->intel
;
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
->vue_map
.num_slots
% 2) {
78 /* The VUE has an odd number of slots so the last register is only half
79 * used. Fill the second half with zero.
81 for (j
= 0; j
< 3; j
++) {
82 GLuint delta
= brw_vue_slot_to_offset(c
->vue_map
.num_slots
);
84 brw_MOV(&c
->func
, byte_offset(c
->reg
.vertex
[j
], delta
), brw_imm_f(0));
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);
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);
99 c
->reg
.inlist
= brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, i
, 0);
102 c
->reg
.outlist
= brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, i
, 0);
105 c
->reg
.freelist
= brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, i
, 0);
108 if (!c
->key
.nr_userclip
) {
109 c
->reg
.fixed_planes
= brw_vec8_grf(i
, 0);
113 if (c
->key
.do_unfilled
) {
114 c
->reg
.dir
= brw_vec4_grf(i
, 0);
115 c
->reg
.offset
= brw_vec4_grf(i
, 4);
117 c
->reg
.tmp0
= brw_vec4_grf(i
, 0);
118 c
->reg
.tmp1
= brw_vec4_grf(i
, 4);
122 if (intel
->needs_ff_sync
) {
123 c
->reg
.ff_sync
= retype(brw_vec1_grf(i
, 0), BRW_REGISTER_TYPE_UD
);
130 c
->prog_data
.urb_read_length
= c
->nr_regs
; /* ? */
131 c
->prog_data
.total_grf
= i
;
136 void brw_clip_tri_init_vertices( struct brw_clip_compile
*c
)
138 struct brw_compile
*p
= &c
->func
;
139 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
141 /* Initial list of indices for incoming vertexes:
143 brw_AND(p
, tmp0
, get_element_ud(c
->reg
.R0
, 2), brw_imm_ud(PRIM_MASK
));
145 vec1(brw_null_reg()),
148 brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE
));
150 /* XXX: Is there an easier way to do this? Need to reverse every
151 * second tristrip element: Can ignore sometimes?
153 brw_IF(p
, BRW_EXECUTE_1
);
155 brw_MOV(p
, get_element(c
->reg
.inlist
, 0), brw_address(c
->reg
.vertex
[1]) );
156 brw_MOV(p
, get_element(c
->reg
.inlist
, 1), brw_address(c
->reg
.vertex
[0]) );
157 if (c
->need_direction
)
158 brw_MOV(p
, c
->reg
.dir
, brw_imm_f(-1));
162 brw_MOV(p
, get_element(c
->reg
.inlist
, 0), brw_address(c
->reg
.vertex
[0]) );
163 brw_MOV(p
, get_element(c
->reg
.inlist
, 1), brw_address(c
->reg
.vertex
[1]) );
164 if (c
->need_direction
)
165 brw_MOV(p
, c
->reg
.dir
, brw_imm_f(1));
169 brw_MOV(p
, get_element(c
->reg
.inlist
, 2), brw_address(c
->reg
.vertex
[2]) );
170 brw_MOV(p
, brw_vec8_grf(c
->reg
.outlist
.nr
, 0), brw_imm_f(0));
171 brw_MOV(p
, c
->reg
.nr_verts
, brw_imm_ud(3));
176 void brw_clip_tri_flat_shade( struct brw_clip_compile
*c
)
178 struct brw_compile
*p
= &c
->func
;
179 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
181 brw_AND(p
, tmp0
, get_element_ud(c
->reg
.R0
, 2), brw_imm_ud(PRIM_MASK
));
183 vec1(brw_null_reg()),
186 brw_imm_ud(_3DPRIM_POLYGON
));
188 brw_IF(p
, BRW_EXECUTE_1
);
190 brw_clip_copy_colors(c
, 1, 0);
191 brw_clip_copy_colors(c
, 2, 0);
195 if (c
->key
.pv_first
) {
197 vec1(brw_null_reg()),
200 brw_imm_ud(_3DPRIM_TRIFAN
));
201 brw_IF(p
, BRW_EXECUTE_1
);
203 brw_clip_copy_colors(c
, 0, 1);
204 brw_clip_copy_colors(c
, 2, 1);
208 brw_clip_copy_colors(c
, 1, 0);
209 brw_clip_copy_colors(c
, 2, 0);
214 brw_clip_copy_colors(c
, 0, 2);
215 brw_clip_copy_colors(c
, 1, 2);
223 /* Use mesa's clipping algorithms, translated to GEN4 assembly.
225 void brw_clip_tri( struct brw_clip_compile
*c
)
227 struct brw_compile
*p
= &c
->func
;
228 struct brw_indirect vtx
= brw_indirect(0, 0);
229 struct brw_indirect vtxPrev
= brw_indirect(1, 0);
230 struct brw_indirect vtxOut
= brw_indirect(2, 0);
231 struct brw_indirect plane_ptr
= brw_indirect(3, 0);
232 struct brw_indirect inlist_ptr
= brw_indirect(4, 0);
233 struct brw_indirect outlist_ptr
= brw_indirect(5, 0);
234 struct brw_indirect freelist_ptr
= brw_indirect(6, 0);
235 struct brw_instruction
*plane_loop
;
236 struct brw_instruction
*vertex_loop
;
237 GLuint hpos_offset
= brw_vert_result_to_offset(&c
->vue_map
,
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
));
245 brw_MOV(p
, get_addr_reg(freelist_ptr
), brw_address(c
->reg
.vertex
[3]) );
247 plane_loop
= brw_DO(p
, BRW_EXECUTE_1
);
249 /* if (planemask & 1)
251 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
252 brw_AND(p
, vec1(brw_null_reg()), c
->reg
.planemask
, brw_imm_ud(1));
254 brw_IF(p
, BRW_EXECUTE_1
);
256 /* vtxOut = freelist_ptr++
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
));
261 if (c
->key
.nr_userclip
)
262 brw_MOV(p
, c
->reg
.plane_equation
, deref_4f(plane_ptr
, 0));
264 brw_MOV(p
, c
->reg
.plane_equation
, deref_4b(plane_ptr
, 0));
266 brw_MOV(p
, c
->reg
.loopcount
, c
->reg
.nr_verts
);
267 brw_MOV(p
, c
->reg
.nr_verts
, brw_imm_ud(0));
269 vertex_loop
= brw_DO(p
, BRW_EXECUTE_1
);
273 brw_MOV(p
, get_addr_reg(vtx
), deref_1uw(inlist_ptr
, 0));
275 /* IS_NEGATIVE(prev) */
276 brw_set_conditionalmod(p
, BRW_CONDITIONAL_L
);
277 brw_DP4(p
, vec4(c
->reg
.dpPrev
), deref_4f(vtxPrev
, hpos_offset
), c
->reg
.plane_equation
);
278 brw_IF(p
, BRW_EXECUTE_1
);
282 brw_set_conditionalmod(p
, BRW_CONDITIONAL_GE
);
283 brw_DP4(p
, vec4(c
->reg
.dp
), deref_4f(vtx
, hpos_offset
), c
->reg
.plane_equation
);
284 brw_IF(p
, BRW_EXECUTE_1
);
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
);
293 /* If (vtxOut == 0) vtxOut = vtxPrev
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
);
299 brw_clip_interp_vertex(c
, vtxOut
, vtxPrev
, vtx
, c
->reg
.t
, false);
301 /* *outlist_ptr++ = vtxOut;
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) );
315 /* *outlist_ptr++ = vtxPrev;
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));
324 brw_set_conditionalmod(p
, BRW_CONDITIONAL_L
);
325 brw_DP4(p
, vec4(c
->reg
.dp
), deref_4f(vtx
, hpos_offset
), c
->reg
.plane_equation
);
326 brw_IF(p
, BRW_EXECUTE_1
);
328 /* Going out of bounds. Avoid division by zero as we
329 * know dp != dpPrev from DIFFERENT_SIGNS, above.
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
);
335 /* If (vtxOut == 0) vtxOut = vtx
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
);
341 brw_clip_interp_vertex(c
, vtxOut
, vtx
, vtxPrev
, c
->reg
.t
, true);
343 /* *outlist_ptr++ = vtxOut;
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) );
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)));
362 /* while (--loopcount != 0)
364 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
365 brw_ADD(p
, c
->reg
.loopcount
, c
->reg
.loopcount
, brw_imm_d(-1));
367 brw_WHILE(p
, vertex_loop
);
369 /* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1]
371 * inlist_ptr = &inlist[0]
372 * outlist_ptr = &outlist[0]
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
));
384 brw_ADD(p
, get_addr_reg(plane_ptr
), get_addr_reg(plane_ptr
), brw_clip_plane_stride(c
));
389 vec1(brw_null_reg()),
394 /* && (planemask>>=1) != 0
396 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
397 brw_SHR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud(1));
399 brw_WHILE(p
, plane_loop
);
404 void brw_clip_tri_emit_polygon(struct brw_clip_compile
*c
)
406 struct brw_compile
*p
= &c
->func
;
407 struct brw_instruction
*loop
;
409 /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
411 brw_set_conditionalmod(p
, BRW_CONDITIONAL_G
);
417 brw_IF(p
, BRW_EXECUTE_1
);
419 struct brw_indirect v0
= brw_indirect(0, 0);
420 struct brw_indirect vptr
= brw_indirect(1, 0);
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));
425 brw_clip_emit_vue(c
, v0
, 1, 0, ((_3DPRIM_TRIFAN
<< 2) | R02_PRIM_START
));
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));
430 loop
= brw_DO(p
, BRW_EXECUTE_1
);
432 brw_clip_emit_vue(c
, v0
, 1, 0, (_3DPRIM_TRIFAN
<< 2));
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));
437 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
438 brw_ADD(p
, c
->reg
.loopcount
, c
->reg
.loopcount
, brw_imm_d(-1));
442 brw_clip_emit_vue(c
, v0
, 0, 1, ((_3DPRIM_TRIFAN
<< 2) | R02_PRIM_END
));
447 static void do_clip_tri( struct brw_clip_compile
*c
)
449 brw_clip_init_planes(c
);
455 static void maybe_do_clip_tri( struct brw_clip_compile
*c
)
457 struct brw_compile
*p
= &c
->func
;
459 brw_CMP(p
, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ
, c
->reg
.planemask
, brw_imm_ud(0));
460 brw_IF(p
, BRW_EXECUTE_1
);
467 static void brw_clip_test( struct brw_clip_compile
*c
)
469 struct brw_reg t
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
470 struct brw_reg t1
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
471 struct brw_reg t2
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
472 struct brw_reg t3
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
474 struct brw_reg v0
= get_tmp(c
);
475 struct brw_reg v1
= get_tmp(c
);
476 struct brw_reg v2
= get_tmp(c
);
478 struct brw_indirect vt0
= brw_indirect(0, 0);
479 struct brw_indirect vt1
= brw_indirect(1, 0);
480 struct brw_indirect vt2
= brw_indirect(2, 0);
482 struct brw_compile
*p
= &c
->func
;
483 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
485 GLuint hpos_offset
= brw_vert_result_to_offset(&c
->vue_map
,
488 brw_MOV(p
, get_addr_reg(vt0
), brw_address(c
->reg
.vertex
[0]));
489 brw_MOV(p
, get_addr_reg(vt1
), brw_address(c
->reg
.vertex
[1]));
490 brw_MOV(p
, get_addr_reg(vt2
), brw_address(c
->reg
.vertex
[2]));
491 brw_MOV(p
, v0
, deref_4f(vt0
, hpos_offset
));
492 brw_MOV(p
, v1
, deref_4f(vt1
, hpos_offset
));
493 brw_MOV(p
, v2
, deref_4f(vt2
, hpos_offset
));
494 brw_AND(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud(~0x3f));
496 /* test nearz, xmin, ymin plane */
497 /* clip.xyz < -clip.w */
498 brw_CMP(p
, t1
, BRW_CONDITIONAL_L
, v0
, negate(get_element(v0
, 3)));
499 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
500 brw_CMP(p
, t2
, BRW_CONDITIONAL_L
, v1
, negate(get_element(v1
, 3)));
501 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
502 brw_CMP(p
, t3
, BRW_CONDITIONAL_L
, v2
, negate(get_element(v2
, 3)));
503 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
505 /* All vertices are outside of a plane, rejected */
506 brw_AND(p
, t
, t1
, t2
);
507 brw_AND(p
, t
, t
, t3
);
508 brw_OR(p
, tmp0
, get_element(t
, 0), get_element(t
, 1));
509 brw_OR(p
, tmp0
, tmp0
, get_element(t
, 2));
510 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
511 brw_AND(p
, brw_null_reg(), tmp0
, brw_imm_ud(0x1));
512 brw_IF(p
, BRW_EXECUTE_1
);
514 brw_clip_kill_thread(c
);
517 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
519 /* some vertices are inside a plane, some are outside,need to clip */
520 brw_XOR(p
, t
, t1
, t2
);
521 brw_XOR(p
, t1
, t2
, t3
);
523 brw_AND(p
, t
, t
, brw_imm_ud(0x1));
524 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
525 get_element(t
, 0), brw_imm_ud(0));
526 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<5)));
527 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
528 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
529 get_element(t
, 1), brw_imm_ud(0));
530 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<3)));
531 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
532 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
533 get_element(t
, 2), brw_imm_ud(0));
534 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<1)));
535 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
537 /* test farz, xmax, ymax plane */
538 /* clip.xyz > clip.w */
539 brw_CMP(p
, t1
, BRW_CONDITIONAL_G
, v0
, get_element(v0
, 3));
540 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
541 brw_CMP(p
, t2
, BRW_CONDITIONAL_G
, v1
, get_element(v1
, 3));
542 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
543 brw_CMP(p
, t3
, BRW_CONDITIONAL_G
, v2
, get_element(v2
, 3));
544 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
546 /* All vertices are outside of a plane, rejected */
547 brw_AND(p
, t
, t1
, t2
);
548 brw_AND(p
, t
, t
, t3
);
549 brw_OR(p
, tmp0
, get_element(t
, 0), get_element(t
, 1));
550 brw_OR(p
, tmp0
, tmp0
, get_element(t
, 2));
551 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
552 brw_AND(p
, brw_null_reg(), tmp0
, brw_imm_ud(0x1));
553 brw_IF(p
, BRW_EXECUTE_1
);
555 brw_clip_kill_thread(c
);
558 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
560 /* some vertices are inside a plane, some are outside,need to clip */
561 brw_XOR(p
, t
, t1
, t2
);
562 brw_XOR(p
, t1
, t2
, t3
);
564 brw_AND(p
, t
, t
, brw_imm_ud(0x1));
565 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
566 get_element(t
, 0), brw_imm_ud(0));
567 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<4)));
568 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
569 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
570 get_element(t
, 1), brw_imm_ud(0));
571 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<2)));
572 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
573 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
574 get_element(t
, 2), brw_imm_ud(0));
575 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<0)));
576 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
582 void brw_emit_tri_clip( struct brw_clip_compile
*c
)
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
);
591 /* if -ve rhw workaround bit is set,
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),
597 brw_IF(p
, BRW_EXECUTE_1
);
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:
607 if (c
->key
.do_flat_shading
)
608 brw_clip_tri_flat_shade(c
);
610 if ((c
->key
.clip_mode
== BRW_CLIPMODE_NORMAL
) ||
611 (c
->key
.clip_mode
== BRW_CLIPMODE_KERNEL_CLIP
))
614 maybe_do_clip_tri(c
);
616 brw_clip_tri_emit_polygon(c
);
618 /* Send an empty message to kill the thread:
620 brw_clip_kill_thread(c
);