i965/nir/vec4: Implement load_const intrinsic
[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_codegen *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_codegen *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_codegen *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_codegen *p = &c->func;
195 GLuint nr;
196 GLuint jmpi = 1;
197
198 /* Already done in clip program:
199 */
200 if (c->key.primitive == SF_UNFILLED_TRIS)
201 return;
202
203 if (p->devinfo->gen == 5)
204 jmpi = 2;
205
206 nr = count_flatshaded_attributes(c);
207
208 brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr*2+1)));
209 brw_JMPI(p, c->pv, BRW_PREDICATE_NONE);
210
211 copy_flatshaded_attributes(c, c->vert[1], c->vert[0]);
212 copy_flatshaded_attributes(c, c->vert[2], c->vert[0]);
213 brw_JMPI(p, brw_imm_d(jmpi*(nr*4+1)), BRW_PREDICATE_NONE);
214
215 copy_flatshaded_attributes(c, c->vert[0], c->vert[1]);
216 copy_flatshaded_attributes(c, c->vert[2], c->vert[1]);
217 brw_JMPI(p, brw_imm_d(jmpi*nr*2), BRW_PREDICATE_NONE);
218
219 copy_flatshaded_attributes(c, c->vert[0], c->vert[2]);
220 copy_flatshaded_attributes(c, c->vert[1], c->vert[2]);
221 }
222
223
224 static void do_flatshade_line( struct brw_sf_compile *c )
225 {
226 struct brw_codegen *p = &c->func;
227 GLuint nr;
228 GLuint jmpi = 1;
229
230 /* Already done in clip program:
231 */
232 if (c->key.primitive == SF_UNFILLED_TRIS)
233 return;
234
235 if (p->devinfo->gen == 5)
236 jmpi = 2;
237
238 nr = count_flatshaded_attributes(c);
239
240 brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr+1)));
241 brw_JMPI(p, c->pv, BRW_PREDICATE_NONE);
242 copy_flatshaded_attributes(c, c->vert[1], c->vert[0]);
243
244 brw_JMPI(p, brw_imm_ud(jmpi*nr), BRW_PREDICATE_NONE);
245 copy_flatshaded_attributes(c, c->vert[0], c->vert[1]);
246 }
247
248
249
250 /***********************************************************************
251 * Triangle setup.
252 */
253
254
255 static void alloc_regs( struct brw_sf_compile *c )
256 {
257 GLuint reg, i;
258
259 /* Values computed by fixed function unit:
260 */
261 c->pv = retype(brw_vec1_grf(1, 1), BRW_REGISTER_TYPE_D);
262 c->det = brw_vec1_grf(1, 2);
263 c->dx0 = brw_vec1_grf(1, 3);
264 c->dx2 = brw_vec1_grf(1, 4);
265 c->dy0 = brw_vec1_grf(1, 5);
266 c->dy2 = brw_vec1_grf(1, 6);
267
268 /* z and 1/w passed in seperately:
269 */
270 c->z[0] = brw_vec1_grf(2, 0);
271 c->inv_w[0] = brw_vec1_grf(2, 1);
272 c->z[1] = brw_vec1_grf(2, 2);
273 c->inv_w[1] = brw_vec1_grf(2, 3);
274 c->z[2] = brw_vec1_grf(2, 4);
275 c->inv_w[2] = brw_vec1_grf(2, 5);
276
277 /* The vertices:
278 */
279 reg = 3;
280 for (i = 0; i < c->nr_verts; i++) {
281 c->vert[i] = brw_vec8_grf(reg, 0);
282 reg += c->nr_attr_regs;
283 }
284
285 /* Temporaries, allocated after last vertex reg.
286 */
287 c->inv_det = brw_vec1_grf(reg, 0); reg++;
288 c->a1_sub_a0 = brw_vec8_grf(reg, 0); reg++;
289 c->a2_sub_a0 = brw_vec8_grf(reg, 0); reg++;
290 c->tmp = brw_vec8_grf(reg, 0); reg++;
291
292 /* Note grf allocation:
293 */
294 c->prog_data.total_grf = reg;
295
296
297 /* Outputs of this program - interpolation coefficients for
298 * rasterization:
299 */
300 c->m1Cx = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 1, 0);
301 c->m2Cy = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 2, 0);
302 c->m3C0 = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 3, 0);
303 }
304
305
306 static void copy_z_inv_w( struct brw_sf_compile *c )
307 {
308 struct brw_codegen *p = &c->func;
309 GLuint i;
310
311 /* Copy both scalars with a single MOV:
312 */
313 for (i = 0; i < c->nr_verts; i++)
314 brw_MOV(p, vec2(suboffset(c->vert[i], 2)), vec2(c->z[i]));
315 }
316
317
318 static void invert_det( struct brw_sf_compile *c)
319 {
320 /* Looks like we invert all 8 elements just to get 1/det in
321 * position 2 !?!
322 */
323 gen4_math(&c->func,
324 c->inv_det,
325 BRW_MATH_FUNCTION_INV,
326 0,
327 c->det,
328 BRW_MATH_PRECISION_FULL);
329
330 }
331
332
333 static bool
334 calculate_masks(struct brw_sf_compile *c,
335 GLuint reg,
336 GLushort *pc,
337 GLushort *pc_persp,
338 GLushort *pc_linear)
339 {
340 bool is_last_attr = (reg == c->nr_setup_regs - 1);
341 enum glsl_interp_qualifier interp;
342
343 *pc_persp = 0;
344 *pc_linear = 0;
345 *pc = 0xf;
346
347 interp = c->key.interpolation_mode.mode[vert_reg_to_vue_slot(c, reg, 0)];
348 if (interp == INTERP_QUALIFIER_SMOOTH) {
349 *pc_linear = 0xf;
350 *pc_persp = 0xf;
351 } else if (interp == INTERP_QUALIFIER_NOPERSPECTIVE)
352 *pc_linear = 0xf;
353
354 /* Maybe only processs one attribute on the final round:
355 */
356 if (vert_reg_to_varying(c, reg, 1) != BRW_VARYING_SLOT_COUNT) {
357 *pc |= 0xf0;
358
359 interp = c->key.interpolation_mode.mode[vert_reg_to_vue_slot(c, reg, 1)];
360 if (interp == INTERP_QUALIFIER_SMOOTH) {
361 *pc_linear |= 0xf0;
362 *pc_persp |= 0xf0;
363 } else if (interp == INTERP_QUALIFIER_NOPERSPECTIVE)
364 *pc_linear |= 0xf0;
365 }
366
367 return is_last_attr;
368 }
369
370 /* Calculates the predicate control for which channels of a reg
371 * (containing 2 attrs) to do point sprite coordinate replacement on.
372 */
373 static uint16_t
374 calculate_point_sprite_mask(struct brw_sf_compile *c, GLuint reg)
375 {
376 int varying1, varying2;
377 uint16_t pc = 0;
378
379 varying1 = vert_reg_to_varying(c, reg, 0);
380 if (varying1 >= VARYING_SLOT_TEX0 && varying1 <= VARYING_SLOT_TEX7) {
381 if (c->key.point_sprite_coord_replace & (1 << (varying1 - VARYING_SLOT_TEX0)))
382 pc |= 0x0f;
383 }
384 if (varying1 == BRW_VARYING_SLOT_PNTC)
385 pc |= 0x0f;
386
387 varying2 = vert_reg_to_varying(c, reg, 1);
388 if (varying2 >= VARYING_SLOT_TEX0 && varying2 <= VARYING_SLOT_TEX7) {
389 if (c->key.point_sprite_coord_replace & (1 << (varying2 -
390 VARYING_SLOT_TEX0)))
391 pc |= 0xf0;
392 }
393 if (varying2 == BRW_VARYING_SLOT_PNTC)
394 pc |= 0xf0;
395
396 return pc;
397 }
398
399 static void
400 set_predicate_control_flag_value(struct brw_codegen *p,
401 struct brw_sf_compile *c,
402 unsigned value)
403 {
404 brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
405
406 if (value != 0xff) {
407 if (value != c->flag_value) {
408 brw_MOV(p, brw_flag_reg(0, 0), brw_imm_uw(value));
409 c->flag_value = value;
410 }
411
412 brw_set_default_predicate_control(p, BRW_PREDICATE_NORMAL);
413 }
414 }
415
416 void brw_emit_tri_setup(struct brw_sf_compile *c, bool allocate)
417 {
418 struct brw_codegen *p = &c->func;
419 GLuint i;
420
421 c->flag_value = 0xff;
422 c->nr_verts = 3;
423
424 if (allocate)
425 alloc_regs(c);
426
427 invert_det(c);
428 copy_z_inv_w(c);
429
430 if (c->key.do_twoside_color)
431 do_twoside_color(c);
432
433 if (c->has_flat_shading)
434 do_flatshade_triangle(c);
435
436
437 for (i = 0; i < c->nr_setup_regs; i++)
438 {
439 /* Pair of incoming attributes:
440 */
441 struct brw_reg a0 = offset(c->vert[0], i);
442 struct brw_reg a1 = offset(c->vert[1], i);
443 struct brw_reg a2 = offset(c->vert[2], i);
444 GLushort pc, pc_persp, pc_linear;
445 bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
446
447 if (pc_persp)
448 {
449 set_predicate_control_flag_value(p, c, pc_persp);
450 brw_MUL(p, a0, a0, c->inv_w[0]);
451 brw_MUL(p, a1, a1, c->inv_w[1]);
452 brw_MUL(p, a2, a2, c->inv_w[2]);
453 }
454
455
456 /* Calculate coefficients for interpolated values:
457 */
458 if (pc_linear)
459 {
460 set_predicate_control_flag_value(p, c, pc_linear);
461
462 brw_ADD(p, c->a1_sub_a0, a1, negate(a0));
463 brw_ADD(p, c->a2_sub_a0, a2, negate(a0));
464
465 /* calculate dA/dx
466 */
467 brw_MUL(p, brw_null_reg(), c->a1_sub_a0, c->dy2);
468 brw_MAC(p, c->tmp, c->a2_sub_a0, negate(c->dy0));
469 brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
470
471 /* calculate dA/dy
472 */
473 brw_MUL(p, brw_null_reg(), c->a2_sub_a0, c->dx0);
474 brw_MAC(p, c->tmp, c->a1_sub_a0, negate(c->dx2));
475 brw_MUL(p, c->m2Cy, c->tmp, c->inv_det);
476 }
477
478 {
479 set_predicate_control_flag_value(p, c, pc);
480 /* start point for interpolation
481 */
482 brw_MOV(p, c->m3C0, a0);
483
484 /* Copy m0..m3 to URB. m0 is implicitly copied from r0 in
485 * the send instruction:
486 */
487 brw_urb_WRITE(p,
488 brw_null_reg(),
489 0,
490 brw_vec8_grf(0, 0), /* r0, will be copied to m0 */
491 last ? BRW_URB_WRITE_EOT_COMPLETE
492 : BRW_URB_WRITE_NO_FLAGS,
493 4, /* msg len */
494 0, /* response len */
495 i*4, /* offset */
496 BRW_URB_SWIZZLE_TRANSPOSE); /* XXX: Swizzle control "SF to windower" */
497 }
498 }
499
500 brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
501 }
502
503
504
505 void brw_emit_line_setup(struct brw_sf_compile *c, bool allocate)
506 {
507 struct brw_codegen *p = &c->func;
508 GLuint i;
509
510 c->flag_value = 0xff;
511 c->nr_verts = 2;
512
513 if (allocate)
514 alloc_regs(c);
515
516 invert_det(c);
517 copy_z_inv_w(c);
518
519 if (c->has_flat_shading)
520 do_flatshade_line(c);
521
522 for (i = 0; i < c->nr_setup_regs; i++)
523 {
524 /* Pair of incoming attributes:
525 */
526 struct brw_reg a0 = offset(c->vert[0], i);
527 struct brw_reg a1 = offset(c->vert[1], i);
528 GLushort pc, pc_persp, pc_linear;
529 bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
530
531 if (pc_persp)
532 {
533 set_predicate_control_flag_value(p, c, pc_persp);
534 brw_MUL(p, a0, a0, c->inv_w[0]);
535 brw_MUL(p, a1, a1, c->inv_w[1]);
536 }
537
538 /* Calculate coefficients for position, color:
539 */
540 if (pc_linear) {
541 set_predicate_control_flag_value(p, c, pc_linear);
542
543 brw_ADD(p, c->a1_sub_a0, a1, negate(a0));
544
545 brw_MUL(p, c->tmp, c->a1_sub_a0, c->dx0);
546 brw_MUL(p, c->m1Cx, c->tmp, c->inv_det);
547
548 brw_MUL(p, c->tmp, c->a1_sub_a0, c->dy0);
549 brw_MUL(p, c->m2Cy, c->tmp, c->inv_det);
550 }
551
552 {
553 set_predicate_control_flag_value(p, c, pc);
554
555 /* start point for interpolation
556 */
557 brw_MOV(p, c->m3C0, a0);
558
559 /* Copy m0..m3 to URB.
560 */
561 brw_urb_WRITE(p,
562 brw_null_reg(),
563 0,
564 brw_vec8_grf(0, 0),
565 last ? BRW_URB_WRITE_EOT_COMPLETE
566 : BRW_URB_WRITE_NO_FLAGS,
567 4, /* msg len */
568 0, /* response len */
569 i*4, /* urb destination offset */
570 BRW_URB_SWIZZLE_TRANSPOSE);
571 }
572 }
573
574 brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
575 }
576
577 void brw_emit_point_sprite_setup(struct brw_sf_compile *c, bool allocate)
578 {
579 struct brw_codegen *p = &c->func;
580 GLuint i;
581
582 c->flag_value = 0xff;
583 c->nr_verts = 1;
584
585 if (allocate)
586 alloc_regs(c);
587
588 copy_z_inv_w(c);
589 for (i = 0; i < c->nr_setup_regs; i++)
590 {
591 struct brw_reg a0 = offset(c->vert[0], i);
592 GLushort pc, pc_persp, pc_linear, pc_coord_replace;
593 bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
594
595 pc_coord_replace = calculate_point_sprite_mask(c, i);
596 pc_persp &= ~pc_coord_replace;
597
598 if (pc_persp) {
599 set_predicate_control_flag_value(p, c, pc_persp);
600 brw_MUL(p, a0, a0, c->inv_w[0]);
601 }
602
603 /* Point sprite coordinate replacement: A texcoord with this
604 * enabled gets replaced with the value (x, y, 0, 1) where x and
605 * y vary from 0 to 1 across the horizontal and vertical of the
606 * point.
607 */
608 if (pc_coord_replace) {
609 set_predicate_control_flag_value(p, c, pc_coord_replace);
610 /* Caculate 1.0/PointWidth */
611 gen4_math(&c->func,
612 c->tmp,
613 BRW_MATH_FUNCTION_INV,
614 0,
615 c->dx0,
616 BRW_MATH_PRECISION_FULL);
617
618 brw_set_default_access_mode(p, BRW_ALIGN_16);
619
620 /* dA/dx, dA/dy */
621 brw_MOV(p, c->m1Cx, brw_imm_f(0.0));
622 brw_MOV(p, c->m2Cy, brw_imm_f(0.0));
623 brw_MOV(p, brw_writemask(c->m1Cx, WRITEMASK_X), c->tmp);
624 if (c->key.sprite_origin_lower_left) {
625 brw_MOV(p, brw_writemask(c->m2Cy, WRITEMASK_Y), negate(c->tmp));
626 } else {
627 brw_MOV(p, brw_writemask(c->m2Cy, WRITEMASK_Y), c->tmp);
628 }
629
630 /* attribute constant offset */
631 brw_MOV(p, c->m3C0, brw_imm_f(0.0));
632 if (c->key.sprite_origin_lower_left) {
633 brw_MOV(p, brw_writemask(c->m3C0, WRITEMASK_YW), brw_imm_f(1.0));
634 } else {
635 brw_MOV(p, brw_writemask(c->m3C0, WRITEMASK_W), brw_imm_f(1.0));
636 }
637
638 brw_set_default_access_mode(p, BRW_ALIGN_1);
639 }
640
641 if (pc & ~pc_coord_replace) {
642 set_predicate_control_flag_value(p, c, pc & ~pc_coord_replace);
643 brw_MOV(p, c->m1Cx, brw_imm_ud(0));
644 brw_MOV(p, c->m2Cy, brw_imm_ud(0));
645 brw_MOV(p, c->m3C0, a0); /* constant value */
646 }
647
648
649 set_predicate_control_flag_value(p, c, pc);
650 /* Copy m0..m3 to URB. */
651 brw_urb_WRITE(p,
652 brw_null_reg(),
653 0,
654 brw_vec8_grf(0, 0),
655 last ? BRW_URB_WRITE_EOT_COMPLETE
656 : BRW_URB_WRITE_NO_FLAGS,
657 4, /* msg len */
658 0, /* response len */
659 i*4, /* urb destination offset */
660 BRW_URB_SWIZZLE_TRANSPOSE);
661 }
662
663 brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
664 }
665
666 /* Points setup - several simplifications as all attributes are
667 * constant across the face of the point (point sprites excluded!)
668 */
669 void brw_emit_point_setup(struct brw_sf_compile *c, bool allocate)
670 {
671 struct brw_codegen *p = &c->func;
672 GLuint i;
673
674 c->flag_value = 0xff;
675 c->nr_verts = 1;
676
677 if (allocate)
678 alloc_regs(c);
679
680 copy_z_inv_w(c);
681
682 brw_MOV(p, c->m1Cx, brw_imm_ud(0)); /* zero - move out of loop */
683 brw_MOV(p, c->m2Cy, brw_imm_ud(0)); /* zero - move out of loop */
684
685 for (i = 0; i < c->nr_setup_regs; i++)
686 {
687 struct brw_reg a0 = offset(c->vert[0], i);
688 GLushort pc, pc_persp, pc_linear;
689 bool last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear);
690
691 if (pc_persp)
692 {
693 /* This seems odd as the values are all constant, but the
694 * fragment shader will be expecting it:
695 */
696 set_predicate_control_flag_value(p, c, pc_persp);
697 brw_MUL(p, a0, a0, c->inv_w[0]);
698 }
699
700
701 /* The delta values are always zero, just send the starting
702 * coordinate. Again, this is to fit in with the interpolation
703 * code in the fragment shader.
704 */
705 {
706 set_predicate_control_flag_value(p, c, pc);
707
708 brw_MOV(p, c->m3C0, a0); /* constant value */
709
710 /* Copy m0..m3 to URB.
711 */
712 brw_urb_WRITE(p,
713 brw_null_reg(),
714 0,
715 brw_vec8_grf(0, 0),
716 last ? BRW_URB_WRITE_EOT_COMPLETE
717 : BRW_URB_WRITE_NO_FLAGS,
718 4, /* msg len */
719 0, /* response len */
720 i*4, /* urb destination offset */
721 BRW_URB_SWIZZLE_TRANSPOSE);
722 }
723 }
724
725 brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
726 }
727
728 void brw_emit_anyprim_setup( struct brw_sf_compile *c )
729 {
730 struct brw_codegen *p = &c->func;
731 struct brw_reg payload_prim = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0);
732 struct brw_reg payload_attr = get_element_ud(brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0), 0);
733 struct brw_reg primmask;
734 int jmp;
735 struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD));
736
737 c->nr_verts = 3;
738 alloc_regs(c);
739
740 primmask = retype(get_element(c->tmp, 0), BRW_REGISTER_TYPE_UD);
741
742 brw_MOV(p, primmask, brw_imm_ud(1));
743 brw_SHL(p, primmask, primmask, payload_prim);
744
745 brw_AND(p, v1_null_ud, primmask, brw_imm_ud((1<<_3DPRIM_TRILIST) |
746 (1<<_3DPRIM_TRISTRIP) |
747 (1<<_3DPRIM_TRIFAN) |
748 (1<<_3DPRIM_TRISTRIP_REVERSE) |
749 (1<<_3DPRIM_POLYGON) |
750 (1<<_3DPRIM_RECTLIST) |
751 (1<<_3DPRIM_TRIFAN_NOSTIPPLE)));
752 brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_Z);
753 jmp = brw_JMPI(p, brw_imm_d(0), BRW_PREDICATE_NORMAL) - p->store;
754 brw_emit_tri_setup(c, false);
755 brw_land_fwd_jump(p, jmp);
756
757 brw_AND(p, v1_null_ud, primmask, brw_imm_ud((1<<_3DPRIM_LINELIST) |
758 (1<<_3DPRIM_LINESTRIP) |
759 (1<<_3DPRIM_LINELOOP) |
760 (1<<_3DPRIM_LINESTRIP_CONT) |
761 (1<<_3DPRIM_LINESTRIP_BF) |
762 (1<<_3DPRIM_LINESTRIP_CONT_BF)));
763 brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_Z);
764 jmp = brw_JMPI(p, brw_imm_d(0), BRW_PREDICATE_NORMAL) - p->store;
765 brw_emit_line_setup(c, false);
766 brw_land_fwd_jump(p, jmp);
767
768 brw_AND(p, v1_null_ud, payload_attr, brw_imm_ud(1<<BRW_SPRITE_POINT_ENABLE));
769 brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, BRW_CONDITIONAL_Z);
770 jmp = brw_JMPI(p, brw_imm_d(0), BRW_PREDICATE_NORMAL) - p->store;
771 brw_emit_point_sprite_setup(c, false);
772 brw_land_fwd_jump(p, jmp);
773
774 brw_emit_point_setup( c, false );
775 }
776
777
778
779