1 /*
2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
5
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:
13
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.
17
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.
25
26 **********************************************************************/
27 /*
28 * Authors:
29 * Keith Whitwell <keith@tungstengraphics.com>
30 */
31
32 #include "main/glheader.h"
33 #include "main/macros.h"
34 #include "main/enums.h"
35 #include "program/program.h"
36
37 #include "intel_batchbuffer.h"
38
39 #include "brw_defines.h"
40 #include "brw_context.h"
41 #include "brw_eu.h"
42 #include "brw_clip.h"
43
release_tmps(struct brw_clip_compile * c)44 static void release_tmps( struct brw_clip_compile *c )
45 {
46 c->last_tmp = c->first_tmp;
47 }
48
49
brw_clip_tri_alloc_regs(struct brw_clip_compile * c,GLuint nr_verts)50 void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
51 GLuint nr_verts )
52 {
53 struct intel_context *intel = &c->func.brw->intel;
54 GLuint i = 0,j;
55
56 /* Register usage is static, precompute here:
57 */
58 c->reg.R0 = retype(brw_vec8_grf(i, 0), BRW_REGISTER_TYPE_UD); i++;
59
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;
63
64 c->prog_data.curb_read_length = (6 + c->key.nr_userclip + 1) / 2;
65 }
66 else
67 c->prog_data.curb_read_length = 0;
68
69
70 /* Payload vertices plus space for more generated vertices:
71 */
72 for (j = 0; j < nr_verts; j++) {
73 c->reg.vertex[j] = brw_vec4_grf(i, 0);
74 i += c->nr_regs;
75 }
76
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.
80 */
81 for (j = 0; j < 3; j++) {
82 GLuint delta = brw_vue_slot_to_offset(c->vue_map.num_slots);
83
84 brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0));
85 }
86 }
87
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);
93 i++;
94
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);
97 i++;
98
99 c->reg.inlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
100 i++;
101
102 c->reg.outlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
103 i++;
104
105 c->reg.freelist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
106 i++;
107
108 if (!c->key.nr_userclip) {
109 c->reg.fixed_planes = brw_vec8_grf(i, 0);
110 i++;
111 }
112
113 if (c->key.do_unfilled) {
114 c->reg.dir = brw_vec4_grf(i, 0);
115 c->reg.offset = brw_vec4_grf(i, 4);
116 i++;
117 c->reg.tmp0 = brw_vec4_grf(i, 0);
118 c->reg.tmp1 = brw_vec4_grf(i, 4);
119 i++;
120 }
121
122 if (intel->needs_ff_sync) {
123 c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
124 i++;
125 }
126
127 c->first_tmp = i;
128 c->last_tmp = i;
129
130 c->prog_data.urb_read_length = c->nr_regs; /* ? */
131 c->prog_data.total_grf = i;
132 }
133
134
135
brw_clip_tri_init_vertices(struct brw_clip_compile * c)136 void brw_clip_tri_init_vertices( struct brw_clip_compile *c )
137 {
138 struct brw_compile *p = &c->func;
139 struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
140
141 /* Initial list of indices for incoming vertexes:
142 */
143 brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
144 brw_CMP(p,
145 vec1(brw_null_reg()),
146 BRW_CONDITIONAL_EQ,
147 tmp0,
148 brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE));
149
150 /* XXX: Is there an easier way to do this? Need to reverse every
151 * second tristrip element: Can ignore sometimes?
152 */
153 brw_IF(p, BRW_EXECUTE_1);
154 {
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));
159 }
160 brw_ELSE(p);
161 {
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));
166 }
167 brw_ENDIF(p);
168
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));
172 }
173
174
175
brw_clip_tri_flat_shade(struct brw_clip_compile * c)176 void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
177 {
178 struct brw_compile *p = &c->func;
179 struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
180
181 brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
182 brw_CMP(p,
183 vec1(brw_null_reg()),
184 BRW_CONDITIONAL_EQ,
185 tmp0,
186 brw_imm_ud(_3DPRIM_POLYGON));
187
188 brw_IF(p, BRW_EXECUTE_1);
189 {
190 brw_clip_copy_colors(c, 1, 0);
191 brw_clip_copy_colors(c, 2, 0);
192 }
193 brw_ELSE(p);
194 {
195 if (c->key.pv_first) {
196 brw_CMP(p,
197 vec1(brw_null_reg()),
198 BRW_CONDITIONAL_EQ,
199 tmp0,
200 brw_imm_ud(_3DPRIM_TRIFAN));
201 brw_IF(p, BRW_EXECUTE_1);
202 {
203 brw_clip_copy_colors(c, 0, 1);
204 brw_clip_copy_colors(c, 2, 1);
205 }
206 brw_ELSE(p);
207 {
208 brw_clip_copy_colors(c, 1, 0);
209 brw_clip_copy_colors(c, 2, 0);
210 }
211 brw_ENDIF(p);
212 }
213 else {
214 brw_clip_copy_colors(c, 0, 2);
215 brw_clip_copy_colors(c, 1, 2);
216 }
217 }
218 brw_ENDIF(p);
219 }
220
221
222
223 /* Use mesa's clipping algorithms, translated to GEN4 assembly.
224 */
brw_clip_tri(struct brw_clip_compile * c)225 void brw_clip_tri( struct brw_clip_compile *c )
226 {
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 GLuint hpos_offset = brw_vert_result_to_offset(&c->vue_map,
236 VERT_RESULT_HPOS);
237
238 brw_MOV(p, get_addr_reg(vtxPrev), brw_address(c->reg.vertex[2]) );
239 brw_MOV(p, get_addr_reg(plane_ptr), brw_clip_plane0_address(c));
240 brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist));
241 brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
242
243 brw_MOV(p, get_addr_reg(freelist_ptr), brw_address(c->reg.vertex[3]) );
244
245 brw_DO(p, BRW_EXECUTE_1);
246 {
247 /* if (planemask & 1)
248 */
249 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
250 brw_AND(p, vec1(brw_null_reg()), c->reg.planemask, brw_imm_ud(1));
251
252 brw_IF(p, BRW_EXECUTE_1);
253 {
254 /* vtxOut = freelist_ptr++
255 */
256 brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(freelist_ptr) );
257 brw_ADD(p, get_addr_reg(freelist_ptr), get_addr_reg(freelist_ptr), brw_imm_uw(c->nr_regs * REG_SIZE));
258
259 if (c->key.nr_userclip)
260 brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
261 else
262 brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
263
264 brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
265 brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0));
266
267 brw_DO(p, BRW_EXECUTE_1);
268 {
269 /* vtx = *input_ptr;
270 */
271 brw_MOV(p, get_addr_reg(vtx), deref_1uw(inlist_ptr, 0));
272
273 /* IS_NEGATIVE(prev) */
274 brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
275 brw_DP4(p, vec4(c->reg.dpPrev), deref_4f(vtxPrev, hpos_offset), c->reg.plane_equation);
276 brw_IF(p, BRW_EXECUTE_1);
277 {
278 /* IS_POSITIVE(next)
279 */
280 brw_set_conditionalmod(p, BRW_CONDITIONAL_GE);
281 brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, hpos_offset), c->reg.plane_equation);
282 brw_IF(p, BRW_EXECUTE_1);
283 {
284
285 /* Coming back in.
286 */
287 brw_ADD(p, c->reg.t, c->reg.dpPrev, negate(c->reg.dp));
288 brw_math_invert(p, c->reg.t, c->reg.t);
289 brw_MUL(p, c->reg.t, c->reg.t, c->reg.dpPrev);
290
291 /* If (vtxOut == 0) vtxOut = vtxPrev
292 */
293 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
294 brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtxPrev) );
295 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
296
297 brw_clip_interp_vertex(c, vtxOut, vtxPrev, vtx, c->reg.t, false);
298
299 /* *outlist_ptr++ = vtxOut;
300 * nr_verts++;
301 * vtxOut = 0;
302 */
303 brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
304 brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
305 brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
306 brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
307 }
308 brw_ENDIF(p);
309
310 }
311 brw_ELSE(p);
312 {
313 /* *outlist_ptr++ = vtxPrev;
314 * nr_verts++;
315 */
316 brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxPrev));
317 brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
318 brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
319
320 /* IS_NEGATIVE(next)
321 */
322 brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
323 brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, hpos_offset), c->reg.plane_equation);
324 brw_IF(p, BRW_EXECUTE_1);
325 {
326 /* Going out of bounds. Avoid division by zero as we
327 * know dp != dpPrev from DIFFERENT_SIGNS, above.
328 */
329 brw_ADD(p, c->reg.t, c->reg.dp, negate(c->reg.dpPrev));
330 brw_math_invert(p, c->reg.t, c->reg.t);
331 brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp);
332
333 /* If (vtxOut == 0) vtxOut = vtx
334 */
335 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ, get_addr_reg(vtxOut), brw_imm_uw(0) );
336 brw_MOV(p, get_addr_reg(vtxOut), get_addr_reg(vtx) );
337 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
338
339 brw_clip_interp_vertex(c, vtxOut, vtx, vtxPrev, c->reg.t, true);
340
341 /* *outlist_ptr++ = vtxOut;
342 * nr_verts++;
343 * vtxOut = 0;
344 */
345 brw_MOV(p, deref_1uw(outlist_ptr, 0), get_addr_reg(vtxOut));
346 brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short)));
347 brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
348 brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
349 }
350 brw_ENDIF(p);
351 }
352 brw_ENDIF(p);
353
354 /* vtxPrev = vtx;
355 * inlist_ptr++;
356 */
357 brw_MOV(p, get_addr_reg(vtxPrev), get_addr_reg(vtx));
358 brw_ADD(p, get_addr_reg(inlist_ptr), get_addr_reg(inlist_ptr), brw_imm_uw(sizeof(short)));
359
360 /* while (--loopcount != 0)
361 */
362 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
363 brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
364 }
365 brw_WHILE(p);
366
367 /* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1]
368 * inlist = outlist
369 * inlist_ptr = &inlist[0]
370 * outlist_ptr = &outlist[0]
371 */
372 brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_w(-2));
373 brw_MOV(p, get_addr_reg(vtxPrev), deref_1uw(outlist_ptr, 0));
374 brw_MOV(p, brw_vec8_grf(c->reg.inlist.nr, 0), brw_vec8_grf(c->reg.outlist.nr, 0));
375 brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist));
376 brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
377 }
378 brw_ENDIF(p);
379
380 /* plane_ptr++;
381 */
382 brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
383
384 /* nr_verts >= 3
385 */
386 brw_CMP(p,
387 vec1(brw_null_reg()),
388 BRW_CONDITIONAL_GE,
389 c->reg.nr_verts,
390 brw_imm_ud(3));
391
392 /* && (planemask>>=1) != 0
393 */
394 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
395 brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
396 }
397 brw_WHILE(p);
398 }
399
400
401
brw_clip_tri_emit_polygon(struct brw_clip_compile * c)402 void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
403 {
404 struct brw_compile *p = &c->func;
405
406 /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
407 */
408 brw_set_conditionalmod(p, BRW_CONDITIONAL_G);
409 brw_ADD(p,
410 c->reg.loopcount,
411 c->reg.nr_verts,
412 brw_imm_d(-2));
413
414 brw_IF(p, BRW_EXECUTE_1);
415 {
416 struct brw_indirect v0 = brw_indirect(0, 0);
417 struct brw_indirect vptr = brw_indirect(1, 0);
418
419 brw_MOV(p, get_addr_reg(vptr), brw_address(c->reg.inlist));
420 brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
421
422 brw_clip_emit_vue(c, v0, 1, 0,
423 ((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
424 | URB_WRITE_PRIM_START));
425
426 brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
427 brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
428
429 brw_DO(p, BRW_EXECUTE_1);
430 {
431 brw_clip_emit_vue(c, v0, 1, 0,
432 (_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT));
433
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));
436
437 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
438 brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
439 }
440 brw_WHILE(p);
441
442 brw_clip_emit_vue(c, v0, 0, 1,
443 ((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
444 | URB_WRITE_PRIM_END));
445 }
446 brw_ENDIF(p);
447 }
448
do_clip_tri(struct brw_clip_compile * c)449 static void do_clip_tri( struct brw_clip_compile *c )
450 {
451 brw_clip_init_planes(c);
452
453 brw_clip_tri(c);
454 }
455
456
maybe_do_clip_tri(struct brw_clip_compile * c)457 static void maybe_do_clip_tri( struct brw_clip_compile *c )
458 {
459 struct brw_compile *p = &c->func;
460
461 brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
462 brw_IF(p, BRW_EXECUTE_1);
463 {
464 do_clip_tri(c);
465 }
466 brw_ENDIF(p);
467 }
468
brw_clip_test(struct brw_clip_compile * c)469 static void brw_clip_test( struct brw_clip_compile *c )
470 {
471 struct brw_reg t = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
472 struct brw_reg t1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
473 struct brw_reg t2 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
474 struct brw_reg t3 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
475
476 struct brw_reg v0 = get_tmp(c);
477 struct brw_reg v1 = get_tmp(c);
478 struct brw_reg v2 = get_tmp(c);
479
480 struct brw_indirect vt0 = brw_indirect(0, 0);
481 struct brw_indirect vt1 = brw_indirect(1, 0);
482 struct brw_indirect vt2 = brw_indirect(2, 0);
483
484 struct brw_compile *p = &c->func;
485 struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
486
487 GLuint hpos_offset = brw_vert_result_to_offset(&c->vue_map,
488 VERT_RESULT_HPOS);
489
490 brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0]));
491 brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1]));
492 brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2]));
493 brw_MOV(p, v0, deref_4f(vt0, hpos_offset));
494 brw_MOV(p, v1, deref_4f(vt1, hpos_offset));
495 brw_MOV(p, v2, deref_4f(vt2, hpos_offset));
496 brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f));
497
498 /* test nearz, xmin, ymin plane */
499 /* clip.xyz < -clip.w */
500 brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, negate(get_element(v0, 3)));
501 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
502 brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, negate(get_element(v1, 3)));
503 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
504 brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, negate(get_element(v2, 3)));
505 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
506
507 /* All vertices are outside of a plane, rejected */
508 brw_AND(p, t, t1, t2);
509 brw_AND(p, t, t, t3);
510 brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
511 brw_OR(p, tmp0, tmp0, get_element(t, 2));
512 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
513 brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
514 brw_IF(p, BRW_EXECUTE_1);
515 {
516 brw_clip_kill_thread(c);
517 }
518 brw_ENDIF(p);
519 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
520
521 /* some vertices are inside a plane, some are outside,need to clip */
522 brw_XOR(p, t, t1, t2);
523 brw_XOR(p, t1, t2, t3);
524 brw_OR(p, t, t, t1);
525 brw_AND(p, t, t, brw_imm_ud(0x1));
526 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
527 get_element(t, 0), brw_imm_ud(0));
528 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5)));
529 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
530 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
531 get_element(t, 1), brw_imm_ud(0));
532 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3)));
533 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
534 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
535 get_element(t, 2), brw_imm_ud(0));
536 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1)));
537 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
538
539 /* test farz, xmax, ymax plane */
540 /* clip.xyz > clip.w */
541 brw_CMP(p, t1, BRW_CONDITIONAL_G, v0, get_element(v0, 3));
542 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
543 brw_CMP(p, t2, BRW_CONDITIONAL_G, v1, get_element(v1, 3));
544 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
545 brw_CMP(p, t3, BRW_CONDITIONAL_G, v2, get_element(v2, 3));
546 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
547
548 /* All vertices are outside of a plane, rejected */
549 brw_AND(p, t, t1, t2);
550 brw_AND(p, t, t, t3);
551 brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
552 brw_OR(p, tmp0, tmp0, get_element(t, 2));
553 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
554 brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
555 brw_IF(p, BRW_EXECUTE_1);
556 {
557 brw_clip_kill_thread(c);
558 }
559 brw_ENDIF(p);
560 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
561
562 /* some vertices are inside a plane, some are outside,need to clip */
563 brw_XOR(p, t, t1, t2);
564 brw_XOR(p, t1, t2, t3);
565 brw_OR(p, t, t, t1);
566 brw_AND(p, t, t, brw_imm_ud(0x1));
567 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
568 get_element(t, 0), brw_imm_ud(0));
569 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4)));
570 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
571 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
572 get_element(t, 1), brw_imm_ud(0));
573 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2)));
574 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
575 brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
576 get_element(t, 2), brw_imm_ud(0));
577 brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0)));
578 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
579
580 release_tmps(c);
581 }
582
583
brw_emit_tri_clip(struct brw_clip_compile * c)584 void brw_emit_tri_clip( struct brw_clip_compile *c )
585 {
586 struct brw_compile *p = &c->func;
587 struct brw_context *brw = p->brw;
588 brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
589 brw_clip_tri_init_vertices(c);
590 brw_clip_init_clipmask(c);
591 brw_clip_init_ff_sync(c);
592
593 /* if -ve rhw workaround bit is set,
594 do cliptest */
595 if (brw->has_negative_rhw_bug) {
596 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
597 brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
598 brw_imm_ud(1<<20));
599 brw_IF(p, BRW_EXECUTE_1);
600 {
601 brw_clip_test(c);
602 }
603 brw_ENDIF(p);
604 }
605 /* Can't push into do_clip_tri because with polygon (or quad)
606 * flatshading, need to apply the flatshade here because we don't
607 * respect the PV when converting to trifan for emit:
608 */
609 if (c->key.do_flat_shading)
610 brw_clip_tri_flat_shade(c);
611
612 if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) ||
613 (c->key.clip_mode == BRW_CLIPMODE_KERNEL_CLIP))
614 do_clip_tri(c);
615 else
616 maybe_do_clip_tri(c);
617
618 brw_clip_tri_emit_polygon(c);
619
620 /* Send an empty message to kill the thread:
621 */
622 brw_clip_kill_thread(c);
623 }
624