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