winsys/drm: Handle circular dependencies in Makefile.egl.
[mesa.git] / src / gallium / drivers / i965 / brw_sf_emit.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
33 #include "brw_batchbuffer.h"
34
35 #include "brw_defines.h"
36 #include "brw_context.h"
37 #include "brw_eu.h"
38 #include "brw_sf.h"
39
40
41 static struct brw_reg get_vert_attr(struct brw_sf_compile *c,
42 struct brw_reg vert,
43 GLuint attr)
44 {
45 GLuint off = attr / 2;
46 GLuint sub = attr % 2;
47
48 return brw_vec4_grf(vert.nr + off, sub * 4);
49 }
50
51
52 /***********************************************************************
53 * Twoside lighting
54 */
55 static void copy_bfc( struct brw_sf_compile *c,
56 struct brw_reg vert )
57 {
58 struct brw_compile *p = &c->func;
59
60 if (c->key.attr_col0 && c->key.attr_bfc0)
61 brw_MOV(p,
62 get_vert_attr(c, vert, c->key.attr_col0),
63 get_vert_attr(c, vert, c->key.attr_bfc0));
64
65 if (c->key.attr_col1 && c->key.attr_bfc1)
66 brw_MOV(p,
67 get_vert_attr(c, vert, c->key.attr_col1),
68 get_vert_attr(c, vert, c->key.attr_bfc1));
69 }
70
71
72 static void do_twoside_color( struct brw_sf_compile *c )
73 {
74 struct brw_compile *p = &c->func;
75 struct brw_instruction *if_insn;
76 GLuint backface_conditional = c->key.frontface_ccw ? BRW_CONDITIONAL_G : BRW_CONDITIONAL_L;
77
78 /* Already done in clip program:
79 */
80 if (c->key.primitive == SF_UNFILLED_TRIS)
81 return;
82
83 /* XXX: What happens if BFC isn't present? This could only happen
84 * for user-supplied vertex programs, as t_vp_build.c always does
85 * the right thing.
86 */
87 if (!(c->key.attr_col0 && c->key.attr_bfc0) &&
88 !(c->key.attr_col1 && c->key.attr_bfc1))
89 return;
90
91 /* Need to use BRW_EXECUTE_4 and also do an 4-wide compare in order
92 * to get all channels active inside the IF. In the clipping code
93 * we run with NoMask, so it's not an option and we can use
94 * BRW_EXECUTE_1 for all comparisions.
95 */
96 brw_push_insn_state(p);
97 brw_CMP(p, vec4(brw_null_reg()), backface_conditional, c->det, brw_imm_f(0));
98 if_insn = brw_IF(p, BRW_EXECUTE_4);
99 {
100 switch (c->nr_verts) {
101 case 3: copy_bfc(c, c->vert[2]);
102 case 2: copy_bfc(c, c->vert[1]);
103 case 1: copy_bfc(c, c->vert[0]);
104 }
105 }
106 brw_ENDIF(p, if_insn);
107 brw_pop_insn_state(p);
108 }
109
110
111
112 /***********************************************************************
113 * Flat shading
114 */
115
116 #define VERT_RESULT_COLOR_BITS ((1<<VERT_RESULT_COL0) | \
117 (1<<VERT_RESULT_COL1))
118
119 static void copy_colors( struct brw_sf_compile *c,
120 struct brw_reg dst,
121 struct brw_reg src)
122 {
123 struct brw_compile *p = &c->func;
124
125 if (c->key.attr_col0)
126 brw_MOV(p,
127 get_vert_attr(c, dst, c->key.attr_col0),
128 get_vert_attr(c, src, c->key.attr_col0));
129
130 if (c->key.attr_col1)
131 brw_MOV(p,
132 get_vert_attr(c, dst, c->key.attr_col1),
133 get_vert_attr(c, src, c->key.attr_col1));
134
135 }
136
137
138
139 /* Need to use a computed jump to copy flatshaded attributes as the
140 * vertices are ordered according to y-coordinate before reaching this
141 * point, so the PV could be anywhere.
142 */
143 static void do_flatshade_triangle( struct brw_sf_compile *c )
144 {
145 struct brw_compile *p = &c->func;
146 struct brw_reg ip = brw_ip_reg();
147 GLuint jmpi = 1;
148 GLuint nr = 0;
149
150 if (c->key.attr_col0)
151 nr++;
152
153 if (c->key.attr_col1)
154 nr++;
155
156 if (nr == 0)
157 return;
158
159 /* Already done in clip program:
160 */
161 if (c->key.primitive == SF_UNFILLED_TRIS)
162 return;
163
164 if (BRW_IS_IGDNG(p->brw))
165 jmpi = 2;
166
167 brw_push_insn_state(p);
168
169 brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr*2+1)));
170 brw_JMPI(p, ip, ip, c->pv);
171
172 copy_colors(c, c->vert[1], c->vert[0]);
173 copy_colors(c, c->vert[2], c->vert[0]);
174 brw_JMPI(p, ip, ip, brw_imm_d(jmpi*(nr*4+1)));
175
176 copy_colors(c, c->vert[0], c->vert[1]);
177 copy_colors(c, c->vert[2], c->vert[1]);
178 brw_JMPI(p, ip, ip, brw_imm_d(jmpi*nr*2));
179
180 copy_colors(c, c->vert[0], c->vert[2]);
181 copy_colors(c, c->vert[1], c->vert[2]);
182
183 brw_pop_insn_state(p);
184 }
185
186
187 static void do_flatshade_line( struct brw_sf_compile *c )
188 {
189 struct brw_compile *p = &c->func;
190 struct brw_reg ip = brw_ip_reg();
191 GLuint jmpi = 1;
192 GLuint nr = 0;
193
194 if (c->key.attr_col0)
195 nr++;
196
197 if (c->key.attr_col1)
198 nr++;
199
200 if (nr == 0)
201 return;
202
203 /* Already done in clip program:
204 */
205 if (c->key.primitive == SF_UNFILLED_TRIS)
206 return;
207
208 if (BRW_IS_IGDNG(p->brw))
209 jmpi = 2;
210
211 brw_push_insn_state(p);
212
213 brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr+1)));
214 brw_JMPI(p, ip, ip, c->pv);
215 copy_colors(c, c->vert[1], c->vert[0]);
216
217 brw_JMPI(p, ip, ip, brw_imm_ud(jmpi*nr));
218 copy_colors(c, c->vert[0], c->vert[1]);
219
220 brw_pop_insn_state(p);
221 }
222
223
224
225 /***********************************************************************
226 * Triangle setup.
227 */
228
229
230 static void alloc_regs( struct brw_sf_compile *c )
231 {
232 GLuint reg, i;
233
234 /* Values computed by fixed function unit:
235 */
236 c->pv = retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_D);
237 c->det = brw_vec1_grf(1, 2);
238 c->dx0 = brw_vec1_grf(1, 3);
239 c->dx2 = brw_vec1_grf(1, 4);
240 c->dy0 = brw_vec1_grf(1, 5);
241 c->dy2 = brw_vec1_grf(1, 6);
242
243 /* z and 1/w passed in seperately:
244 */
245 c->z[0] = brw_vec1_grf(2, 0);
246 c->inv_w[0] = brw_vec1_grf(2, 1);
247 c->z[1] = brw_vec1_grf(2, 2);
248 c->inv_w[1] = brw_vec1_grf(2, 3);
249 c->z[2] = brw_vec1_grf(2, 4);
250 c->inv_w[2] = brw_vec1_grf(2, 5);
251
252 /* The vertices:
253 */
254 reg = 3;
255 for (i = 0; i < c->nr_verts; i++) {
256 c->vert[i] = brw_vec8_grf(reg, 0);
257 reg += c->nr_attr_regs;
258 }
259
260 /* Temporaries, allocated after last vertex reg.
261 */
262 c->inv_det = brw_vec1_grf(reg, 0); reg++;
263 c->a1_sub_a0 = brw_vec8_grf(reg, 0); reg++;
264 c->a2_sub_a0 = brw_vec8_grf(reg, 0); reg++;
265 c->tmp = brw_vec8_grf(reg, 0); reg++;
266
267 /* Note grf allocation:
268 */
269 c->prog_data.total_grf = reg;
270
271
272 /* Outputs of this program - interpolation coefficients for
273 * rasterization:
274 */
275 c->m1Cx = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 1, 0);
276 c->m2Cy = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 2, 0);
277 c->m3C0 = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 3, 0);
278 }
279
280
281 static void copy_z_inv_w( struct brw_sf_compile *c )
282 {
283 struct brw_compile *p = &c->func;
284 GLuint i;
285
286 brw_push_insn_state(p);
287
288 /* Copy both scalars with a single MOV:
289 */
290 for (i = 0; i < c->nr_verts; i++)
291 brw_MOV(p, vec2(suboffset(c->vert[i], 2)), vec2(c->z[i]));
292
293 brw_pop_insn_state(p);
294 }
295
296
297 static void invert_det( struct brw_sf_compile *c)
298 {
299 /* Looks like we invert all 8 elements just to get 1/det in
300 * position 2 !?!
301 */
302 brw_math(&c->func,
303 c->inv_det,
304 BRW_MATH_FUNCTION_INV,
305 BRW_MATH_SATURATE_NONE,
306 0,
307 c->det,
308 BRW_MATH_DATA_SCALAR,
309 BRW_MATH_PRECISION_FULL);
310
311 }
312
313
314 /* Two attributes packed into a wide register. Figure out if either
315 * or both of them need linear/perspective interpolation. Constant
316 * regs are left as-is.
317 */
318 static GLboolean calculate_masks( struct brw_sf_compile *c,
319 GLuint reg,
320 GLushort *pc,
321 GLushort *pc_persp,
322 GLushort *pc_linear)
323 {
324 GLboolean is_last_attr = (reg == c->nr_setup_regs - 1);
325 GLuint persp_mask = c->key.persp_attrs;
326 GLuint linear_mask = (c->key.persp_attrs | c->key.linear_attrs);
327
328 *pc_persp = 0;
329 *pc_linear = 0;
330 *pc = 0xf;
331
332 if (persp_mask & (1 << (reg*2)))
333 *pc_persp = 0xf;
334
335 if (linear_mask & (1 << (reg*2)))
336 *pc_linear = 0xf;
337
338 /* Maybe only processs one attribute on the final round:
339 */
340 if (reg*2+1 < c->nr_setup_attrs) {
341 *pc |= 0xf0;
342
343 if (persp_mask & (1 << (reg*2+1)))
344 *pc_persp |= 0xf0;
345
346 if (linear_mask & (1 << (reg*2+1)))
347 *pc_linear |= 0xf0;
348 }
349
350 return is_last_attr;
351 }
352
353
354 void brw_emit_null_setup( struct brw_sf_compile *c )
355 {
356 struct brw_compile *p = &c->func;
357
358 /* m0 is implicitly copied from r0 in the send instruction:
359 */
360 brw_urb_WRITE(p,
361 brw_null_reg(),
362 0,
363 brw_vec8_grf(0, 0), /* r0, will be copied to m0 */
364 0, /* allocate */
365 1, /* used */
366 1, /* msg len */
367 0, /* response len */
368 1, /* eot */
369 1, /* writes complete */
370 0, /* offset */
371 BRW_URB_SWIZZLE_TRANSPOSE);
372 }
373
374 void brw_emit_tri_setup( struct brw_sf_compile *c, GLboolean allocate)
375 {
376 struct brw_compile *p = &c->func;
377 GLuint i;
378
379 c->nr_verts = 3;
380
381 if (allocate)
382 alloc_regs(c);
383
384 invert_det(c);
385 copy_z_inv_w(c);
386
387 if (c->key.do_twoside_color)
388 do_twoside_color(c);
389
390 if (c->key.do_flat_shading)
391 do_flatshade_triangle(c);
392
393
394 for (i = 0; i < c->nr_setup_regs; i++)
395 {
396 /* Pair of incoming attributes:
397 */
398 struct brw_reg a0 = offset(c->vert[0], i);
399 struct brw_reg a1 = offset(c->vert[1], i);
400 struct brw_reg a2 = offset(c->vert[2], i);
401 GLushort pc, pc_persp, pc_linear;
402 GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
403
404 if (pc_persp)
405 {
406 brw_set_predicate_control_flag_value(p, pc_persp);
407 brw_MUL(p, a0, a0, c->inv_w[0]);
408 brw_MUL(p, a1, a1, c->inv_w[1]);
409 brw_MUL(p, a2, a2, c->inv_w[2]);
410 }
411
412
413 /* Calculate coefficients for interpolated values:
414 */
415 if (pc_linear)
416 {
417 brw_set_predicate_control_flag_value(p, pc_linear);
418
419 brw_ADD(p, c->a1_sub_a0, a1, negate(a0));
420 brw_ADD(p, c->a2_sub_a0, a2, negate(a0));
421
422 /* calculate dA/dx
423 */
424 brw_MUL(p, brw_null_reg(), c->a1_sub_a0, c->dy2);
425 brw_MAC(p, c->tmp, c->a2_sub_a0, negate(c->dy0));
426 brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
427
428 /* calculate dA/dy
429 */
430 brw_MUL(p, brw_null_reg(), c->a2_sub_a0, c->dx0);
431 brw_MAC(p, c->tmp, c->a1_sub_a0, negate(c->dx2));
432 brw_MUL(p, c->m2Cy, c->tmp, c->inv_det);
433 }
434
435 {
436 brw_set_predicate_control_flag_value(p, pc);
437 /* start point for interpolation
438 */
439 brw_MOV(p, c->m3C0, a0);
440
441 /* Copy m0..m3 to URB. m0 is implicitly copied from r0 in
442 * the send instruction:
443 */
444 brw_urb_WRITE(p,
445 brw_null_reg(),
446 0,
447 brw_vec8_grf(0, 0), /* r0, will be copied to m0 */
448 0, /* allocate */
449 1, /* used */
450 4, /* msg len */
451 0, /* response len */
452 last, /* eot */
453 last, /* writes complete */
454 i*4, /* offset */
455 BRW_URB_SWIZZLE_TRANSPOSE); /* XXX: Swizzle control "SF to windower" */
456 }
457 }
458 }
459
460
461
462 void brw_emit_line_setup( struct brw_sf_compile *c, GLboolean allocate)
463 {
464 struct brw_compile *p = &c->func;
465 GLuint i;
466
467
468 c->nr_verts = 2;
469
470 if (allocate)
471 alloc_regs(c);
472
473 invert_det(c);
474 copy_z_inv_w(c);
475
476 if (c->key.do_flat_shading)
477 do_flatshade_line(c);
478
479 for (i = 0; i < c->nr_setup_regs; i++)
480 {
481 /* Pair of incoming attributes:
482 */
483 struct brw_reg a0 = offset(c->vert[0], i);
484 struct brw_reg a1 = offset(c->vert[1], i);
485 GLushort pc, pc_persp, pc_linear;
486 GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
487
488 if (pc_persp)
489 {
490 brw_set_predicate_control_flag_value(p, pc_persp);
491 brw_MUL(p, a0, a0, c->inv_w[0]);
492 brw_MUL(p, a1, a1, c->inv_w[1]);
493 }
494
495 /* Calculate coefficients for position, color:
496 */
497 if (pc_linear) {
498 brw_set_predicate_control_flag_value(p, pc_linear);
499
500 brw_ADD(p, c->a1_sub_a0, a1, negate(a0));
501
502 brw_MUL(p, c->tmp, c->a1_sub_a0, c->dx0);
503 brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
504
505 brw_MUL(p, c->tmp, c->a1_sub_a0, c->dy0);
506 brw_MUL(p, c->m2Cy, c->tmp, c->inv_det);
507 }
508
509 {
510 brw_set_predicate_control_flag_value(p, pc);
511
512 /* start point for interpolation
513 */
514 brw_MOV(p, c->m3C0, a0);
515
516 /* Copy m0..m3 to URB.
517 */
518 brw_urb_WRITE(p,
519 brw_null_reg(),
520 0,
521 brw_vec8_grf(0, 0),
522 0, /* allocate */
523 1, /* used */
524 4, /* msg len */
525 0, /* response len */
526 last, /* eot */
527 last, /* writes complete */
528 i*4, /* urb destination offset */
529 BRW_URB_SWIZZLE_TRANSPOSE);
530 }
531 }
532 }
533
534 void brw_emit_point_sprite_setup( struct brw_sf_compile *c, GLboolean allocate)
535 {
536 struct brw_compile *p = &c->func;
537 GLuint i;
538
539 c->nr_verts = 1;
540
541 if (allocate)
542 alloc_regs(c);
543
544 copy_z_inv_w(c);
545
546 for (i = 0; i < c->nr_setup_regs; i++)
547 {
548 /* XXX: only seems to check point_coord_replace_attrs for every
549 * second attribute?!?
550 */
551 boolean coord_replace = !!(c->key.point_coord_replace_attrs & (1<<(2*i)));
552 struct brw_reg a0 = offset(c->vert[0], i);
553 GLushort pc, pc_persp, pc_linear;
554 GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
555
556 if (pc_persp)
557 {
558 if (coord_replace) {
559 brw_set_predicate_control_flag_value(p, pc_persp);
560 brw_MUL(p, a0, a0, c->inv_w[0]);
561 }
562 }
563
564 if (coord_replace) {
565 /* Caculate 1.0/PointWidth */
566 brw_math(&c->func,
567 c->tmp,
568 BRW_MATH_FUNCTION_INV,
569 BRW_MATH_SATURATE_NONE,
570 0,
571 c->dx0,
572 BRW_MATH_DATA_SCALAR,
573 BRW_MATH_PRECISION_FULL);
574
575 if (c->key.sprite_origin_lower_left) {
576 brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]);
577 brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0));
578 brw_MUL(p, c->m2Cy, c->tmp, negate(c->inv_w[0]));
579 brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0));
580 }
581 else {
582 brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]);
583 brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0));
584 brw_MUL(p, c->m2Cy, c->tmp, c->inv_w[0]);
585 brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0));
586 }
587 }
588 else {
589 brw_MOV(p, c->m1Cx, brw_imm_ud(0));
590 brw_MOV(p, c->m2Cy, brw_imm_ud(0));
591 }
592
593 {
594 brw_set_predicate_control_flag_value(p, pc);
595 if (coord_replace) {
596 if (c->key.sprite_origin_lower_left) {
597 brw_MUL(p, c->m3C0, c->inv_w[0], brw_imm_f(1.0));
598 brw_MOV(p, vec1(suboffset(c->m3C0, 0)), brw_imm_f(0.0));
599 }
600 else {
601 brw_MOV(p, c->m3C0, brw_imm_f(0.0));
602 }
603 }
604 else {
605 brw_MOV(p, c->m3C0, a0); /* constant value */
606 }
607
608 /* Copy m0..m3 to URB.
609 */
610 brw_urb_WRITE(p,
611 brw_null_reg(),
612 0,
613 brw_vec8_grf(0, 0),
614 0, /* allocate */
615 1, /* used */
616 4, /* msg len */
617 0, /* response len */
618 last, /* eot */
619 last, /* writes complete */
620 i*4, /* urb destination offset */
621 BRW_URB_SWIZZLE_TRANSPOSE);
622 }
623 }
624 }
625
626 /* Points setup - several simplifications as all attributes are
627 * constant across the face of the point (point sprites excluded!)
628 */
629 void brw_emit_point_setup( struct brw_sf_compile *c, GLboolean allocate)
630 {
631 struct brw_compile *p = &c->func;
632 GLuint i;
633
634 c->nr_verts = 1;
635
636 if (allocate)
637 alloc_regs(c);
638
639 copy_z_inv_w(c);
640
641 brw_MOV(p, c->m1Cx, brw_imm_ud(0)); /* zero - move out of loop */
642 brw_MOV(p, c->m2Cy, brw_imm_ud(0)); /* zero - move out of loop */
643
644 for (i = 0; i < c->nr_setup_regs; i++)
645 {
646 struct brw_reg a0 = offset(c->vert[0], i);
647 GLushort pc, pc_persp, pc_linear;
648 GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
649
650 if (pc_persp)
651 {
652 /* This seems odd as the values are all constant, but the
653 * fragment shader will be expecting it:
654 */
655 brw_set_predicate_control_flag_value(p, pc_persp);
656 brw_MUL(p, a0, a0, c->inv_w[0]);
657 }
658
659
660 /* The delta values are always zero, just send the starting
661 * coordinate. Again, this is to fit in with the interpolation
662 * code in the fragment shader.
663 */
664 {
665 brw_set_predicate_control_flag_value(p, pc);
666
667 brw_MOV(p, c->m3C0, a0); /* constant value */
668
669 /* Copy m0..m3 to URB.
670 */
671 brw_urb_WRITE(p,
672 brw_null_reg(),
673 0,
674 brw_vec8_grf(0, 0),
675 0, /* allocate */
676 1, /* used */
677 4, /* msg len */
678 0, /* response len */
679 last, /* eot */
680 last, /* writes complete */
681 i*4, /* urb destination offset */
682 BRW_URB_SWIZZLE_TRANSPOSE);
683 }
684 }
685 }
686
687 void brw_emit_anyprim_setup( struct brw_sf_compile *c )
688 {
689 struct brw_compile *p = &c->func;
690 struct brw_reg ip = brw_ip_reg();
691 struct brw_reg payload_prim = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0);
692 struct brw_reg payload_attr = get_element_ud(brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0), 0);
693 struct brw_reg primmask;
694 struct brw_instruction *jmp;
695 struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD));
696
697 GLuint saveflag;
698
699 c->nr_verts = 3;
700 alloc_regs(c);
701
702 primmask = retype(get_element(c->tmp, 0), BRW_REGISTER_TYPE_UD);
703
704 brw_MOV(p, primmask, brw_imm_ud(1));
705 brw_SHL(p, primmask, primmask, payload_prim);
706
707 brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
708 brw_AND(p, v1_null_ud, primmask, brw_imm_ud((1<<_3DPRIM_TRILIST) |
709 (1<<_3DPRIM_TRISTRIP) |
710 (1<<_3DPRIM_TRIFAN) |
711 (1<<_3DPRIM_TRISTRIP_REVERSE) |
712 (1<<_3DPRIM_POLYGON) |
713 (1<<_3DPRIM_RECTLIST) |
714 (1<<_3DPRIM_TRIFAN_NOSTIPPLE)));
715 jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
716 {
717 saveflag = p->flag_value;
718 brw_push_insn_state(p);
719 brw_emit_tri_setup( c, GL_FALSE );
720 brw_pop_insn_state(p);
721 p->flag_value = saveflag;
722 /* note - thread killed in subroutine, so must
723 * restore the flag which is changed when building
724 * the subroutine. fix #13240
725 */
726 }
727 brw_land_fwd_jump(p, jmp);
728
729 brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
730 brw_AND(p, v1_null_ud, primmask, brw_imm_ud((1<<_3DPRIM_LINELIST) |
731 (1<<_3DPRIM_LINESTRIP) |
732 (1<<_3DPRIM_LINELOOP) |
733 (1<<_3DPRIM_LINESTRIP_CONT) |
734 (1<<_3DPRIM_LINESTRIP_BF) |
735 (1<<_3DPRIM_LINESTRIP_CONT_BF)));
736 jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
737 {
738 saveflag = p->flag_value;
739 brw_push_insn_state(p);
740 brw_emit_line_setup( c, GL_FALSE );
741 brw_pop_insn_state(p);
742 p->flag_value = saveflag;
743 /* note - thread killed in subroutine */
744 }
745 brw_land_fwd_jump(p, jmp);
746
747 brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
748 brw_AND(p, v1_null_ud, payload_attr, brw_imm_ud(1<<BRW_SPRITE_POINT_ENABLE));
749 jmp = brw_JMPI(p, ip, ip, brw_imm_d(0));
750 {
751 saveflag = p->flag_value;
752 brw_push_insn_state(p);
753 brw_emit_point_sprite_setup( c, GL_FALSE );
754 brw_pop_insn_state(p);
755 p->flag_value = saveflag;
756 }
757 brw_land_fwd_jump(p, jmp);
758
759 brw_emit_point_setup( c, GL_FALSE );
760 }
761
762
763
764