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