i965/fs: Implement textureSize (TXS) on Gen5+.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_clip_tri.c
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
44 static void release_tmps( struct brw_clip_compile *c )
45 {
46 c->last_tmp = c->first_tmp;
47 }
48
49
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->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;
80
81 brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0));
82 }
83 }
84
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);
90 i++;
91
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);
94 i++;
95
96 c->reg.inlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
97 i++;
98
99 c->reg.outlist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
100 i++;
101
102 c->reg.freelist = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, i, 0);
103 i++;
104
105 if (!c->key.nr_userclip) {
106 c->reg.fixed_planes = brw_vec8_grf(i, 0);
107 i++;
108 }
109
110 if (c->key.do_unfilled) {
111 c->reg.dir = brw_vec4_grf(i, 0);
112 c->reg.offset = brw_vec4_grf(i, 4);
113 i++;
114 c->reg.tmp0 = brw_vec4_grf(i, 0);
115 c->reg.tmp1 = brw_vec4_grf(i, 4);
116 i++;
117 }
118
119 if (intel->needs_ff_sync) {
120 c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
121 i++;
122 }
123
124 c->first_tmp = i;
125 c->last_tmp = i;
126
127 c->prog_data.urb_read_length = c->nr_regs; /* ? */
128 c->prog_data.total_grf = i;
129 }
130
131
132
133 void brw_clip_tri_init_vertices( struct brw_clip_compile *c )
134 {
135 struct brw_compile *p = &c->func;
136 struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
137
138 /* Initial list of indices for incoming vertexes:
139 */
140 brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
141 brw_CMP(p,
142 vec1(brw_null_reg()),
143 BRW_CONDITIONAL_EQ,
144 tmp0,
145 brw_imm_ud(_3DPRIM_TRISTRIP_REVERSE));
146
147 /* XXX: Is there an easier way to do this? Need to reverse every
148 * second tristrip element: Can ignore sometimes?
149 */
150 brw_IF(p, BRW_EXECUTE_1);
151 {
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));
156 }
157 brw_ELSE(p);
158 {
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));
163 }
164 brw_ENDIF(p);
165
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));
169 }
170
171
172
173 void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
174 {
175 struct brw_compile *p = &c->func;
176 struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
177
178 brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK));
179 brw_CMP(p,
180 vec1(brw_null_reg()),
181 BRW_CONDITIONAL_EQ,
182 tmp0,
183 brw_imm_ud(_3DPRIM_POLYGON));
184
185 brw_IF(p, BRW_EXECUTE_1);
186 {
187 brw_clip_copy_colors(c, 1, 0);
188 brw_clip_copy_colors(c, 2, 0);
189 }
190 brw_ELSE(p);
191 {
192 if (c->key.pv_first) {
193 brw_CMP(p,
194 vec1(brw_null_reg()),
195 BRW_CONDITIONAL_EQ,
196 tmp0,
197 brw_imm_ud(_3DPRIM_TRIFAN));
198 brw_IF(p, BRW_EXECUTE_1);
199 {
200 brw_clip_copy_colors(c, 0, 1);
201 brw_clip_copy_colors(c, 2, 1);
202 }
203 brw_ELSE(p);
204 {
205 brw_clip_copy_colors(c, 1, 0);
206 brw_clip_copy_colors(c, 2, 0);
207 }
208 brw_ENDIF(p);
209 }
210 else {
211 brw_clip_copy_colors(c, 0, 2);
212 brw_clip_copy_colors(c, 1, 2);
213 }
214 }
215 brw_ENDIF(p);
216 }
217
218
219
220 /* Use mesa's clipping algorithms, translated to GEN4 assembly.
221 */
222 void brw_clip_tri( struct brw_clip_compile *c )
223 {
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;
234
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));
239
240 brw_MOV(p, get_addr_reg(freelist_ptr), brw_address(c->reg.vertex[3]) );
241
242 plane_loop = brw_DO(p, BRW_EXECUTE_1);
243 {
244 /* if (planemask & 1)
245 */
246 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
247 brw_AND(p, vec1(brw_null_reg()), c->reg.planemask, brw_imm_ud(1));
248
249 brw_IF(p, BRW_EXECUTE_1);
250 {
251 /* vtxOut = freelist_ptr++
252 */
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));
255
256 if (c->key.nr_userclip)
257 brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
258 else
259 brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0));
260
261 brw_MOV(p, c->reg.loopcount, c->reg.nr_verts);
262 brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0));
263
264 vertex_loop = brw_DO(p, BRW_EXECUTE_1);
265 {
266 /* vtx = *input_ptr;
267 */
268 brw_MOV(p, get_addr_reg(vtx), deref_1uw(inlist_ptr, 0));
269
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);
274 {
275 /* IS_POSITIVE(next)
276 */
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);
280 {
281
282 /* Coming back in.
283 */
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);
287
288 /* If (vtxOut == 0) vtxOut = vtxPrev
289 */
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);
293
294 brw_clip_interp_vertex(c, vtxOut, vtxPrev, vtx, c->reg.t, GL_FALSE);
295
296 /* *outlist_ptr++ = vtxOut;
297 * nr_verts++;
298 * vtxOut = 0;
299 */
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) );
304 }
305 brw_ENDIF(p);
306
307 }
308 brw_ELSE(p);
309 {
310 /* *outlist_ptr++ = vtxPrev;
311 * nr_verts++;
312 */
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));
316
317 /* IS_NEGATIVE(next)
318 */
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);
322 {
323 /* Going out of bounds. Avoid division by zero as we
324 * know dp != dpPrev from DIFFERENT_SIGNS, above.
325 */
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);
329
330 /* If (vtxOut == 0) vtxOut = vtx
331 */
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);
335
336 brw_clip_interp_vertex(c, vtxOut, vtx, vtxPrev, c->reg.t, GL_TRUE);
337
338 /* *outlist_ptr++ = vtxOut;
339 * nr_verts++;
340 * vtxOut = 0;
341 */
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) );
346 }
347 brw_ENDIF(p);
348 }
349 brw_ENDIF(p);
350
351 /* vtxPrev = vtx;
352 * inlist_ptr++;
353 */
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)));
356
357 /* while (--loopcount != 0)
358 */
359 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
360 brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
361 }
362 brw_WHILE(p, vertex_loop);
363
364 /* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1]
365 * inlist = outlist
366 * inlist_ptr = &inlist[0]
367 * outlist_ptr = &outlist[0]
368 */
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));
374 }
375 brw_ENDIF(p);
376
377 /* plane_ptr++;
378 */
379 brw_ADD(p, get_addr_reg(plane_ptr), get_addr_reg(plane_ptr), brw_clip_plane_stride(c));
380
381 /* nr_verts >= 3
382 */
383 brw_CMP(p,
384 vec1(brw_null_reg()),
385 BRW_CONDITIONAL_GE,
386 c->reg.nr_verts,
387 brw_imm_ud(3));
388
389 /* && (planemask>>=1) != 0
390 */
391 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
392 brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1));
393 }
394 brw_WHILE(p, plane_loop);
395 }
396
397
398
399 void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
400 {
401 struct brw_compile *p = &c->func;
402 struct brw_instruction *loop;
403
404 /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
405 */
406 brw_set_conditionalmod(p, BRW_CONDITIONAL_G);
407 brw_ADD(p,
408 c->reg.loopcount,
409 c->reg.nr_verts,
410 brw_imm_d(-2));
411
412 brw_IF(p, BRW_EXECUTE_1);
413 {
414 struct brw_indirect v0 = brw_indirect(0, 0);
415 struct brw_indirect vptr = brw_indirect(1, 0);
416
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));
419
420 brw_clip_emit_vue(c, v0, 1, 0, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_START));
421
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));
424
425 loop = brw_DO(p, BRW_EXECUTE_1);
426 {
427 brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_TRIFAN << 2));
428
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));
431
432 brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
433 brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
434 }
435 brw_WHILE(p, loop);
436
437 brw_clip_emit_vue(c, v0, 0, 1, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_END));
438 }
439 brw_ENDIF(p);
440 }
441
442 static void do_clip_tri( struct brw_clip_compile *c )
443 {
444 brw_clip_init_planes(c);
445
446 brw_clip_tri(c);
447 }
448
449
450 static void maybe_do_clip_tri( struct brw_clip_compile *c )
451 {
452 struct brw_compile *p = &c->func;
453
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);
456 {
457 do_clip_tri(c);
458 }
459 brw_ENDIF(p);
460 }
461
462 static void brw_clip_test( struct brw_clip_compile *c )
463 {
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);
468
469 struct brw_reg v0 = get_tmp(c);
470 struct brw_reg v1 = get_tmp(c);
471 struct brw_reg v2 = get_tmp(c);
472
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);
476
477 struct brw_compile *p = &c->func;
478 struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
479
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));
487
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);
496
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);
505 {
506 brw_clip_kill_thread(c);
507 }
508 brw_ENDIF(p);
509 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
510
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);
514 brw_OR(p, t, t, t1);
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);
528
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);
537
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);
546 {
547 brw_clip_kill_thread(c);
548 }
549 brw_ENDIF(p);
550 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
551
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);
555 brw_OR(p, t, t, t1);
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);
569
570 release_tmps(c);
571 }
572
573
574 void brw_emit_tri_clip( struct brw_clip_compile *c )
575 {
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);
582
583 /* if -ve rhw workaround bit is set,
584 do cliptest */
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),
588 brw_imm_ud(1<<20));
589 brw_IF(p, BRW_EXECUTE_1);
590 {
591 brw_clip_test(c);
592 }
593 brw_ENDIF(p);
594 }
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:
598 */
599 if (c->key.do_flat_shading)
600 brw_clip_tri_flat_shade(c);
601
602 if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) ||
603 (c->key.clip_mode == BRW_CLIPMODE_KERNEL_CLIP))
604 do_clip_tri(c);
605 else
606 maybe_do_clip_tri(c);
607
608 brw_clip_tri_emit_polygon(c);
609
610 /* Send an empty message to kill the thread:
611 */
612 brw_clip_kill_thread(c);
613 }