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"
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
->nr_attrs
*16 + 32;
82 delta
= c
->nr_attrs
* 16 + 32 * 3;
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 */
140 struct brw_instruction
*is_rev
;
142 /* Initial list of indices for incoming vertexes:
144 brw_AND(p
, tmp0
, get_element_ud(c
->reg
.R0
, 2), brw_imm_ud(PRIM_MASK
));
146 vec1(brw_null_reg()),
149 brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE
));
151 /* XXX: Is there an easier way to do this? Need to reverse every
152 * second tristrip element: Can ignore sometimes?
154 is_rev
= brw_IF(p
, BRW_EXECUTE_1
);
156 brw_MOV(p
, get_element(c
->reg
.inlist
, 0), brw_address(c
->reg
.vertex
[1]) );
157 brw_MOV(p
, get_element(c
->reg
.inlist
, 1), brw_address(c
->reg
.vertex
[0]) );
158 if (c
->need_direction
)
159 brw_MOV(p
, c
->reg
.dir
, brw_imm_f(-1));
161 is_rev
= brw_ELSE(p
, is_rev
);
163 brw_MOV(p
, get_element(c
->reg
.inlist
, 0), brw_address(c
->reg
.vertex
[0]) );
164 brw_MOV(p
, get_element(c
->reg
.inlist
, 1), brw_address(c
->reg
.vertex
[1]) );
165 if (c
->need_direction
)
166 brw_MOV(p
, c
->reg
.dir
, brw_imm_f(1));
168 brw_ENDIF(p
, is_rev
);
170 brw_MOV(p
, get_element(c
->reg
.inlist
, 2), brw_address(c
->reg
.vertex
[2]) );
171 brw_MOV(p
, brw_vec8_grf(c
->reg
.outlist
.nr
, 0), brw_imm_f(0));
172 brw_MOV(p
, c
->reg
.nr_verts
, brw_imm_ud(3));
177 void brw_clip_tri_flat_shade( struct brw_clip_compile
*c
)
179 struct brw_compile
*p
= &c
->func
;
180 struct brw_instruction
*is_poly
;
181 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
183 brw_AND(p
, tmp0
, get_element_ud(c
->reg
.R0
, 2), brw_imm_ud(PRIM_MASK
));
185 vec1(brw_null_reg()),
188 brw_imm_ud(_3DPRIM_POLYGON
));
190 is_poly
= brw_IF(p
, BRW_EXECUTE_1
);
192 brw_clip_copy_colors(c
, 1, 0);
193 brw_clip_copy_colors(c
, 2, 0);
195 is_poly
= brw_ELSE(p
, is_poly
);
197 if (c
->key
.pv_first
) {
198 brw_clip_copy_colors(c
, 1, 0);
199 brw_clip_copy_colors(c
, 2, 0);
202 brw_clip_copy_colors(c
, 0, 2);
203 brw_clip_copy_colors(c
, 1, 2);
206 brw_ENDIF(p
, is_poly
);
211 /* Use mesa's clipping algorithms, translated to GEN4 assembly.
213 void brw_clip_tri( struct brw_clip_compile
*c
)
215 struct brw_compile
*p
= &c
->func
;
216 struct brw_indirect vtx
= brw_indirect(0, 0);
217 struct brw_indirect vtxPrev
= brw_indirect(1, 0);
218 struct brw_indirect vtxOut
= brw_indirect(2, 0);
219 struct brw_indirect plane_ptr
= brw_indirect(3, 0);
220 struct brw_indirect inlist_ptr
= brw_indirect(4, 0);
221 struct brw_indirect outlist_ptr
= brw_indirect(5, 0);
222 struct brw_indirect freelist_ptr
= brw_indirect(6, 0);
223 struct brw_instruction
*plane_loop
;
224 struct brw_instruction
*plane_active
;
225 struct brw_instruction
*vertex_loop
;
226 struct brw_instruction
*next_test
;
227 struct brw_instruction
*prev_test
;
229 brw_MOV(p
, get_addr_reg(vtxPrev
), brw_address(c
->reg
.vertex
[2]) );
230 brw_MOV(p
, get_addr_reg(plane_ptr
), brw_clip_plane0_address(c
));
231 brw_MOV(p
, get_addr_reg(inlist_ptr
), brw_address(c
->reg
.inlist
));
232 brw_MOV(p
, get_addr_reg(outlist_ptr
), brw_address(c
->reg
.outlist
));
234 brw_MOV(p
, get_addr_reg(freelist_ptr
), brw_address(c
->reg
.vertex
[3]) );
236 plane_loop
= brw_DO(p
, BRW_EXECUTE_1
);
238 /* if (planemask & 1)
240 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
241 brw_AND(p
, vec1(brw_null_reg()), c
->reg
.planemask
, brw_imm_ud(1));
243 plane_active
= brw_IF(p
, BRW_EXECUTE_1
);
245 /* vtxOut = freelist_ptr++
247 brw_MOV(p
, get_addr_reg(vtxOut
), get_addr_reg(freelist_ptr
) );
248 brw_ADD(p
, get_addr_reg(freelist_ptr
), get_addr_reg(freelist_ptr
), brw_imm_uw(c
->nr_regs
* REG_SIZE
));
250 if (c
->key
.nr_userclip
)
251 brw_MOV(p
, c
->reg
.plane_equation
, deref_4f(plane_ptr
, 0));
253 brw_MOV(p
, c
->reg
.plane_equation
, deref_4b(plane_ptr
, 0));
255 brw_MOV(p
, c
->reg
.loopcount
, c
->reg
.nr_verts
);
256 brw_MOV(p
, c
->reg
.nr_verts
, brw_imm_ud(0));
258 vertex_loop
= brw_DO(p
, BRW_EXECUTE_1
);
262 brw_MOV(p
, get_addr_reg(vtx
), deref_1uw(inlist_ptr
, 0));
264 /* IS_NEGATIVE(prev) */
265 brw_set_conditionalmod(p
, BRW_CONDITIONAL_L
);
266 brw_DP4(p
, vec4(c
->reg
.dpPrev
), deref_4f(vtxPrev
, c
->offset
[VERT_RESULT_HPOS
]), c
->reg
.plane_equation
);
267 prev_test
= brw_IF(p
, BRW_EXECUTE_1
);
271 brw_set_conditionalmod(p
, BRW_CONDITIONAL_GE
);
272 brw_DP4(p
, vec4(c
->reg
.dp
), deref_4f(vtx
, c
->offset
[VERT_RESULT_HPOS
]), c
->reg
.plane_equation
);
273 next_test
= brw_IF(p
, BRW_EXECUTE_1
);
278 brw_ADD(p
, c
->reg
.t
, c
->reg
.dpPrev
, negate(c
->reg
.dp
));
279 brw_math_invert(p
, c
->reg
.t
, c
->reg
.t
);
280 brw_MUL(p
, c
->reg
.t
, c
->reg
.t
, c
->reg
.dpPrev
);
282 /* If (vtxOut == 0) vtxOut = vtxPrev
284 brw_CMP(p
, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
285 brw_MOV(p
, get_addr_reg(vtxOut
), get_addr_reg(vtxPrev
) );
286 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
288 brw_clip_interp_vertex(c
, vtxOut
, vtxPrev
, vtx
, c
->reg
.t
, GL_FALSE
);
290 /* *outlist_ptr++ = vtxOut;
294 brw_MOV(p
, deref_1uw(outlist_ptr
, 0), get_addr_reg(vtxOut
));
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));
297 brw_MOV(p
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
299 brw_ENDIF(p
, next_test
);
302 prev_test
= brw_ELSE(p
, prev_test
);
304 /* *outlist_ptr++ = vtxPrev;
307 brw_MOV(p
, deref_1uw(outlist_ptr
, 0), get_addr_reg(vtxPrev
));
308 brw_ADD(p
, get_addr_reg(outlist_ptr
), get_addr_reg(outlist_ptr
), brw_imm_uw(sizeof(short)));
309 brw_ADD(p
, c
->reg
.nr_verts
, c
->reg
.nr_verts
, brw_imm_ud(1));
313 brw_set_conditionalmod(p
, BRW_CONDITIONAL_L
);
314 brw_DP4(p
, vec4(c
->reg
.dp
), deref_4f(vtx
, c
->offset
[VERT_RESULT_HPOS
]), c
->reg
.plane_equation
);
315 next_test
= brw_IF(p
, BRW_EXECUTE_1
);
317 /* Going out of bounds. Avoid division by zero as we
318 * know dp != dpPrev from DIFFERENT_SIGNS, above.
320 brw_ADD(p
, c
->reg
.t
, c
->reg
.dp
, negate(c
->reg
.dpPrev
));
321 brw_math_invert(p
, c
->reg
.t
, c
->reg
.t
);
322 brw_MUL(p
, c
->reg
.t
, c
->reg
.t
, c
->reg
.dp
);
324 /* If (vtxOut == 0) vtxOut = vtx
326 brw_CMP(p
, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
327 brw_MOV(p
, get_addr_reg(vtxOut
), get_addr_reg(vtx
) );
328 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
330 brw_clip_interp_vertex(c
, vtxOut
, vtx
, vtxPrev
, c
->reg
.t
, GL_TRUE
);
332 /* *outlist_ptr++ = vtxOut;
336 brw_MOV(p
, deref_1uw(outlist_ptr
, 0), get_addr_reg(vtxOut
));
337 brw_ADD(p
, get_addr_reg(outlist_ptr
), get_addr_reg(outlist_ptr
), brw_imm_uw(sizeof(short)));
338 brw_ADD(p
, c
->reg
.nr_verts
, c
->reg
.nr_verts
, brw_imm_ud(1));
339 brw_MOV(p
, get_addr_reg(vtxOut
), brw_imm_uw(0) );
341 brw_ENDIF(p
, next_test
);
343 brw_ENDIF(p
, prev_test
);
348 brw_MOV(p
, get_addr_reg(vtxPrev
), get_addr_reg(vtx
));
349 brw_ADD(p
, get_addr_reg(inlist_ptr
), get_addr_reg(inlist_ptr
), brw_imm_uw(sizeof(short)));
351 /* while (--loopcount != 0)
353 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
354 brw_ADD(p
, c
->reg
.loopcount
, c
->reg
.loopcount
, brw_imm_d(-1));
356 brw_WHILE(p
, vertex_loop
);
358 /* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1]
360 * inlist_ptr = &inlist[0]
361 * outlist_ptr = &outlist[0]
363 brw_ADD(p
, get_addr_reg(outlist_ptr
), get_addr_reg(outlist_ptr
), brw_imm_w(-2));
364 brw_MOV(p
, get_addr_reg(vtxPrev
), deref_1uw(outlist_ptr
, 0));
365 brw_MOV(p
, brw_vec8_grf(c
->reg
.inlist
.nr
, 0), brw_vec8_grf(c
->reg
.outlist
.nr
, 0));
366 brw_MOV(p
, get_addr_reg(inlist_ptr
), brw_address(c
->reg
.inlist
));
367 brw_MOV(p
, get_addr_reg(outlist_ptr
), brw_address(c
->reg
.outlist
));
369 brw_ENDIF(p
, plane_active
);
373 brw_ADD(p
, get_addr_reg(plane_ptr
), get_addr_reg(plane_ptr
), brw_clip_plane_stride(c
));
378 vec1(brw_null_reg()),
383 /* && (planemask>>=1) != 0
385 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
386 brw_SHR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud(1));
388 brw_WHILE(p
, plane_loop
);
393 void brw_clip_tri_emit_polygon(struct brw_clip_compile
*c
)
395 struct brw_compile
*p
= &c
->func
;
396 struct brw_instruction
*loop
, *if_insn
;
398 /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
400 brw_set_conditionalmod(p
, BRW_CONDITIONAL_G
);
406 if_insn
= brw_IF(p
, BRW_EXECUTE_1
);
408 struct brw_indirect v0
= brw_indirect(0, 0);
409 struct brw_indirect vptr
= brw_indirect(1, 0);
411 brw_MOV(p
, get_addr_reg(vptr
), brw_address(c
->reg
.inlist
));
412 brw_MOV(p
, get_addr_reg(v0
), deref_1uw(vptr
, 0));
414 brw_clip_emit_vue(c
, v0
, 1, 0, ((_3DPRIM_TRIFAN
<< 2) | R02_PRIM_START
));
416 brw_ADD(p
, get_addr_reg(vptr
), get_addr_reg(vptr
), brw_imm_uw(2));
417 brw_MOV(p
, get_addr_reg(v0
), deref_1uw(vptr
, 0));
419 loop
= brw_DO(p
, BRW_EXECUTE_1
);
421 brw_clip_emit_vue(c
, v0
, 1, 0, (_3DPRIM_TRIFAN
<< 2));
423 brw_ADD(p
, get_addr_reg(vptr
), get_addr_reg(vptr
), brw_imm_uw(2));
424 brw_MOV(p
, get_addr_reg(v0
), deref_1uw(vptr
, 0));
426 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
427 brw_ADD(p
, c
->reg
.loopcount
, c
->reg
.loopcount
, brw_imm_d(-1));
431 brw_clip_emit_vue(c
, v0
, 0, 1, ((_3DPRIM_TRIFAN
<< 2) | R02_PRIM_END
));
433 brw_ENDIF(p
, if_insn
);
436 static void do_clip_tri( struct brw_clip_compile
*c
)
438 brw_clip_init_planes(c
);
444 static void maybe_do_clip_tri( struct brw_clip_compile
*c
)
446 struct brw_compile
*p
= &c
->func
;
447 struct brw_instruction
*do_clip
;
449 brw_CMP(p
, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ
, c
->reg
.planemask
, brw_imm_ud(0));
450 do_clip
= brw_IF(p
, BRW_EXECUTE_1
);
454 brw_ENDIF(p
, do_clip
);
457 static void brw_clip_test( struct brw_clip_compile
*c
)
459 struct brw_reg t
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
460 struct brw_reg t1
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
461 struct brw_reg t2
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
462 struct brw_reg t3
= retype(get_tmp(c
), BRW_REGISTER_TYPE_UD
);
464 struct brw_reg v0
= get_tmp(c
);
465 struct brw_reg v1
= get_tmp(c
);
466 struct brw_reg v2
= get_tmp(c
);
468 struct brw_indirect vt0
= brw_indirect(0, 0);
469 struct brw_indirect vt1
= brw_indirect(1, 0);
470 struct brw_indirect vt2
= brw_indirect(2, 0);
472 struct brw_compile
*p
= &c
->func
;
473 struct brw_instruction
*is_outside
;
474 struct brw_reg tmp0
= c
->reg
.loopcount
; /* handy temporary */
476 brw_MOV(p
, get_addr_reg(vt0
), brw_address(c
->reg
.vertex
[0]));
477 brw_MOV(p
, get_addr_reg(vt1
), brw_address(c
->reg
.vertex
[1]));
478 brw_MOV(p
, get_addr_reg(vt2
), brw_address(c
->reg
.vertex
[2]));
479 brw_MOV(p
, v0
, deref_4f(vt0
, c
->offset
[VERT_RESULT_HPOS
]));
480 brw_MOV(p
, v1
, deref_4f(vt1
, c
->offset
[VERT_RESULT_HPOS
]));
481 brw_MOV(p
, v2
, deref_4f(vt2
, c
->offset
[VERT_RESULT_HPOS
]));
482 brw_AND(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud(~0x3f));
484 /* test nearz, xmin, ymin plane */
485 /* clip.xyz < -clip.w */
486 brw_CMP(p
, t1
, BRW_CONDITIONAL_L
, v0
, negate(get_element(v0
, 3)));
487 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
488 brw_CMP(p
, t2
, BRW_CONDITIONAL_L
, v1
, negate(get_element(v1
, 3)));
489 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
490 brw_CMP(p
, t3
, BRW_CONDITIONAL_L
, v2
, negate(get_element(v2
, 3)));
491 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
493 /* All vertices are outside of a plane, rejected */
494 brw_AND(p
, t
, t1
, t2
);
495 brw_AND(p
, t
, t
, t3
);
496 brw_OR(p
, tmp0
, get_element(t
, 0), get_element(t
, 1));
497 brw_OR(p
, tmp0
, tmp0
, get_element(t
, 2));
498 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
499 brw_AND(p
, brw_null_reg(), tmp0
, brw_imm_ud(0x1));
500 is_outside
= brw_IF(p
, BRW_EXECUTE_1
);
502 brw_clip_kill_thread(c
);
504 brw_ENDIF(p
, is_outside
);
505 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
507 /* some vertices are inside a plane, some are outside,need to clip */
508 brw_XOR(p
, t
, t1
, t2
);
509 brw_XOR(p
, t1
, t2
, t3
);
511 brw_AND(p
, t
, t
, brw_imm_ud(0x1));
512 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
513 get_element(t
, 0), brw_imm_ud(0));
514 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<5)));
515 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
516 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
517 get_element(t
, 1), brw_imm_ud(0));
518 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<3)));
519 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
520 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
521 get_element(t
, 2), brw_imm_ud(0));
522 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<1)));
523 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
525 /* test farz, xmax, ymax plane */
526 /* clip.xyz > clip.w */
527 brw_CMP(p
, t1
, BRW_CONDITIONAL_G
, v0
, get_element(v0
, 3));
528 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
529 brw_CMP(p
, t2
, BRW_CONDITIONAL_G
, v1
, get_element(v1
, 3));
530 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
531 brw_CMP(p
, t3
, BRW_CONDITIONAL_G
, v2
, get_element(v2
, 3));
532 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
534 /* All vertices are outside of a plane, rejected */
535 brw_AND(p
, t
, t1
, t2
);
536 brw_AND(p
, t
, t
, t3
);
537 brw_OR(p
, tmp0
, get_element(t
, 0), get_element(t
, 1));
538 brw_OR(p
, tmp0
, tmp0
, get_element(t
, 2));
539 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
540 brw_AND(p
, brw_null_reg(), tmp0
, brw_imm_ud(0x1));
541 is_outside
= brw_IF(p
, BRW_EXECUTE_1
);
543 brw_clip_kill_thread(c
);
545 brw_ENDIF(p
, is_outside
);
546 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
548 /* some vertices are inside a plane, some are outside,need to clip */
549 brw_XOR(p
, t
, t1
, t2
);
550 brw_XOR(p
, t1
, t2
, t3
);
552 brw_AND(p
, t
, t
, brw_imm_ud(0x1));
553 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
554 get_element(t
, 0), brw_imm_ud(0));
555 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<4)));
556 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
557 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
558 get_element(t
, 1), brw_imm_ud(0));
559 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<2)));
560 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
561 brw_CMP(p
, brw_null_reg(), BRW_CONDITIONAL_NZ
,
562 get_element(t
, 2), brw_imm_ud(0));
563 brw_OR(p
, c
->reg
.planemask
, c
->reg
.planemask
, brw_imm_ud((1<<0)));
564 brw_set_predicate_control(p
, BRW_PREDICATE_NONE
);
570 void brw_emit_tri_clip( struct brw_clip_compile
*c
)
572 struct brw_instruction
*neg_rhw
;
573 struct brw_compile
*p
= &c
->func
;
574 struct brw_context
*brw
= p
->brw
;
575 brw_clip_tri_alloc_regs(c
, 3 + c
->key
.nr_userclip
+ 6);
576 brw_clip_tri_init_vertices(c
);
577 brw_clip_init_clipmask(c
);
578 brw_clip_init_ff_sync(c
);
580 /* if -ve rhw workaround bit is set,
582 if (brw
->has_negative_rhw_bug
) {
583 brw_set_conditionalmod(p
, BRW_CONDITIONAL_NZ
);
584 brw_AND(p
, brw_null_reg(), get_element_ud(c
->reg
.R0
, 2),
586 neg_rhw
= brw_IF(p
, BRW_EXECUTE_1
);
590 brw_ENDIF(p
, neg_rhw
);
592 /* Can't push into do_clip_tri because with polygon (or quad)
593 * flatshading, need to apply the flatshade here because we don't
594 * respect the PV when converting to trifan for emit:
596 if (c
->key
.do_flat_shading
)
597 brw_clip_tri_flat_shade(c
);
599 if ((c
->key
.clip_mode
== BRW_CLIPMODE_NORMAL
) ||
600 (c
->key
.clip_mode
== BRW_CLIPMODE_KERNEL_CLIP
))
603 maybe_do_clip_tri(c
);
605 brw_clip_tri_emit_polygon(c
);
607 /* Send an empty message to kill the thread:
609 brw_clip_kill_thread(c
);