i965: Allocate dummy slots for point sprites before computing VUE map.
[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 bool
74 have_attr(struct brw_sf_compile *c, 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 bool
327 calculate_masks(struct brw_sf_compile *c,
328 GLuint reg,
329 GLushort *pc,
330 GLushort *pc_persp,
331 GLushort *pc_linear)
332 {
333 bool is_last_attr = (reg == c->nr_setup_regs - 1);
334 GLbitfield64 persp_mask;
335 GLbitfield64 linear_mask;
336
337 if (c->key.do_flat_shading)
338 persp_mask = c->key.attrs & ~(BITFIELD64_BIT(VERT_RESULT_HPOS) |
339 BITFIELD64_BIT(VERT_RESULT_COL0) |
340 BITFIELD64_BIT(VERT_RESULT_COL1));
341 else
342 persp_mask = c->key.attrs & ~(BITFIELD64_BIT(VERT_RESULT_HPOS));
343
344 if (c->key.do_flat_shading)
345 linear_mask = c->key.attrs & ~(BITFIELD64_BIT(VERT_RESULT_COL0) |
346 BITFIELD64_BIT(VERT_RESULT_COL1));
347 else
348 linear_mask = c->key.attrs;
349
350 *pc_persp = 0;
351 *pc_linear = 0;
352 *pc = 0xf;
353
354 if (persp_mask & BITFIELD64_BIT(vert_reg_to_vert_result(c, reg, 0)))
355 *pc_persp = 0xf;
356
357 if (linear_mask & BITFIELD64_BIT(vert_reg_to_vert_result(c, reg, 0)))
358 *pc_linear = 0xf;
359
360 /* Maybe only processs one attribute on the final round:
361 */
362 if (vert_reg_to_vert_result(c, reg, 1) != BRW_VERT_RESULT_MAX) {
363 *pc |= 0xf0;
364
365 if (persp_mask & BITFIELD64_BIT(vert_reg_to_vert_result(c, reg, 1)))
366 *pc_persp |= 0xf0;
367
368 if (linear_mask & BITFIELD64_BIT(vert_reg_to_vert_result(c, reg, 1)))
369 *pc_linear |= 0xf0;
370 }
371
372 return is_last_attr;
373 }
374
375 /* Calculates the predicate control for which channels of a reg
376 * (containing 2 attrs) to do point sprite coordinate replacement on.
377 */
378 static uint16_t
379 calculate_point_sprite_mask(struct brw_sf_compile *c, GLuint reg)
380 {
381 int vert_result1, vert_result2;
382 uint16_t pc = 0;
383
384 vert_result1 = vert_reg_to_vert_result(c, reg, 0);
385 if (vert_result1 >= VERT_RESULT_TEX0 && vert_result1 <= VERT_RESULT_TEX7) {
386 if (c->key.point_sprite_coord_replace & (1 << (vert_result1 - VERT_RESULT_TEX0)))
387 pc |= 0x0f;
388 }
389 if (vert_result1 == BRW_VERT_RESULT_PNTC)
390 pc |= 0x0f;
391
392 vert_result2 = vert_reg_to_vert_result(c, reg, 1);
393 if (vert_result2 >= VERT_RESULT_TEX0 && vert_result2 <= VERT_RESULT_TEX7) {
394 if (c->key.point_sprite_coord_replace & (1 << (vert_result2 -
395 VERT_RESULT_TEX0)))
396 pc |= 0xf0;
397 }
398 if (vert_result2 == BRW_VERT_RESULT_PNTC)
399 pc |= 0xf0;
400
401 return pc;
402 }
403
404
405
406 void brw_emit_tri_setup(struct brw_sf_compile *c, bool allocate)
407 {
408 struct brw_compile *p = &c->func;
409 GLuint i;
410
411 c->nr_verts = 3;
412
413 if (allocate)
414 alloc_regs(c);
415
416 invert_det(c);
417 copy_z_inv_w(c);
418
419 if (c->key.do_twoside_color)
420 do_twoside_color(c);
421
422 if (c->key.do_flat_shading)
423 do_flatshade_triangle(c);
424
425
426 for (i = 0; i < c->nr_setup_regs; i++)
427 {
428 /* Pair of incoming attributes:
429 */
430 struct brw_reg a0 = offset(c->vert[0], i);
431 struct brw_reg a1 = offset(c->vert[1], i);
432 struct brw_reg a2 = offset(c->vert[2], i);
433 GLushort pc, pc_persp, pc_linear;
434 bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
435
436 if (pc_persp)
437 {
438 brw_set_predicate_control_flag_value(p, pc_persp);
439 brw_MUL(p, a0, a0, c->inv_w[0]);
440 brw_MUL(p, a1, a1, c->inv_w[1]);
441 brw_MUL(p, a2, a2, c->inv_w[2]);
442 }
443
444
445 /* Calculate coefficients for interpolated values:
446 */
447 if (pc_linear)
448 {
449 brw_set_predicate_control_flag_value(p, pc_linear);
450
451 brw_ADD(p, c->a1_sub_a0, a1, negate(a0));
452 brw_ADD(p, c->a2_sub_a0, a2, negate(a0));
453
454 /* calculate dA/dx
455 */
456 brw_MUL(p, brw_null_reg(), c->a1_sub_a0, c->dy2);
457 brw_MAC(p, c->tmp, c->a2_sub_a0, negate(c->dy0));
458 brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
459
460 /* calculate dA/dy
461 */
462 brw_MUL(p, brw_null_reg(), c->a2_sub_a0, c->dx0);
463 brw_MAC(p, c->tmp, c->a1_sub_a0, negate(c->dx2));
464 brw_MUL(p, c->m2Cy, c->tmp, c->inv_det);
465 }
466
467 {
468 brw_set_predicate_control_flag_value(p, pc);
469 /* start point for interpolation
470 */
471 brw_MOV(p, c->m3C0, a0);
472
473 /* Copy m0..m3 to URB. m0 is implicitly copied from r0 in
474 * the send instruction:
475 */
476 brw_urb_WRITE(p,
477 brw_null_reg(),
478 0,
479 brw_vec8_grf(0, 0), /* r0, will be copied to m0 */
480 0, /* allocate */
481 1, /* used */
482 4, /* msg len */
483 0, /* response len */
484 last, /* eot */
485 last, /* writes complete */
486 i*4, /* offset */
487 BRW_URB_SWIZZLE_TRANSPOSE); /* XXX: Swizzle control "SF to windower" */
488 }
489 }
490 }
491
492
493
494 void brw_emit_line_setup(struct brw_sf_compile *c, bool allocate)
495 {
496 struct brw_compile *p = &c->func;
497 GLuint i;
498
499
500 c->nr_verts = 2;
501
502 if (allocate)
503 alloc_regs(c);
504
505 invert_det(c);
506 copy_z_inv_w(c);
507
508 if (c->key.do_flat_shading)
509 do_flatshade_line(c);
510
511 for (i = 0; i < c->nr_setup_regs; i++)
512 {
513 /* Pair of incoming attributes:
514 */
515 struct brw_reg a0 = offset(c->vert[0], i);
516 struct brw_reg a1 = offset(c->vert[1], i);
517 GLushort pc, pc_persp, pc_linear;
518 bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
519
520 if (pc_persp)
521 {
522 brw_set_predicate_control_flag_value(p, pc_persp);
523 brw_MUL(p, a0, a0, c->inv_w[0]);
524 brw_MUL(p, a1, a1, c->inv_w[1]);
525 }
526
527 /* Calculate coefficients for position, color:
528 */
529 if (pc_linear) {
530 brw_set_predicate_control_flag_value(p, pc_linear);
531
532 brw_ADD(p, c->a1_sub_a0, a1, negate(a0));
533
534 brw_MUL(p, c->tmp, c->a1_sub_a0, c->dx0);
535 brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
536
537 brw_MUL(p, c->tmp, c->a1_sub_a0, c->dy0);
538 brw_MUL(p, c->m2Cy, c->tmp, c->inv_det);
539 }
540
541 {
542 brw_set_predicate_control_flag_value(p, pc);
543
544 /* start point for interpolation
545 */
546 brw_MOV(p, c->m3C0, a0);
547
548 /* Copy m0..m3 to URB.
549 */
550 brw_urb_WRITE(p,
551 brw_null_reg(),
552 0,
553 brw_vec8_grf(0, 0),
554 0, /* allocate */
555 1, /* used */
556 4, /* msg len */
557 0, /* response len */
558 last, /* eot */
559 last, /* writes complete */
560 i*4, /* urb destination offset */
561 BRW_URB_SWIZZLE_TRANSPOSE);
562 }
563 }
564 }
565
566 void brw_emit_point_sprite_setup(struct brw_sf_compile *c, bool allocate)
567 {
568 struct brw_compile *p = &c->func;
569 GLuint i;
570
571 c->nr_verts = 1;
572
573 if (allocate)
574 alloc_regs(c);
575
576 copy_z_inv_w(c);
577 for (i = 0; i < c->nr_setup_regs; i++)
578 {
579 struct brw_reg a0 = offset(c->vert[0], i);
580 GLushort pc, pc_persp, pc_linear, pc_coord_replace;
581 bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
582
583 pc_coord_replace = calculate_point_sprite_mask(c, i);
584 pc_persp &= ~pc_coord_replace;
585
586 if (pc_persp) {
587 brw_set_predicate_control_flag_value(p, pc_persp);
588 brw_MUL(p, a0, a0, c->inv_w[0]);
589 }
590
591 /* Point sprite coordinate replacement: A texcoord with this
592 * enabled gets replaced with the value (x, y, 0, 1) where x and
593 * y vary from 0 to 1 across the horizontal and vertical of the
594 * point.
595 */
596 if (pc_coord_replace) {
597 brw_set_predicate_control_flag_value(p, pc_coord_replace);
598 /* Caculate 1.0/PointWidth */
599 brw_math(&c->func,
600 c->tmp,
601 BRW_MATH_FUNCTION_INV,
602 BRW_MATH_SATURATE_NONE,
603 0,
604 c->dx0,
605 BRW_MATH_DATA_SCALAR,
606 BRW_MATH_PRECISION_FULL);
607
608 brw_set_access_mode(p, BRW_ALIGN_16);
609
610 /* dA/dx, dA/dy */
611 brw_MOV(p, c->m1Cx, brw_imm_f(0.0));
612 brw_MOV(p, c->m2Cy, brw_imm_f(0.0));
613 brw_MOV(p, brw_writemask(c->m1Cx, WRITEMASK_X), c->tmp);
614 if (c->key.sprite_origin_lower_left) {
615 brw_MOV(p, brw_writemask(c->m2Cy, WRITEMASK_Y), negate(c->tmp));
616 } else {
617 brw_MOV(p, brw_writemask(c->m2Cy, WRITEMASK_Y), c->tmp);
618 }
619
620 /* attribute constant offset */
621 brw_MOV(p, c->m3C0, brw_imm_f(0.0));
622 if (c->key.sprite_origin_lower_left) {
623 brw_MOV(p, brw_writemask(c->m3C0, WRITEMASK_YW), brw_imm_f(1.0));
624 } else {
625 brw_MOV(p, brw_writemask(c->m3C0, WRITEMASK_W), brw_imm_f(1.0));
626 }
627
628 brw_set_access_mode(p, BRW_ALIGN_1);
629 }
630
631 if (pc & ~pc_coord_replace) {
632 brw_set_predicate_control_flag_value(p, pc & ~pc_coord_replace);
633 brw_MOV(p, c->m1Cx, brw_imm_ud(0));
634 brw_MOV(p, c->m2Cy, brw_imm_ud(0));
635 brw_MOV(p, c->m3C0, a0); /* constant value */
636 }
637
638
639 brw_set_predicate_control_flag_value(p, pc);
640 /* Copy m0..m3 to URB. */
641 brw_urb_WRITE(p,
642 brw_null_reg(),
643 0,
644 brw_vec8_grf(0, 0),
645 0, /* allocate */
646 1, /* used */
647 4, /* msg len */
648 0, /* response len */
649 last, /* eot */
650 last, /* writes complete */
651 i*4, /* urb destination offset */
652 BRW_URB_SWIZZLE_TRANSPOSE);
653 }
654 }
655
656 /* Points setup - several simplifications as all attributes are
657 * constant across the face of the point (point sprites excluded!)
658 */
659 void brw_emit_point_setup(struct brw_sf_compile *c, bool allocate)
660 {
661 struct brw_compile *p = &c->func;
662 GLuint i;
663
664 c->nr_verts = 1;
665
666 if (allocate)
667 alloc_regs(c);
668
669 copy_z_inv_w(c);
670
671 brw_MOV(p, c->m1Cx, brw_imm_ud(0)); /* zero - move out of loop */
672 brw_MOV(p, c->m2Cy, brw_imm_ud(0)); /* zero - move out of loop */
673
674 for (i = 0; i < c->nr_setup_regs; i++)
675 {
676 struct brw_reg a0 = offset(c->vert[0], i);
677 GLushort pc, pc_persp, pc_linear;
678 bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
679
680 if (pc_persp)
681 {
682 /* This seems odd as the values are all constant, but the
683 * fragment shader will be expecting it:
684 */
685 brw_set_predicate_control_flag_value(p, pc_persp);
686 brw_MUL(p, a0, a0, c->inv_w[0]);
687 }
688
689
690 /* The delta values are always zero, just send the starting
691 * coordinate. Again, this is to fit in with the interpolation
692 * code in the fragment shader.
693 */
694 {
695 brw_set_predicate_control_flag_value(p, pc);
696
697 brw_MOV(p, c->m3C0, a0); /* constant value */
698
699 /* Copy m0..m3 to URB.
700 */
701 brw_urb_WRITE(p,
702 brw_null_reg(),
703 0,
704 brw_vec8_grf(0, 0),
705 0, /* allocate */
706 1, /* used */
707 4, /* msg len */
708 0, /* response len */
709 last, /* eot */
710 last, /* writes complete */
711 i*4, /* urb destination offset */
712 BRW_URB_SWIZZLE_TRANSPOSE);
713 }
714 }
715 }
716
717 void brw_emit_anyprim_setup( struct brw_sf_compile *c )
718 {
719 struct brw_compile *p = &c->func;
720 struct brw_reg ip = brw_ip_reg();
721 struct brw_reg payload_prim = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0);
722 struct brw_reg payload_attr = get_element_ud(brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0), 0);
723 struct brw_reg primmask;
724 int jmp;
725 struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD));
726
727 GLuint saveflag;
728
729 c->nr_verts = 3;
730 alloc_regs(c);
731
732 primmask = retype(get_element(c->tmp, 0), BRW_REGISTER_TYPE_UD);
733
734 brw_MOV(p, primmask, brw_imm_ud(1));
735 brw_SHL(p, primmask, primmask, payload_prim);
736
737 brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
738 brw_AND(p, v1_null_ud, primmask, brw_imm_ud((1<<_3DPRIM_TRILIST) |
739 (1<<_3DPRIM_TRISTRIP) |
740 (1<<_3DPRIM_TRIFAN) |
741 (1<<_3DPRIM_TRISTRIP_REVERSE) |
742 (1<<_3DPRIM_POLYGON) |
743 (1<<_3DPRIM_RECTLIST) |
744 (1<<_3DPRIM_TRIFAN_NOSTIPPLE)));
745 jmp = brw_JMPI(p, ip, ip, brw_imm_d(0)) - p->store;
746 {
747 saveflag = p->flag_value;
748 brw_push_insn_state(p);
749 brw_emit_tri_setup( c, false );
750 brw_pop_insn_state(p);
751 p->flag_value = saveflag;
752 /* note - thread killed in subroutine, so must
753 * restore the flag which is changed when building
754 * the subroutine. fix #13240
755 */
756 }
757 brw_land_fwd_jump(p, jmp);
758
759 brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
760 brw_AND(p, v1_null_ud, primmask, brw_imm_ud((1<<_3DPRIM_LINELIST) |
761 (1<<_3DPRIM_LINESTRIP) |
762 (1<<_3DPRIM_LINELOOP) |
763 (1<<_3DPRIM_LINESTRIP_CONT) |
764 (1<<_3DPRIM_LINESTRIP_BF) |
765 (1<<_3DPRIM_LINESTRIP_CONT_BF)));
766 jmp = brw_JMPI(p, ip, ip, brw_imm_d(0)) - p->store;
767 {
768 saveflag = p->flag_value;
769 brw_push_insn_state(p);
770 brw_emit_line_setup( c, false );
771 brw_pop_insn_state(p);
772 p->flag_value = saveflag;
773 /* note - thread killed in subroutine */
774 }
775 brw_land_fwd_jump(p, jmp);
776
777 brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
778 brw_AND(p, v1_null_ud, payload_attr, brw_imm_ud(1<<BRW_SPRITE_POINT_ENABLE));
779 jmp = brw_JMPI(p, ip, ip, brw_imm_d(0)) - p->store;
780 {
781 saveflag = p->flag_value;
782 brw_push_insn_state(p);
783 brw_emit_point_sprite_setup( c, false );
784 brw_pop_insn_state(p);
785 p->flag_value = saveflag;
786 }
787 brw_land_fwd_jump(p, jmp);
788
789 brw_emit_point_setup( c, false );
790 }
791
792
793
794