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 c
->reg
.vertex_src_mask
= retype(brw_vec1_grf(i
, 0), BRW_REGISTER_TYPE_UD
);
125 if (intel
->needs_ff_sync
) {
126 c
->reg
.ff_sync
= retype(brw_vec1_grf(i
, 0), BRW_REGISTER_TYPE_UD
);
133 c
->prog_data
.urb_read_length
= c
->nr_regs
; /* ? */
134 c
->prog_data
.total_grf
= i
;
139 void brw_clip_tri_init_vertices( struct brw_clip_compile
*c
)
141 struct brw_compile
*p
= &c
->func
;
142 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
144 /* Initial list of indices for incoming vertexes:
146 brw_AND(p
, tmp0
, get_element_ud(c
->reg
.R0
, 2), brw_imm_ud(PRIM_MASK
));
148 vec1(brw_null_reg()),
151 brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE
));
153 /* XXX: Is there an easier way to do this? Need to reverse every
154 * second tristrip element: Can ignore sometimes?
156 brw_IF(p
, BRW_EXECUTE_1
);
158 brw_MOV(p
, get_element(c
->reg
.inlist
, 0), brw_address(c
->reg
.vertex
[1]) );
159 brw_MOV(p
, get_element(c
->reg
.inlist
, 1), brw_address(c
->reg
.vertex
[0]) );
160 if (c
->need_direction
)
161 brw_MOV(p
, c
->reg
.dir
, brw_imm_f(-1));
165 brw_MOV(p
, get_element(c
->reg
.inlist
, 0), brw_address(c
->reg
.vertex
[0]) );
166 brw_MOV(p
, get_element(c
->reg
.inlist
, 1), brw_address(c
->reg
.vertex
[1]) );
167 if (c
->need_direction
)
168 brw_MOV(p
, c
->reg
.dir
, brw_imm_f(1));
172 brw_MOV(p
, get_element(c
->reg
.inlist
, 2), brw_address(c
->reg
.vertex
[2]) );
173 brw_MOV(p
, brw_vec8_grf(c
->reg
.outlist
.nr
, 0), brw_imm_f(0));
174 brw_MOV(p
, c
->reg
.nr_verts
, brw_imm_ud(3));
179 void brw_clip_tri_flat_shade( struct brw_clip_compile
*c
)
181 struct brw_compile
*p
= &c
->func
;
182 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
184 brw_AND(p
, tmp0
, get_element_ud(c
->reg
.R0
, 2), brw_imm_ud(PRIM_MASK
));
186 vec1(brw_null_reg()),
189 brw_imm_ud(_3DPRIM_POLYGON
));
191 brw_IF(p
, BRW_EXECUTE_1
);
193 brw_clip_copy_colors(c
, 1, 0);
194 brw_clip_copy_colors(c
, 2, 0);
198 if (c
->key
.pv_first
) {
200 vec1(brw_null_reg()),
203 brw_imm_ud(_3DPRIM_TRIFAN
));
204 brw_IF(p
, BRW_EXECUTE_1
);
206 brw_clip_copy_colors(c
, 0, 1);
207 brw_clip_copy_colors(c
, 2, 1);
211 brw_clip_copy_colors(c
, 1, 0);
212 brw_clip_copy_colors(c
, 2, 0);
217 brw_clip_copy_colors(c
, 0, 2);
218 brw_clip_copy_colors(c
, 1, 2);
226 load_vertex_pos(struct brw_clip_compile
*c
, struct brw_indirect vtx
,
228 GLuint hpos_offset
, GLuint clip_offset
)
230 struct brw_compile
*p
= &c
->func
;
234 * dst = (vertex_src_mask & 1) ? src.hpos : src.clipvertex;
237 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
238 brw_AND(p
, vec1(brw_null_reg()), c
->reg
.vertex_src_mask
, brw_imm_ud(1));
239 brw_IF(p
, BRW_EXECUTE_1
);
241 brw_MOV(p
, dst
, deref_4f(vtx
, clip_offset
));
245 brw_MOV(p
, dst
, deref_4f(vtx
, hpos_offset
));
251 /* Use mesa's clipping algorithms, translated to GEN4 assembly.
253 void brw_clip_tri( struct brw_clip_compile
*c
)
255 struct brw_compile
*p
= &c
->func
;
256 struct brw_indirect vtx
= brw_indirect(0, 0);
257 struct brw_indirect vtxPrev
= brw_indirect(1, 0);
258 struct brw_indirect vtxOut
= brw_indirect(2, 0);
259 struct brw_indirect plane_ptr
= brw_indirect(3, 0);
260 struct brw_indirect inlist_ptr
= brw_indirect(4, 0);
261 struct brw_indirect outlist_ptr
= brw_indirect(5, 0);
262 struct brw_indirect freelist_ptr
= brw_indirect(6, 0);
263 GLuint hpos_offset
= brw_varying_to_offset(&c
->vue_map
, VARYING_SLOT_POS
);
264 GLuint clipvert_offset
= brw_clip_have_varying(c
, VARYING_SLOT_CLIP_VERTEX
)
265 ? brw_varying_to_offset(&c
->vue_map
, VARYING_SLOT_CLIP_VERTEX
)
268 brw_MOV(p
, get_addr_reg(vtxPrev
), brw_address(c
->reg
.vertex
[2]) );
269 brw_MOV(p
, get_addr_reg(plane_ptr
), brw_clip_plane0_address(c
));
270 brw_MOV(p
, get_addr_reg(inlist_ptr
), brw_address(c
->reg
.inlist
));
271 brw_MOV(p
, get_addr_reg(outlist_ptr
), brw_address(c
->reg
.outlist
));
273 brw_MOV(p
, get_addr_reg(freelist_ptr
), brw_address(c
->reg
.vertex
[3]) );
275 /* Set the initial vertex source mask: The first 6 planes are the bounds
276 * of the view volume; the next 6 planes are the user clipping planes.
278 brw_MOV(p
, c
->reg
.vertex_src_mask
, brw_imm_ud(0xfc0));
280 brw_DO(p
, BRW_EXECUTE_1
);
282 /* if (planemask & 1)
284 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
285 brw_AND(p
, vec1(brw_null_reg()), c
->reg
.planemask
, brw_imm_ud(1));
287 brw_IF(p
, BRW_EXECUTE_1
);
289 /* vtxOut = freelist_ptr++
291 brw_MOV(p
, get_addr_reg(vtxOut
), get_addr_reg(freelist_ptr
) );
292 brw_ADD(p
, get_addr_reg(freelist_ptr
), get_addr_reg(freelist_ptr
), brw_imm_uw(c
->nr_regs
* REG_SIZE
));
294 if (c
->key
.nr_userclip
)
295 brw_MOV(p
, c
->reg
.plane_equation
, deref_4f(plane_ptr
, 0));
297 brw_MOV(p
, c
->reg
.plane_equation
, deref_4b(plane_ptr
, 0));
299 brw_MOV(p
, c
->reg
.loopcount
, c
->reg
.nr_verts
);
300 brw_MOV(p
, c
->reg
.nr_verts
, brw_imm_ud(0));
302 brw_DO(p
, BRW_EXECUTE_1
);
306 brw_MOV(p
, get_addr_reg(vtx
), deref_1uw(inlist_ptr
, 0));
308 load_vertex_pos(c
, vtxPrev
, vec4(c
->reg
.dpPrev
), hpos_offset
, clipvert_offset
);
309 /* IS_NEGATIVE(prev) */
310 brw_set_conditionalmod(p
, BRW_CONDITIONAL_L
);
311 brw_DP4(p
, vec4(c
->reg
.dpPrev
), vec4(c
->reg
.dpPrev
), c
->reg
.plane_equation
);
312 brw_IF(p
, BRW_EXECUTE_1
);
314 load_vertex_pos(c
, vtx
, vec4(c
->reg
.dp
), hpos_offset
, clipvert_offset
);
317 brw_set_conditionalmod(p
, BRW_CONDITIONAL_GE
);
318 brw_DP4(p
, vec4(c
->reg
.dp
), vec4(c
->reg
.dp
), c
->reg
.plane_equation
);
319 brw_IF(p
, BRW_EXECUTE_1
);
324 brw_ADD(p
, c
->reg
.t
, c
->reg
.dpPrev
, negate(c
->reg
.dp
));
325 brw_math_invert(p
, c
->reg
.t
, c
->reg
.t
);
326 brw_MUL(p
, c
->reg
.t
, c
->reg
.t
, c
->reg
.dpPrev
);
328 /* If (vtxOut == 0) vtxOut = vtxPrev
330 brw_CMP(p
, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
331 brw_MOV(p
, get_addr_reg(vtxOut
), get_addr_reg(vtxPrev
) );
332 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
334 brw_clip_interp_vertex(c
, vtxOut
, vtxPrev
, vtx
, c
->reg
.t
, false);
336 /* *outlist_ptr++ = vtxOut;
340 brw_MOV(p
, deref_1uw(outlist_ptr
, 0), get_addr_reg(vtxOut
));
341 brw_ADD(p
, get_addr_reg(outlist_ptr
), get_addr_reg(outlist_ptr
), brw_imm_uw(sizeof(short)));
342 brw_ADD(p
, c
->reg
.nr_verts
, c
->reg
.nr_verts
, brw_imm_ud(1));
343 brw_MOV(p
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
350 /* *outlist_ptr++ = vtxPrev;
353 brw_MOV(p
, deref_1uw(outlist_ptr
, 0), get_addr_reg(vtxPrev
));
354 brw_ADD(p
, get_addr_reg(outlist_ptr
), get_addr_reg(outlist_ptr
), brw_imm_uw(sizeof(short)));
355 brw_ADD(p
, c
->reg
.nr_verts
, c
->reg
.nr_verts
, brw_imm_ud(1));
357 load_vertex_pos(c
, vtx
, vec4(c
->reg
.dp
), hpos_offset
, clipvert_offset
);
360 brw_set_conditionalmod(p
, BRW_CONDITIONAL_L
);
361 brw_DP4(p
, vec4(c
->reg
.dp
), vec4(c
->reg
.dp
), c
->reg
.plane_equation
);
362 brw_IF(p
, BRW_EXECUTE_1
);
364 /* Going out of bounds. Avoid division by zero as we
365 * know dp != dpPrev from DIFFERENT_SIGNS, above.
367 brw_ADD(p
, c
->reg
.t
, c
->reg
.dp
, negate(c
->reg
.dpPrev
));
368 brw_math_invert(p
, c
->reg
.t
, c
->reg
.t
);
369 brw_MUL(p
, c
->reg
.t
, c
->reg
.t
, c
->reg
.dp
);
371 /* If (vtxOut == 0) vtxOut = vtx
373 brw_CMP(p
, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
374 brw_MOV(p
, get_addr_reg(vtxOut
), get_addr_reg(vtx
) );
375 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
377 brw_clip_interp_vertex(c
, vtxOut
, vtx
, vtxPrev
, c
->reg
.t
, true);
379 /* *outlist_ptr++ = vtxOut;
383 brw_MOV(p
, deref_1uw(outlist_ptr
, 0), get_addr_reg(vtxOut
));
384 brw_ADD(p
, get_addr_reg(outlist_ptr
), get_addr_reg(outlist_ptr
), brw_imm_uw(sizeof(short)));
385 brw_ADD(p
, c
->reg
.nr_verts
, c
->reg
.nr_verts
, brw_imm_ud(1));
386 brw_MOV(p
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
395 brw_MOV(p
, get_addr_reg(vtxPrev
), get_addr_reg(vtx
));
396 brw_ADD(p
, get_addr_reg(inlist_ptr
), get_addr_reg(inlist_ptr
), brw_imm_uw(sizeof(short)));
398 /* while (--loopcount != 0)
400 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
401 brw_ADD(p
, c
->reg
.loopcount
, c
->reg
.loopcount
, brw_imm_d(-1));
405 /* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1]
407 * inlist_ptr = &inlist[0]
408 * outlist_ptr = &outlist[0]
410 brw_ADD(p
, get_addr_reg(outlist_ptr
), get_addr_reg(outlist_ptr
), brw_imm_w(-2));
411 brw_MOV(p
, get_addr_reg(vtxPrev
), deref_1uw(outlist_ptr
, 0));
412 brw_MOV(p
, brw_vec8_grf(c
->reg
.inlist
.nr
, 0), brw_vec8_grf(c
->reg
.outlist
.nr
, 0));
413 brw_MOV(p
, get_addr_reg(inlist_ptr
), brw_address(c
->reg
.inlist
));
414 brw_MOV(p
, get_addr_reg(outlist_ptr
), brw_address(c
->reg
.outlist
));
420 brw_ADD(p
, get_addr_reg(plane_ptr
), get_addr_reg(plane_ptr
), brw_clip_plane_stride(c
));
425 vec1(brw_null_reg()),
430 /* && (planemask>>=1) != 0
432 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
433 brw_SHR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud(1));
434 brw_SHR(p
, c
->reg
.vertex_src_mask
, c
->reg
.vertex_src_mask
, brw_imm_ud(1));
441 void brw_clip_tri_emit_polygon(struct brw_clip_compile
*c
)
443 struct brw_compile
*p
= &c
->func
;
445 /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
447 brw_set_conditionalmod(p
, BRW_CONDITIONAL_G
);
453 brw_IF(p
, BRW_EXECUTE_1
);
455 struct brw_indirect v0
= brw_indirect(0, 0);
456 struct brw_indirect vptr
= brw_indirect(1, 0);
458 brw_MOV(p
, get_addr_reg(vptr
), brw_address(c
->reg
.inlist
));
459 brw_MOV(p
, get_addr_reg(v0
), deref_1uw(vptr
, 0));
461 brw_clip_emit_vue(c
, v0
, 1, 0,
462 ((_3DPRIM_TRIFAN
<< URB_WRITE_PRIM_TYPE_SHIFT
)
463 | URB_WRITE_PRIM_START
));
465 brw_ADD(p
, get_addr_reg(vptr
), get_addr_reg(vptr
), brw_imm_uw(2));
466 brw_MOV(p
, get_addr_reg(v0
), deref_1uw(vptr
, 0));
468 brw_DO(p
, BRW_EXECUTE_1
);
470 brw_clip_emit_vue(c
, v0
, 1, 0,
471 (_3DPRIM_TRIFAN
<< URB_WRITE_PRIM_TYPE_SHIFT
));
473 brw_ADD(p
, get_addr_reg(vptr
), get_addr_reg(vptr
), brw_imm_uw(2));
474 brw_MOV(p
, get_addr_reg(v0
), deref_1uw(vptr
, 0));
476 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
477 brw_ADD(p
, c
->reg
.loopcount
, c
->reg
.loopcount
, brw_imm_d(-1));
481 brw_clip_emit_vue(c
, v0
, 0, 1,
482 ((_3DPRIM_TRIFAN
<< URB_WRITE_PRIM_TYPE_SHIFT
)
483 | URB_WRITE_PRIM_END
));
488 static void do_clip_tri( struct brw_clip_compile
*c
)
490 brw_clip_init_planes(c
);
496 static void maybe_do_clip_tri( struct brw_clip_compile
*c
)
498 struct brw_compile
*p
= &c
->func
;
500 brw_CMP(p
, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ
, c
->reg
.planemask
, brw_imm_ud(0));
501 brw_IF(p
, BRW_EXECUTE_1
);
508 static void brw_clip_test( struct brw_clip_compile
*c
)
510 struct brw_reg t
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
511 struct brw_reg t1
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
512 struct brw_reg t2
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
513 struct brw_reg t3
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
515 struct brw_reg v0
= get_tmp(c
);
516 struct brw_reg v1
= get_tmp(c
);
517 struct brw_reg v2
= get_tmp(c
);
519 struct brw_indirect vt0
= brw_indirect(0, 0);
520 struct brw_indirect vt1
= brw_indirect(1, 0);
521 struct brw_indirect vt2
= brw_indirect(2, 0);
523 struct brw_compile
*p
= &c
->func
;
524 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
526 GLuint hpos_offset
= brw_varying_to_offset(&c
->vue_map
,
529 brw_MOV(p
, get_addr_reg(vt0
), brw_address(c
->reg
.vertex
[0]));
530 brw_MOV(p
, get_addr_reg(vt1
), brw_address(c
->reg
.vertex
[1]));
531 brw_MOV(p
, get_addr_reg(vt2
), brw_address(c
->reg
.vertex
[2]));
532 brw_MOV(p
, v0
, deref_4f(vt0
, hpos_offset
));
533 brw_MOV(p
, v1
, deref_4f(vt1
, hpos_offset
));
534 brw_MOV(p
, v2
, deref_4f(vt2
, hpos_offset
));
535 brw_AND(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud(~0x3f));
537 /* test nearz, xmin, ymin plane */
538 /* clip.xyz < -clip.w */
539 brw_CMP(p
, t1
, BRW_CONDITIONAL_L
, v0
, negate(get_element(v0
, 3)));
540 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
541 brw_CMP(p
, t2
, BRW_CONDITIONAL_L
, v1
, negate(get_element(v1
, 3)));
542 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
543 brw_CMP(p
, t3
, BRW_CONDITIONAL_L
, v2
, negate(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<<5)));
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<<3)));
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<<1)));
576 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
578 /* test farz, xmax, ymax plane */
579 /* clip.xyz > clip.w */
580 brw_CMP(p
, t1
, BRW_CONDITIONAL_G
, v0
, get_element(v0
, 3));
581 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
582 brw_CMP(p
, t2
, BRW_CONDITIONAL_G
, v1
, get_element(v1
, 3));
583 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
584 brw_CMP(p
, t3
, BRW_CONDITIONAL_G
, v2
, get_element(v2
, 3));
585 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
587 /* All vertices are outside of a plane, rejected */
588 brw_AND(p
, t
, t1
, t2
);
589 brw_AND(p
, t
, t
, t3
);
590 brw_OR(p
, tmp0
, get_element(t
, 0), get_element(t
, 1));
591 brw_OR(p
, tmp0
, tmp0
, get_element(t
, 2));
592 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
593 brw_AND(p
, brw_null_reg(), tmp0
, brw_imm_ud(0x1));
594 brw_IF(p
, BRW_EXECUTE_1
);
596 brw_clip_kill_thread(c
);
599 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
601 /* some vertices are inside a plane, some are outside,need to clip */
602 brw_XOR(p
, t
, t1
, t2
);
603 brw_XOR(p
, t1
, t2
, t3
);
605 brw_AND(p
, t
, t
, brw_imm_ud(0x1));
606 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
607 get_element(t
, 0), brw_imm_ud(0));
608 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<4)));
609 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
610 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
611 get_element(t
, 1), brw_imm_ud(0));
612 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<2)));
613 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
614 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
615 get_element(t
, 2), brw_imm_ud(0));
616 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<0)));
617 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
623 void brw_emit_tri_clip( struct brw_clip_compile
*c
)
625 struct brw_compile
*p
= &c
->func
;
626 struct brw_context
*brw
= p
->brw
;
627 brw_clip_tri_alloc_regs(c
, 3 + c
->key
.nr_userclip
+ 6);
628 brw_clip_tri_init_vertices(c
);
629 brw_clip_init_clipmask(c
);
630 brw_clip_init_ff_sync(c
);
632 /* if -ve rhw workaround bit is set,
634 if (brw
->has_negative_rhw_bug
) {
635 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
636 brw_AND(p
, brw_null_reg(), get_element_ud(c
->reg
.R0
, 2),
638 brw_IF(p
, BRW_EXECUTE_1
);
644 /* Can't push into do_clip_tri because with polygon (or quad)
645 * flatshading, need to apply the flatshade here because we don't
646 * respect the PV when converting to trifan for emit:
648 if (c
->key
.do_flat_shading
)
649 brw_clip_tri_flat_shade(c
);
651 if ((c
->key
.clip_mode
== BRW_CLIPMODE_NORMAL
) ||
652 (c
->key
.clip_mode
== BRW_CLIPMODE_KERNEL_CLIP
))
655 maybe_do_clip_tri(c
);
657 brw_clip_tri_emit_polygon(c
);
659 /* Send an empty message to kill the thread:
661 brw_clip_kill_thread(c
);