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