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