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