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