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