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
->nr_attrs
& 1) {
78 for (j
= 0; j
< 3; j
++) {
79 GLuint delta
= c
->offset
[c
->idx_to_attr
[c
->nr_attrs
- 1]] + ATTR_SIZE
;
81 brw_MOV(&c
->func
, byte_offset(c
->reg
.vertex
[j
], delta
), brw_imm_f(0));
85 c
->reg
.t
= brw_vec1_grf(i
, 0);
86 c
->reg
.loopcount
= retype(brw_vec1_grf(i
, 1), BRW_REGISTER_TYPE_D
);
87 c
->reg
.nr_verts
= retype(brw_vec1_grf(i
, 2), BRW_REGISTER_TYPE_UD
);
88 c
->reg
.planemask
= retype(brw_vec1_grf(i
, 3), BRW_REGISTER_TYPE_UD
);
89 c
->reg
.plane_equation
= brw_vec4_grf(i
, 4);
92 c
->reg
.dpPrev
= brw_vec1_grf(i
, 0); /* fixme - dp4 will clobber r.1,2,3 */
93 c
->reg
.dp
= brw_vec1_grf(i
, 4);
96 c
->reg
.inlist
= brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, i
, 0);
99 c
->reg
.outlist
= brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, i
, 0);
102 c
->reg
.freelist
= brw_uw16_reg(BRW_GENERAL_REGISTER_FILE
, i
, 0);
105 if (!c
->key
.nr_userclip
) {
106 c
->reg
.fixed_planes
= brw_vec8_grf(i
, 0);
110 if (c
->key
.do_unfilled
) {
111 c
->reg
.dir
= brw_vec4_grf(i
, 0);
112 c
->reg
.offset
= brw_vec4_grf(i
, 4);
114 c
->reg
.tmp0
= brw_vec4_grf(i
, 0);
115 c
->reg
.tmp1
= brw_vec4_grf(i
, 4);
119 if (intel
->needs_ff_sync
) {
120 c
->reg
.ff_sync
= retype(brw_vec1_grf(i
, 0), BRW_REGISTER_TYPE_UD
);
127 c
->prog_data
.urb_read_length
= c
->nr_regs
; /* ? */
128 c
->prog_data
.total_grf
= i
;
133 void brw_clip_tri_init_vertices( struct brw_clip_compile
*c
)
135 struct brw_compile
*p
= &c
->func
;
136 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
138 /* Initial list of indices for incoming vertexes:
140 brw_AND(p
, tmp0
, get_element_ud(c
->reg
.R0
, 2), brw_imm_ud(PRIM_MASK
));
142 vec1(brw_null_reg()),
145 brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE
));
147 /* XXX: Is there an easier way to do this? Need to reverse every
148 * second tristrip element: Can ignore sometimes?
150 brw_IF(p
, BRW_EXECUTE_1
);
152 brw_MOV(p
, get_element(c
->reg
.inlist
, 0), brw_address(c
->reg
.vertex
[1]) );
153 brw_MOV(p
, get_element(c
->reg
.inlist
, 1), brw_address(c
->reg
.vertex
[0]) );
154 if (c
->need_direction
)
155 brw_MOV(p
, c
->reg
.dir
, brw_imm_f(-1));
159 brw_MOV(p
, get_element(c
->reg
.inlist
, 0), brw_address(c
->reg
.vertex
[0]) );
160 brw_MOV(p
, get_element(c
->reg
.inlist
, 1), brw_address(c
->reg
.vertex
[1]) );
161 if (c
->need_direction
)
162 brw_MOV(p
, c
->reg
.dir
, brw_imm_f(1));
166 brw_MOV(p
, get_element(c
->reg
.inlist
, 2), brw_address(c
->reg
.vertex
[2]) );
167 brw_MOV(p
, brw_vec8_grf(c
->reg
.outlist
.nr
, 0), brw_imm_f(0));
168 brw_MOV(p
, c
->reg
.nr_verts
, brw_imm_ud(3));
173 void brw_clip_tri_flat_shade( struct brw_clip_compile
*c
)
175 struct brw_compile
*p
= &c
->func
;
176 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
178 brw_AND(p
, tmp0
, get_element_ud(c
->reg
.R0
, 2), brw_imm_ud(PRIM_MASK
));
180 vec1(brw_null_reg()),
183 brw_imm_ud(_3DPRIM_POLYGON
));
185 brw_IF(p
, BRW_EXECUTE_1
);
187 brw_clip_copy_colors(c
, 1, 0);
188 brw_clip_copy_colors(c
, 2, 0);
192 if (c
->key
.pv_first
) {
194 vec1(brw_null_reg()),
197 brw_imm_ud(_3DPRIM_TRIFAN
));
198 brw_IF(p
, BRW_EXECUTE_1
);
200 brw_clip_copy_colors(c
, 0, 1);
201 brw_clip_copy_colors(c
, 2, 1);
205 brw_clip_copy_colors(c
, 1, 0);
206 brw_clip_copy_colors(c
, 2, 0);
211 brw_clip_copy_colors(c
, 0, 2);
212 brw_clip_copy_colors(c
, 1, 2);
220 /* Use mesa's clipping algorithms, translated to GEN4 assembly.
222 void brw_clip_tri( struct brw_clip_compile
*c
)
224 struct brw_compile
*p
= &c
->func
;
225 struct brw_indirect vtx
= brw_indirect(0, 0);
226 struct brw_indirect vtxPrev
= brw_indirect(1, 0);
227 struct brw_indirect vtxOut
= brw_indirect(2, 0);
228 struct brw_indirect plane_ptr
= brw_indirect(3, 0);
229 struct brw_indirect inlist_ptr
= brw_indirect(4, 0);
230 struct brw_indirect outlist_ptr
= brw_indirect(5, 0);
231 struct brw_indirect freelist_ptr
= brw_indirect(6, 0);
232 struct brw_instruction
*plane_loop
;
233 struct brw_instruction
*vertex_loop
;
235 brw_MOV(p
, get_addr_reg(vtxPrev
), brw_address(c
->reg
.vertex
[2]) );
236 brw_MOV(p
, get_addr_reg(plane_ptr
), brw_clip_plane0_address(c
));
237 brw_MOV(p
, get_addr_reg(inlist_ptr
), brw_address(c
->reg
.inlist
));
238 brw_MOV(p
, get_addr_reg(outlist_ptr
), brw_address(c
->reg
.outlist
));
240 brw_MOV(p
, get_addr_reg(freelist_ptr
), brw_address(c
->reg
.vertex
[3]) );
242 plane_loop
= brw_DO(p
, BRW_EXECUTE_1
);
244 /* if (planemask & 1)
246 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
247 brw_AND(p
, vec1(brw_null_reg()), c
->reg
.planemask
, brw_imm_ud(1));
249 brw_IF(p
, BRW_EXECUTE_1
);
251 /* vtxOut = freelist_ptr++
253 brw_MOV(p
, get_addr_reg(vtxOut
), get_addr_reg(freelist_ptr
) );
254 brw_ADD(p
, get_addr_reg(freelist_ptr
), get_addr_reg(freelist_ptr
), brw_imm_uw(c
->nr_regs
* REG_SIZE
));
256 if (c
->key
.nr_userclip
)
257 brw_MOV(p
, c
->reg
.plane_equation
, deref_4f(plane_ptr
, 0));
259 brw_MOV(p
, c
->reg
.plane_equation
, deref_4b(plane_ptr
, 0));
261 brw_MOV(p
, c
->reg
.loopcount
, c
->reg
.nr_verts
);
262 brw_MOV(p
, c
->reg
.nr_verts
, brw_imm_ud(0));
264 vertex_loop
= brw_DO(p
, BRW_EXECUTE_1
);
268 brw_MOV(p
, get_addr_reg(vtx
), deref_1uw(inlist_ptr
, 0));
270 /* IS_NEGATIVE(prev) */
271 brw_set_conditionalmod(p
, BRW_CONDITIONAL_L
);
272 brw_DP4(p
, vec4(c
->reg
.dpPrev
), deref_4f(vtxPrev
, c
->offset
[VERT_RESULT_HPOS
]), c
->reg
.plane_equation
);
273 brw_IF(p
, BRW_EXECUTE_1
);
277 brw_set_conditionalmod(p
, BRW_CONDITIONAL_GE
);
278 brw_DP4(p
, vec4(c
->reg
.dp
), deref_4f(vtx
, c
->offset
[VERT_RESULT_HPOS
]), c
->reg
.plane_equation
);
279 brw_IF(p
, BRW_EXECUTE_1
);
284 brw_ADD(p
, c
->reg
.t
, c
->reg
.dpPrev
, negate(c
->reg
.dp
));
285 brw_math_invert(p
, c
->reg
.t
, c
->reg
.t
);
286 brw_MUL(p
, c
->reg
.t
, c
->reg
.t
, c
->reg
.dpPrev
);
288 /* If (vtxOut == 0) vtxOut = vtxPrev
290 brw_CMP(p
, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
291 brw_MOV(p
, get_addr_reg(vtxOut
), get_addr_reg(vtxPrev
) );
292 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
294 brw_clip_interp_vertex(c
, vtxOut
, vtxPrev
, vtx
, c
->reg
.t
, GL_FALSE
);
296 /* *outlist_ptr++ = vtxOut;
300 brw_MOV(p
, deref_1uw(outlist_ptr
, 0), get_addr_reg(vtxOut
));
301 brw_ADD(p
, get_addr_reg(outlist_ptr
), get_addr_reg(outlist_ptr
), brw_imm_uw(sizeof(short)));
302 brw_ADD(p
, c
->reg
.nr_verts
, c
->reg
.nr_verts
, brw_imm_ud(1));
303 brw_MOV(p
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
310 /* *outlist_ptr++ = vtxPrev;
313 brw_MOV(p
, deref_1uw(outlist_ptr
, 0), get_addr_reg(vtxPrev
));
314 brw_ADD(p
, get_addr_reg(outlist_ptr
), get_addr_reg(outlist_ptr
), brw_imm_uw(sizeof(short)));
315 brw_ADD(p
, c
->reg
.nr_verts
, c
->reg
.nr_verts
, brw_imm_ud(1));
319 brw_set_conditionalmod(p
, BRW_CONDITIONAL_L
);
320 brw_DP4(p
, vec4(c
->reg
.dp
), deref_4f(vtx
, c
->offset
[VERT_RESULT_HPOS
]), c
->reg
.plane_equation
);
321 brw_IF(p
, BRW_EXECUTE_1
);
323 /* Going out of bounds. Avoid division by zero as we
324 * know dp != dpPrev from DIFFERENT_SIGNS, above.
326 brw_ADD(p
, c
->reg
.t
, c
->reg
.dp
, negate(c
->reg
.dpPrev
));
327 brw_math_invert(p
, c
->reg
.t
, c
->reg
.t
);
328 brw_MUL(p
, c
->reg
.t
, c
->reg
.t
, c
->reg
.dp
);
330 /* If (vtxOut == 0) vtxOut = vtx
332 brw_CMP(p
, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
333 brw_MOV(p
, get_addr_reg(vtxOut
), get_addr_reg(vtx
) );
334 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
336 brw_clip_interp_vertex(c
, vtxOut
, vtx
, vtxPrev
, c
->reg
.t
, GL_TRUE
);
338 /* *outlist_ptr++ = vtxOut;
342 brw_MOV(p
, deref_1uw(outlist_ptr
, 0), get_addr_reg(vtxOut
));
343 brw_ADD(p
, get_addr_reg(outlist_ptr
), get_addr_reg(outlist_ptr
), brw_imm_uw(sizeof(short)));
344 brw_ADD(p
, c
->reg
.nr_verts
, c
->reg
.nr_verts
, brw_imm_ud(1));
345 brw_MOV(p
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
354 brw_MOV(p
, get_addr_reg(vtxPrev
), get_addr_reg(vtx
));
355 brw_ADD(p
, get_addr_reg(inlist_ptr
), get_addr_reg(inlist_ptr
), brw_imm_uw(sizeof(short)));
357 /* while (--loopcount != 0)
359 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
360 brw_ADD(p
, c
->reg
.loopcount
, c
->reg
.loopcount
, brw_imm_d(-1));
362 brw_WHILE(p
, vertex_loop
);
364 /* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1]
366 * inlist_ptr = &inlist[0]
367 * outlist_ptr = &outlist[0]
369 brw_ADD(p
, get_addr_reg(outlist_ptr
), get_addr_reg(outlist_ptr
), brw_imm_w(-2));
370 brw_MOV(p
, get_addr_reg(vtxPrev
), deref_1uw(outlist_ptr
, 0));
371 brw_MOV(p
, brw_vec8_grf(c
->reg
.inlist
.nr
, 0), brw_vec8_grf(c
->reg
.outlist
.nr
, 0));
372 brw_MOV(p
, get_addr_reg(inlist_ptr
), brw_address(c
->reg
.inlist
));
373 brw_MOV(p
, get_addr_reg(outlist_ptr
), brw_address(c
->reg
.outlist
));
379 brw_ADD(p
, get_addr_reg(plane_ptr
), get_addr_reg(plane_ptr
), brw_clip_plane_stride(c
));
384 vec1(brw_null_reg()),
389 /* && (planemask>>=1) != 0
391 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
392 brw_SHR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud(1));
394 brw_WHILE(p
, plane_loop
);
399 void brw_clip_tri_emit_polygon(struct brw_clip_compile
*c
)
401 struct brw_compile
*p
= &c
->func
;
402 struct brw_instruction
*loop
;
404 /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
406 brw_set_conditionalmod(p
, BRW_CONDITIONAL_G
);
412 brw_IF(p
, BRW_EXECUTE_1
);
414 struct brw_indirect v0
= brw_indirect(0, 0);
415 struct brw_indirect vptr
= brw_indirect(1, 0);
417 brw_MOV(p
, get_addr_reg(vptr
), brw_address(c
->reg
.inlist
));
418 brw_MOV(p
, get_addr_reg(v0
), deref_1uw(vptr
, 0));
420 brw_clip_emit_vue(c
, v0
, 1, 0, ((_3DPRIM_TRIFAN
<< 2) | R02_PRIM_START
));
422 brw_ADD(p
, get_addr_reg(vptr
), get_addr_reg(vptr
), brw_imm_uw(2));
423 brw_MOV(p
, get_addr_reg(v0
), deref_1uw(vptr
, 0));
425 loop
= brw_DO(p
, BRW_EXECUTE_1
);
427 brw_clip_emit_vue(c
, v0
, 1, 0, (_3DPRIM_TRIFAN
<< 2));
429 brw_ADD(p
, get_addr_reg(vptr
), get_addr_reg(vptr
), brw_imm_uw(2));
430 brw_MOV(p
, get_addr_reg(v0
), deref_1uw(vptr
, 0));
432 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
433 brw_ADD(p
, c
->reg
.loopcount
, c
->reg
.loopcount
, brw_imm_d(-1));
437 brw_clip_emit_vue(c
, v0
, 0, 1, ((_3DPRIM_TRIFAN
<< 2) | R02_PRIM_END
));
442 static void do_clip_tri( struct brw_clip_compile
*c
)
444 brw_clip_init_planes(c
);
450 static void maybe_do_clip_tri( struct brw_clip_compile
*c
)
452 struct brw_compile
*p
= &c
->func
;
454 brw_CMP(p
, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ
, c
->reg
.planemask
, brw_imm_ud(0));
455 brw_IF(p
, BRW_EXECUTE_1
);
462 static void brw_clip_test( struct brw_clip_compile
*c
)
464 struct brw_reg t
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
465 struct brw_reg t1
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
466 struct brw_reg t2
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
467 struct brw_reg t3
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
469 struct brw_reg v0
= get_tmp(c
);
470 struct brw_reg v1
= get_tmp(c
);
471 struct brw_reg v2
= get_tmp(c
);
473 struct brw_indirect vt0
= brw_indirect(0, 0);
474 struct brw_indirect vt1
= brw_indirect(1, 0);
475 struct brw_indirect vt2
= brw_indirect(2, 0);
477 struct brw_compile
*p
= &c
->func
;
478 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
480 brw_MOV(p
, get_addr_reg(vt0
), brw_address(c
->reg
.vertex
[0]));
481 brw_MOV(p
, get_addr_reg(vt1
), brw_address(c
->reg
.vertex
[1]));
482 brw_MOV(p
, get_addr_reg(vt2
), brw_address(c
->reg
.vertex
[2]));
483 brw_MOV(p
, v0
, deref_4f(vt0
, c
->offset
[VERT_RESULT_HPOS
]));
484 brw_MOV(p
, v1
, deref_4f(vt1
, c
->offset
[VERT_RESULT_HPOS
]));
485 brw_MOV(p
, v2
, deref_4f(vt2
, c
->offset
[VERT_RESULT_HPOS
]));
486 brw_AND(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud(~0x3f));
488 /* test nearz, xmin, ymin plane */
489 /* clip.xyz < -clip.w */
490 brw_CMP(p
, t1
, BRW_CONDITIONAL_L
, v0
, negate(get_element(v0
, 3)));
491 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
492 brw_CMP(p
, t2
, BRW_CONDITIONAL_L
, v1
, negate(get_element(v1
, 3)));
493 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
494 brw_CMP(p
, t3
, BRW_CONDITIONAL_L
, v2
, negate(get_element(v2
, 3)));
495 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
497 /* All vertices are outside of a plane, rejected */
498 brw_AND(p
, t
, t1
, t2
);
499 brw_AND(p
, t
, t
, t3
);
500 brw_OR(p
, tmp0
, get_element(t
, 0), get_element(t
, 1));
501 brw_OR(p
, tmp0
, tmp0
, get_element(t
, 2));
502 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
503 brw_AND(p
, brw_null_reg(), tmp0
, brw_imm_ud(0x1));
504 brw_IF(p
, BRW_EXECUTE_1
);
506 brw_clip_kill_thread(c
);
509 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
511 /* some vertices are inside a plane, some are outside,need to clip */
512 brw_XOR(p
, t
, t1
, t2
);
513 brw_XOR(p
, t1
, t2
, t3
);
515 brw_AND(p
, t
, t
, brw_imm_ud(0x1));
516 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
517 get_element(t
, 0), brw_imm_ud(0));
518 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<5)));
519 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
520 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
521 get_element(t
, 1), brw_imm_ud(0));
522 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<3)));
523 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
524 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
525 get_element(t
, 2), brw_imm_ud(0));
526 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<1)));
527 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
529 /* test farz, xmax, ymax plane */
530 /* clip.xyz > clip.w */
531 brw_CMP(p
, t1
, BRW_CONDITIONAL_G
, v0
, get_element(v0
, 3));
532 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
533 brw_CMP(p
, t2
, BRW_CONDITIONAL_G
, v1
, get_element(v1
, 3));
534 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
535 brw_CMP(p
, t3
, BRW_CONDITIONAL_G
, v2
, get_element(v2
, 3));
536 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
538 /* All vertices are outside of a plane, rejected */
539 brw_AND(p
, t
, t1
, t2
);
540 brw_AND(p
, t
, t
, t3
);
541 brw_OR(p
, tmp0
, get_element(t
, 0), get_element(t
, 1));
542 brw_OR(p
, tmp0
, tmp0
, get_element(t
, 2));
543 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
544 brw_AND(p
, brw_null_reg(), tmp0
, brw_imm_ud(0x1));
545 brw_IF(p
, BRW_EXECUTE_1
);
547 brw_clip_kill_thread(c
);
550 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
552 /* some vertices are inside a plane, some are outside,need to clip */
553 brw_XOR(p
, t
, t1
, t2
);
554 brw_XOR(p
, t1
, t2
, t3
);
556 brw_AND(p
, t
, t
, brw_imm_ud(0x1));
557 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
558 get_element(t
, 0), brw_imm_ud(0));
559 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<4)));
560 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
561 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
562 get_element(t
, 1), brw_imm_ud(0));
563 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<2)));
564 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
565 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
566 get_element(t
, 2), brw_imm_ud(0));
567 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<0)));
568 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
574 void brw_emit_tri_clip( struct brw_clip_compile
*c
)
576 struct brw_compile
*p
= &c
->func
;
577 struct brw_context
*brw
= p
->brw
;
578 brw_clip_tri_alloc_regs(c
, 3 + c
->key
.nr_userclip
+ 6);
579 brw_clip_tri_init_vertices(c
);
580 brw_clip_init_clipmask(c
);
581 brw_clip_init_ff_sync(c
);
583 /* if -ve rhw workaround bit is set,
585 if (brw
->has_negative_rhw_bug
) {
586 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
587 brw_AND(p
, brw_null_reg(), get_element_ud(c
->reg
.R0
, 2),
589 brw_IF(p
, BRW_EXECUTE_1
);
595 /* Can't push into do_clip_tri because with polygon (or quad)
596 * flatshading, need to apply the flatshade here because we don't
597 * respect the PV when converting to trifan for emit:
599 if (c
->key
.do_flat_shading
)
600 brw_clip_tri_flat_shade(c
);
602 if ((c
->key
.clip_mode
== BRW_CLIPMODE_NORMAL
) ||
603 (c
->key
.clip_mode
== BRW_CLIPMODE_KERNEL_CLIP
))
606 maybe_do_clip_tri(c
);
608 brw_clip_tri_emit_polygon(c
);
610 /* Send an empty message to kill the thread:
612 brw_clip_kill_thread(c
);