OSDN Git Service

i965/fs: Use the LRP instruction for ir_triop_lrp when possible.
[android-x86/external-mesa.git] / src / mesa / drivers / dri / i965 / brw_fs_emit.cpp
1 /*
2  * Copyright © 2010 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23
24 /** @file brw_fs_emit.cpp
25  *
26  * This file supports emitting code from the FS LIR to the actual
27  * native instructions.
28  */
29
30 extern "C" {
31 #include "main/macros.h"
32 #include "brw_context.h"
33 #include "brw_eu.h"
34 } /* extern "C" */
35
36 #include "brw_fs.h"
37 #include "brw_cfg.h"
38 #include "glsl/ir_print_visitor.h"
39
40 fs_generator::fs_generator(struct brw_context *brw,
41                            struct brw_wm_compile *c,
42                            struct gl_shader_program *prog,
43                            struct gl_fragment_program *fp,
44                            bool dual_source_output)
45
46    : brw(brw), c(c), prog(prog), fp(fp), dual_source_output(dual_source_output)
47 {
48    intel = &brw->intel;
49    ctx = &intel->ctx;
50
51    shader = prog ? prog->_LinkedShaders[MESA_SHADER_FRAGMENT] : NULL;
52
53    mem_ctx = c;
54
55    p = rzalloc(mem_ctx, struct brw_compile);
56    brw_init_compile(brw, p, mem_ctx);
57 }
58
59 fs_generator::~fs_generator()
60 {
61 }
62
63 void
64 fs_generator::patch_discard_jumps_to_fb_writes()
65 {
66    if (intel->gen < 6 || this->discard_halt_patches.is_empty())
67       return;
68
69    /* There is a somewhat strange undocumented requirement of using
70     * HALT, according to the simulator.  If some channel has HALTed to
71     * a particular UIP, then by the end of the program, every channel
72     * must have HALTed to that UIP.  Furthermore, the tracking is a
73     * stack, so you can't do the final halt of a UIP after starting
74     * halting to a new UIP.
75     *
76     * Symptoms of not emitting this instruction on actual hardware
77     * included GPU hangs and sparkly rendering on the piglit discard
78     * tests.
79     */
80    struct brw_instruction *last_halt = gen6_HALT(p);
81    last_halt->bits3.break_cont.uip = 2;
82    last_halt->bits3.break_cont.jip = 2;
83
84    int ip = p->nr_insn;
85
86    foreach_list(node, &this->discard_halt_patches) {
87       ip_record *patch_ip = (ip_record *)node;
88       struct brw_instruction *patch = &p->store[patch_ip->ip];
89
90       assert(patch->header.opcode == BRW_OPCODE_HALT);
91       /* HALT takes a half-instruction distance from the pre-incremented IP. */
92       patch->bits3.break_cont.uip = (ip - patch_ip->ip) * 2;
93    }
94
95    this->discard_halt_patches.make_empty();
96 }
97
98 void
99 fs_generator::generate_fb_write(fs_inst *inst)
100 {
101    bool eot = inst->eot;
102    struct brw_reg implied_header;
103    uint32_t msg_control;
104
105    /* Note that the jumps emitted to this point mean that the g0 ->
106     * base_mrf setup must be inside of this function, so that we jump
107     * to a point containing it.
108     */
109    patch_discard_jumps_to_fb_writes();
110
111    /* Header is 2 regs, g0 and g1 are the contents. g0 will be implied
112     * move, here's g1.
113     */
114    brw_push_insn_state(p);
115    brw_set_mask_control(p, BRW_MASK_DISABLE);
116    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
117
118    if (fp->UsesKill) {
119       struct brw_reg pixel_mask;
120
121       if (intel->gen >= 6)
122          pixel_mask = retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_UW);
123       else
124          pixel_mask = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
125
126       brw_MOV(p, pixel_mask, brw_flag_reg(0, 1));
127    }
128
129    if (inst->header_present) {
130       if (intel->gen >= 6) {
131          brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
132          brw_MOV(p,
133                  retype(brw_message_reg(inst->base_mrf), BRW_REGISTER_TYPE_UD),
134                  retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD));
135          brw_set_compression_control(p, BRW_COMPRESSION_NONE);
136
137          if (inst->target > 0 &&
138              c->key.nr_color_regions > 1 &&
139              c->key.sample_alpha_to_coverage) {
140             /* Set "Source0 Alpha Present to RenderTarget" bit in message
141              * header.
142              */
143             brw_OR(p,
144                    vec1(retype(brw_message_reg(inst->base_mrf), BRW_REGISTER_TYPE_UD)),
145                    vec1(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD)),
146                    brw_imm_ud(0x1 << 11));
147          }
148
149          if (inst->target > 0) {
150             /* Set the render target index for choosing BLEND_STATE. */
151             brw_MOV(p, retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE,
152                                            inst->base_mrf, 2),
153                               BRW_REGISTER_TYPE_UD),
154                     brw_imm_ud(inst->target));
155          }
156
157          implied_header = brw_null_reg();
158       } else {
159          implied_header = retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW);
160
161          brw_MOV(p,
162                  brw_message_reg(inst->base_mrf + 1),
163                  brw_vec8_grf(1, 0));
164       }
165    } else {
166       implied_header = brw_null_reg();
167    }
168
169    if (this->dual_source_output)
170       msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01;
171    else if (dispatch_width == 16)
172       msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE;
173    else
174       msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01;
175
176    brw_pop_insn_state(p);
177
178    brw_fb_WRITE(p,
179                 dispatch_width,
180                 inst->base_mrf,
181                 implied_header,
182                 msg_control,
183                 inst->target,
184                 inst->mlen,
185                 0,
186                 eot,
187                 inst->header_present);
188 }
189
190 /* Computes the integer pixel x,y values from the origin.
191  *
192  * This is the basis of gl_FragCoord computation, but is also used
193  * pre-gen6 for computing the deltas from v0 for computing
194  * interpolation.
195  */
196 void
197 fs_generator::generate_pixel_xy(struct brw_reg dst, bool is_x)
198 {
199    struct brw_reg g1_uw = retype(brw_vec1_grf(1, 0), BRW_REGISTER_TYPE_UW);
200    struct brw_reg src;
201    struct brw_reg deltas;
202
203    if (is_x) {
204       src = stride(suboffset(g1_uw, 4), 2, 4, 0);
205       deltas = brw_imm_v(0x10101010);
206    } else {
207       src = stride(suboffset(g1_uw, 5), 2, 4, 0);
208       deltas = brw_imm_v(0x11001100);
209    }
210
211    if (dispatch_width == 16) {
212       dst = vec16(dst);
213    }
214
215    /* We do this 8 or 16-wide, but since the destination is UW we
216     * don't do compression in the 16-wide case.
217     */
218    brw_push_insn_state(p);
219    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
220    brw_ADD(p, dst, src, deltas);
221    brw_pop_insn_state(p);
222 }
223
224 void
225 fs_generator::generate_linterp(fs_inst *inst,
226                              struct brw_reg dst, struct brw_reg *src)
227 {
228    struct brw_reg delta_x = src[0];
229    struct brw_reg delta_y = src[1];
230    struct brw_reg interp = src[2];
231
232    if (brw->has_pln &&
233        delta_y.nr == delta_x.nr + 1 &&
234        (intel->gen >= 6 || (delta_x.nr & 1) == 0)) {
235       brw_PLN(p, dst, interp, delta_x);
236    } else {
237       brw_LINE(p, brw_null_reg(), interp, delta_x);
238       brw_MAC(p, dst, suboffset(interp, 1), delta_y);
239    }
240 }
241
242 void
243 fs_generator::generate_math1_gen7(fs_inst *inst,
244                                 struct brw_reg dst,
245                                 struct brw_reg src0)
246 {
247    assert(inst->mlen == 0);
248    brw_math(p, dst,
249             brw_math_function(inst->opcode),
250             0, src0,
251             BRW_MATH_DATA_VECTOR,
252             BRW_MATH_PRECISION_FULL);
253 }
254
255 void
256 fs_generator::generate_math2_gen7(fs_inst *inst,
257                                 struct brw_reg dst,
258                                 struct brw_reg src0,
259                                 struct brw_reg src1)
260 {
261    assert(inst->mlen == 0);
262    brw_math2(p, dst, brw_math_function(inst->opcode), src0, src1);
263 }
264
265 void
266 fs_generator::generate_math1_gen6(fs_inst *inst,
267                                 struct brw_reg dst,
268                                 struct brw_reg src0)
269 {
270    int op = brw_math_function(inst->opcode);
271
272    assert(inst->mlen == 0);
273
274    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
275    brw_math(p, dst,
276             op,
277             0, src0,
278             BRW_MATH_DATA_VECTOR,
279             BRW_MATH_PRECISION_FULL);
280
281    if (dispatch_width == 16) {
282       brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
283       brw_math(p, sechalf(dst),
284                op,
285                0, sechalf(src0),
286                BRW_MATH_DATA_VECTOR,
287                BRW_MATH_PRECISION_FULL);
288       brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
289    }
290 }
291
292 void
293 fs_generator::generate_math2_gen6(fs_inst *inst,
294                                 struct brw_reg dst,
295                                 struct brw_reg src0,
296                                 struct brw_reg src1)
297 {
298    int op = brw_math_function(inst->opcode);
299
300    assert(inst->mlen == 0);
301
302    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
303    brw_math2(p, dst, op, src0, src1);
304
305    if (dispatch_width == 16) {
306       brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
307       brw_math2(p, sechalf(dst), op, sechalf(src0), sechalf(src1));
308       brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
309    }
310 }
311
312 void
313 fs_generator::generate_math_gen4(fs_inst *inst,
314                                struct brw_reg dst,
315                                struct brw_reg src)
316 {
317    int op = brw_math_function(inst->opcode);
318
319    assert(inst->mlen >= 1);
320
321    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
322    brw_math(p, dst,
323             op,
324             inst->base_mrf, src,
325             BRW_MATH_DATA_VECTOR,
326             BRW_MATH_PRECISION_FULL);
327
328    if (dispatch_width == 16) {
329       brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
330       brw_math(p, sechalf(dst),
331                op,
332                inst->base_mrf + 1, sechalf(src),
333                BRW_MATH_DATA_VECTOR,
334                BRW_MATH_PRECISION_FULL);
335
336       brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
337    }
338 }
339
340 void
341 fs_generator::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
342 {
343    int msg_type = -1;
344    int rlen = 4;
345    uint32_t simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD8;
346    uint32_t return_format;
347
348    switch (dst.type) {
349    case BRW_REGISTER_TYPE_D:
350       return_format = BRW_SAMPLER_RETURN_FORMAT_SINT32;
351       break;
352    case BRW_REGISTER_TYPE_UD:
353       return_format = BRW_SAMPLER_RETURN_FORMAT_UINT32;
354       break;
355    default:
356       return_format = BRW_SAMPLER_RETURN_FORMAT_FLOAT32;
357       break;
358    }
359
360    if (dispatch_width == 16)
361       simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD16;
362
363    if (intel->gen >= 5) {
364       switch (inst->opcode) {
365       case SHADER_OPCODE_TEX:
366          if (inst->shadow_compare) {
367             msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_COMPARE;
368          } else {
369             msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE;
370          }
371          break;
372       case FS_OPCODE_TXB:
373          if (inst->shadow_compare) {
374             msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_BIAS_COMPARE;
375          } else {
376             msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_BIAS;
377          }
378          break;
379       case SHADER_OPCODE_TXL:
380          if (inst->shadow_compare) {
381             msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_LOD_COMPARE;
382          } else {
383             msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_LOD;
384          }
385          break;
386       case SHADER_OPCODE_TXS:
387          msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_RESINFO;
388          break;
389       case SHADER_OPCODE_TXD:
390          if (inst->shadow_compare) {
391             /* Gen7.5+.  Otherwise, lowered by brw_lower_texture_gradients(). */
392             assert(intel->is_haswell);
393             msg_type = HSW_SAMPLER_MESSAGE_SAMPLE_DERIV_COMPARE;
394          } else {
395             msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_DERIVS;
396          }
397          break;
398       case SHADER_OPCODE_TXF:
399          msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_LD;
400          break;
401       default:
402          assert(!"not reached");
403          break;
404       }
405    } else {
406       switch (inst->opcode) {
407       case SHADER_OPCODE_TEX:
408          /* Note that G45 and older determines shadow compare and dispatch width
409           * from message length for most messages.
410           */
411          assert(dispatch_width == 8);
412          msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE;
413          if (inst->shadow_compare) {
414             assert(inst->mlen == 6);
415          } else {
416             assert(inst->mlen <= 4);
417          }
418          break;
419       case FS_OPCODE_TXB:
420          if (inst->shadow_compare) {
421             assert(inst->mlen == 6);
422             msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_BIAS_COMPARE;
423          } else {
424             assert(inst->mlen == 9);
425             msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
426             simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD16;
427          }
428          break;
429       case SHADER_OPCODE_TXL:
430          if (inst->shadow_compare) {
431             assert(inst->mlen == 6);
432             msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_LOD_COMPARE;
433          } else {
434             assert(inst->mlen == 9);
435             msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD;
436             simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD16;
437          }
438          break;
439       case SHADER_OPCODE_TXD:
440          /* There is no sample_d_c message; comparisons are done manually */
441          assert(inst->mlen == 7 || inst->mlen == 10);
442          msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS;
443          break;
444       case SHADER_OPCODE_TXF:
445          assert(inst->mlen == 9);
446          msg_type = BRW_SAMPLER_MESSAGE_SIMD16_LD;
447          simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD16;
448          break;
449       case SHADER_OPCODE_TXS:
450          assert(inst->mlen == 3);
451          msg_type = BRW_SAMPLER_MESSAGE_SIMD16_RESINFO;
452          simd_mode = BRW_SAMPLER_SIMD_MODE_SIMD16;
453          break;
454       default:
455          assert(!"not reached");
456          break;
457       }
458    }
459    assert(msg_type != -1);
460
461    if (simd_mode == BRW_SAMPLER_SIMD_MODE_SIMD16) {
462       rlen = 8;
463       dst = vec16(dst);
464    }
465
466    /* Load the message header if present.  If there's a texture offset,
467     * we need to set it up explicitly and load the offset bitfield.
468     * Otherwise, we can use an implied move from g0 to the first message reg.
469     */
470    if (inst->texture_offset) {
471       brw_push_insn_state(p);
472       brw_set_mask_control(p, BRW_MASK_DISABLE);
473       brw_set_compression_control(p, BRW_COMPRESSION_NONE);
474       /* Explicitly set up the message header by copying g0 to the MRF. */
475       brw_MOV(p, retype(brw_message_reg(inst->base_mrf), BRW_REGISTER_TYPE_UD),
476                  retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD));
477
478       /* Then set the offset bits in DWord 2. */
479       brw_MOV(p, retype(brw_vec1_reg(BRW_MESSAGE_REGISTER_FILE,
480                                      inst->base_mrf, 2), BRW_REGISTER_TYPE_UD),
481                  brw_imm_ud(inst->texture_offset));
482       brw_pop_insn_state(p);
483    } else if (inst->header_present) {
484       /* Set up an implied move from g0 to the MRF. */
485       src = retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW);
486    }
487
488    brw_SAMPLE(p,
489               retype(dst, BRW_REGISTER_TYPE_UW),
490               inst->base_mrf,
491               src,
492               SURF_INDEX_TEXTURE(inst->sampler),
493               inst->sampler,
494               msg_type,
495               rlen,
496               inst->mlen,
497               inst->header_present,
498               simd_mode,
499               return_format);
500 }
501
502
503 /* For OPCODE_DDX and OPCODE_DDY, per channel of output we've got input
504  * looking like:
505  *
506  * arg0: ss0.tl ss0.tr ss0.bl ss0.br ss1.tl ss1.tr ss1.bl ss1.br
507  *
508  * and we're trying to produce:
509  *
510  *           DDX                     DDY
511  * dst: (ss0.tr - ss0.tl)     (ss0.tl - ss0.bl)
512  *      (ss0.tr - ss0.tl)     (ss0.tr - ss0.br)
513  *      (ss0.br - ss0.bl)     (ss0.tl - ss0.bl)
514  *      (ss0.br - ss0.bl)     (ss0.tr - ss0.br)
515  *      (ss1.tr - ss1.tl)     (ss1.tl - ss1.bl)
516  *      (ss1.tr - ss1.tl)     (ss1.tr - ss1.br)
517  *      (ss1.br - ss1.bl)     (ss1.tl - ss1.bl)
518  *      (ss1.br - ss1.bl)     (ss1.tr - ss1.br)
519  *
520  * and add another set of two more subspans if in 16-pixel dispatch mode.
521  *
522  * For DDX, it ends up being easy: width = 2, horiz=0 gets us the same result
523  * for each pair, and vertstride = 2 jumps us 2 elements after processing a
524  * pair. But for DDY, it's harder, as we want to produce the pairs swizzled
525  * between each other.  We could probably do it like ddx and swizzle the right
526  * order later, but bail for now and just produce
527  * ((ss0.tl - ss0.bl)x4 (ss1.tl - ss1.bl)x4)
528  */
529 void
530 fs_generator::generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
531 {
532    struct brw_reg src0 = brw_reg(src.file, src.nr, 1,
533                                  BRW_REGISTER_TYPE_F,
534                                  BRW_VERTICAL_STRIDE_2,
535                                  BRW_WIDTH_2,
536                                  BRW_HORIZONTAL_STRIDE_0,
537                                  BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
538    struct brw_reg src1 = brw_reg(src.file, src.nr, 0,
539                                  BRW_REGISTER_TYPE_F,
540                                  BRW_VERTICAL_STRIDE_2,
541                                  BRW_WIDTH_2,
542                                  BRW_HORIZONTAL_STRIDE_0,
543                                  BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
544    brw_ADD(p, dst, src0, negate(src1));
545 }
546
547 /* The negate_value boolean is used to negate the derivative computation for
548  * FBOs, since they place the origin at the upper left instead of the lower
549  * left.
550  */
551 void
552 fs_generator::generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src,
553                          bool negate_value)
554 {
555    struct brw_reg src0 = brw_reg(src.file, src.nr, 0,
556                                  BRW_REGISTER_TYPE_F,
557                                  BRW_VERTICAL_STRIDE_4,
558                                  BRW_WIDTH_4,
559                                  BRW_HORIZONTAL_STRIDE_0,
560                                  BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
561    struct brw_reg src1 = brw_reg(src.file, src.nr, 2,
562                                  BRW_REGISTER_TYPE_F,
563                                  BRW_VERTICAL_STRIDE_4,
564                                  BRW_WIDTH_4,
565                                  BRW_HORIZONTAL_STRIDE_0,
566                                  BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
567    if (negate_value)
568       brw_ADD(p, dst, src1, negate(src0));
569    else
570       brw_ADD(p, dst, src0, negate(src1));
571 }
572
573 void
574 fs_generator::generate_discard_jump(fs_inst *inst)
575 {
576    assert(intel->gen >= 6);
577
578    /* This HALT will be patched up at FB write time to point UIP at the end of
579     * the program, and at brw_uip_jip() JIP will be set to the end of the
580     * current block (or the program).
581     */
582    this->discard_halt_patches.push_tail(new(mem_ctx) ip_record(p->nr_insn));
583
584    brw_push_insn_state(p);
585    brw_set_mask_control(p, BRW_MASK_DISABLE);
586    gen6_HALT(p);
587    brw_pop_insn_state(p);
588 }
589
590 void
591 fs_generator::generate_spill(fs_inst *inst, struct brw_reg src)
592 {
593    assert(inst->mlen != 0);
594
595    brw_MOV(p,
596            retype(brw_message_reg(inst->base_mrf + 1), BRW_REGISTER_TYPE_UD),
597            retype(src, BRW_REGISTER_TYPE_UD));
598    brw_oword_block_write_scratch(p, brw_message_reg(inst->base_mrf), 1,
599                                  inst->offset);
600 }
601
602 void
603 fs_generator::generate_unspill(fs_inst *inst, struct brw_reg dst)
604 {
605    assert(inst->mlen != 0);
606
607    brw_oword_block_read_scratch(p, dst, brw_message_reg(inst->base_mrf), 1,
608                                 inst->offset);
609 }
610
611 void
612 fs_generator::generate_uniform_pull_constant_load(fs_inst *inst,
613                                                   struct brw_reg dst,
614                                                   struct brw_reg index,
615                                                   struct brw_reg offset)
616 {
617    assert(inst->mlen != 0);
618
619    assert(index.file == BRW_IMMEDIATE_VALUE &&
620           index.type == BRW_REGISTER_TYPE_UD);
621    uint32_t surf_index = index.dw1.ud;
622
623    assert(offset.file == BRW_IMMEDIATE_VALUE &&
624           offset.type == BRW_REGISTER_TYPE_UD);
625    uint32_t read_offset = offset.dw1.ud;
626
627    brw_oword_block_read(p, dst, brw_message_reg(inst->base_mrf),
628                         read_offset, surf_index);
629 }
630
631 void
632 fs_generator::generate_uniform_pull_constant_load_gen7(fs_inst *inst,
633                                                        struct brw_reg dst,
634                                                        struct brw_reg index,
635                                                        struct brw_reg offset)
636 {
637    assert(inst->mlen == 0);
638
639    assert(index.file == BRW_IMMEDIATE_VALUE &&
640           index.type == BRW_REGISTER_TYPE_UD);
641    uint32_t surf_index = index.dw1.ud;
642
643    assert(offset.file == BRW_GENERAL_REGISTER_FILE);
644
645    brw_push_insn_state(p);
646    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
647    brw_set_mask_control(p, BRW_MASK_DISABLE);
648    struct brw_instruction *send = brw_next_insn(p, BRW_OPCODE_SEND);
649    brw_pop_insn_state(p);
650
651    brw_set_dest(p, send, dst);
652    brw_set_src0(p, send, offset);
653
654    uint32_t msg_control = BRW_DATAPORT_OWORD_BLOCK_2_OWORDS;
655    uint32_t msg_type = BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ;
656    bool header_present = true;
657    brw_set_dp_read_message(p, send,
658                            surf_index,
659                            msg_control,
660                            msg_type,
661                            BRW_DATAPORT_READ_TARGET_DATA_CACHE,
662                            1,
663                            header_present,
664                            1);
665 }
666
667 void
668 fs_generator::generate_varying_pull_constant_load(fs_inst *inst,
669                                                   struct brw_reg dst,
670                                                   struct brw_reg index)
671 {
672    assert(intel->gen < 7); /* Should use the gen7 variant. */
673    assert(inst->header_present);
674
675    assert(index.file == BRW_IMMEDIATE_VALUE &&
676           index.type == BRW_REGISTER_TYPE_UD);
677    uint32_t surf_index = index.dw1.ud;
678
679    uint32_t msg_type, msg_control, rlen;
680    if (intel->gen >= 6)
681       msg_type = GEN6_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ;
682    else if (intel->gen == 5 || intel->is_g4x)
683       msg_type = G45_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ;
684    else
685       msg_type = BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ;
686
687    if (dispatch_width == 16) {
688       msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS;
689       rlen = 2;
690    } else {
691       msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS;
692       rlen = 1;
693    }
694
695    struct brw_reg header = brw_vec8_grf(0, 0);
696    gen6_resolve_implied_move(p, &header, inst->base_mrf);
697
698    struct brw_instruction *send = brw_next_insn(p, BRW_OPCODE_SEND);
699    brw_set_dest(p, send, dst);
700    brw_set_src0(p, send, header);
701    if (intel->gen < 6)
702       send->header.destreg__conditionalmod = inst->base_mrf;
703    brw_set_dp_read_message(p, send,
704                            surf_index,
705                            msg_control,
706                            msg_type,
707                            BRW_DATAPORT_READ_TARGET_DATA_CACHE,
708                            inst->mlen,
709                            inst->header_present,
710                            rlen);
711 }
712
713 void
714 fs_generator::generate_varying_pull_constant_load_gen7(fs_inst *inst,
715                                                        struct brw_reg dst,
716                                                        struct brw_reg index,
717                                                        struct brw_reg offset)
718 {
719    assert(intel->gen >= 7);
720    /* Varying-offset pull constant loads are treated as a normal expression on
721     * gen7, so the fact that it's a send message is hidden at the IR level.
722     */
723    assert(!inst->header_present);
724    assert(!inst->mlen);
725
726    assert(index.file == BRW_IMMEDIATE_VALUE &&
727           index.type == BRW_REGISTER_TYPE_UD);
728    uint32_t surf_index = index.dw1.ud;
729
730    uint32_t msg_control, rlen, mlen;
731    if (dispatch_width == 16) {
732       msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS;
733       mlen = rlen = 2;
734    } else {
735       msg_control = BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS;
736       mlen = rlen = 1;
737    }
738
739    struct brw_instruction *send = brw_next_insn(p, BRW_OPCODE_SEND);
740    brw_set_dest(p, send, dst);
741    brw_set_src0(p, send, offset);
742    if (intel->gen < 6)
743       send->header.destreg__conditionalmod = inst->base_mrf;
744    brw_set_dp_read_message(p, send,
745                            surf_index,
746                            msg_control,
747                            GEN7_DATAPORT_DC_DWORD_SCATTERED_READ,
748                            BRW_DATAPORT_READ_TARGET_DATA_CACHE,
749                            mlen,
750                            inst->header_present,
751                            rlen);
752 }
753
754 /**
755  * Cause the current pixel/sample mask (from R1.7 bits 15:0) to be transferred
756  * into the flags register (f0.0).
757  *
758  * Used only on Gen6 and above.
759  */
760 void
761 fs_generator::generate_mov_dispatch_to_flags(fs_inst *inst)
762 {
763    struct brw_reg flags = brw_flag_reg(0, inst->flag_subreg);
764    struct brw_reg dispatch_mask;
765
766    if (intel->gen >= 6)
767       dispatch_mask = retype(brw_vec1_grf(1, 7), BRW_REGISTER_TYPE_UW);
768    else
769       dispatch_mask = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
770
771    brw_push_insn_state(p);
772    brw_set_mask_control(p, BRW_MASK_DISABLE);
773    brw_MOV(p, flags, dispatch_mask);
774    brw_pop_insn_state(p);
775 }
776
777
778 static uint32_t brw_file_from_reg(fs_reg *reg)
779 {
780    switch (reg->file) {
781    case ARF:
782       return BRW_ARCHITECTURE_REGISTER_FILE;
783    case GRF:
784       return BRW_GENERAL_REGISTER_FILE;
785    case MRF:
786       return BRW_MESSAGE_REGISTER_FILE;
787    case IMM:
788       return BRW_IMMEDIATE_VALUE;
789    default:
790       assert(!"not reached");
791       return BRW_GENERAL_REGISTER_FILE;
792    }
793 }
794
795 static struct brw_reg
796 brw_reg_from_fs_reg(fs_reg *reg)
797 {
798    struct brw_reg brw_reg;
799
800    switch (reg->file) {
801    case GRF:
802    case ARF:
803    case MRF:
804       if (reg->smear == -1) {
805          brw_reg = brw_vec8_reg(brw_file_from_reg(reg), reg->reg, 0);
806       } else {
807          brw_reg = brw_vec1_reg(brw_file_from_reg(reg), reg->reg, reg->smear);
808       }
809       brw_reg = retype(brw_reg, reg->type);
810       if (reg->sechalf)
811          brw_reg = sechalf(brw_reg);
812       break;
813    case IMM:
814       switch (reg->type) {
815       case BRW_REGISTER_TYPE_F:
816          brw_reg = brw_imm_f(reg->imm.f);
817          break;
818       case BRW_REGISTER_TYPE_D:
819          brw_reg = brw_imm_d(reg->imm.i);
820          break;
821       case BRW_REGISTER_TYPE_UD:
822          brw_reg = brw_imm_ud(reg->imm.u);
823          break;
824       default:
825          assert(!"not reached");
826          brw_reg = brw_null_reg();
827          break;
828       }
829       break;
830    case FIXED_HW_REG:
831       brw_reg = reg->fixed_hw_reg;
832       break;
833    case BAD_FILE:
834       /* Probably unused. */
835       brw_reg = brw_null_reg();
836       break;
837    case UNIFORM:
838       assert(!"not reached");
839       brw_reg = brw_null_reg();
840       break;
841    default:
842       assert(!"not reached");
843       brw_reg = brw_null_reg();
844       break;
845    }
846    if (reg->abs)
847       brw_reg = brw_abs(brw_reg);
848    if (reg->negate)
849       brw_reg = negate(brw_reg);
850
851    return brw_reg;
852 }
853
854 /**
855  * Sets the second dword of a vgrf for gen7+ message setup.
856  *
857  * For setting up gen7 messages in VGRFs, we need to be able to set the second
858  * dword for some payloads where in the MRF world we'd have just used
859  * brw_message_reg().  We don't want to bake it into the send message's code
860  * generation because that means we don't get a chance to schedule the
861  * instructions.
862  */
863 void
864 fs_generator::generate_set_global_offset(fs_inst *inst,
865                                          struct brw_reg dst,
866                                          struct brw_reg src,
867                                          struct brw_reg value)
868 {
869    /* We use a matching src and dst to get the information on how this
870     * instruction works exposed to various optimization passes that would
871     * otherwise treat it as completely overwriting the dst.
872     */
873    assert(src.file == dst.file && src.nr == dst.nr);
874    assert(value.file == BRW_IMMEDIATE_VALUE);
875
876    brw_push_insn_state(p);
877    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
878    brw_set_mask_control(p, BRW_MASK_DISABLE);
879    brw_MOV(p, retype(brw_vec1_reg(dst.file, dst.nr, 2), value.type), value);
880    brw_pop_insn_state(p);
881 }
882
883 /**
884  * Change the register's data type from UD to W, doubling the strides in order
885  * to compensate for halving the data type width.
886  */
887 static struct brw_reg
888 ud_reg_to_w(struct brw_reg r)
889 {
890    assert(r.type == BRW_REGISTER_TYPE_UD);
891    r.type = BRW_REGISTER_TYPE_W;
892
893    /* The BRW_*_STRIDE enums are defined so that incrementing the field
894     * doubles the real stride.
895     */
896    if (r.hstride != 0)
897       ++r.hstride;
898    if (r.vstride != 0)
899       ++r.vstride;
900
901    return r;
902 }
903
904 void
905 fs_generator::generate_pack_half_2x16_split(fs_inst *inst,
906                                             struct brw_reg dst,
907                                             struct brw_reg x,
908                                             struct brw_reg y)
909 {
910    assert(intel->gen >= 7);
911    assert(dst.type == BRW_REGISTER_TYPE_UD);
912    assert(x.type == BRW_REGISTER_TYPE_F);
913    assert(y.type == BRW_REGISTER_TYPE_F);
914
915    /* From the Ivybridge PRM, Vol4, Part3, Section 6.27 f32to16:
916     *
917     *   Because this instruction does not have a 16-bit floating-point type,
918     *   the destination data type must be Word (W).
919     *
920     *   The destination must be DWord-aligned and specify a horizontal stride
921     *   (HorzStride) of 2. The 16-bit result is stored in the lower word of
922     *   each destination channel and the upper word is not modified.
923     */
924    struct brw_reg dst_w = ud_reg_to_w(dst);
925
926    /* Give each 32-bit channel of dst the form below , where "." means
927     * unchanged.
928     *   0x....hhhh
929     */
930    brw_F32TO16(p, dst_w, y);
931
932    /* Now the form:
933     *   0xhhhh0000
934     */
935    brw_SHL(p, dst, dst, brw_imm_ud(16u));
936
937    /* And, finally the form of packHalf2x16's output:
938     *   0xhhhhllll
939     */
940    brw_F32TO16(p, dst_w, x);
941 }
942
943 void
944 fs_generator::generate_unpack_half_2x16_split(fs_inst *inst,
945                                               struct brw_reg dst,
946                                               struct brw_reg src)
947 {
948    assert(intel->gen >= 7);
949    assert(dst.type == BRW_REGISTER_TYPE_F);
950    assert(src.type == BRW_REGISTER_TYPE_UD);
951
952    /* From the Ivybridge PRM, Vol4, Part3, Section 6.26 f16to32:
953     *
954     *   Because this instruction does not have a 16-bit floating-point type,
955     *   the source data type must be Word (W). The destination type must be
956     *   F (Float).
957     */
958    struct brw_reg src_w = ud_reg_to_w(src);
959
960    /* Each channel of src has the form of unpackHalf2x16's input: 0xhhhhllll.
961     * For the Y case, we wish to access only the upper word; therefore
962     * a 16-bit subregister offset is needed.
963     */
964    assert(inst->opcode == FS_OPCODE_UNPACK_HALF_2x16_SPLIT_X ||
965           inst->opcode == FS_OPCODE_UNPACK_HALF_2x16_SPLIT_Y);
966    if (inst->opcode == FS_OPCODE_UNPACK_HALF_2x16_SPLIT_Y)
967       src_w.subnr += 2;
968
969    brw_F16TO32(p, dst, src_w);
970 }
971
972 void
973 fs_generator::generate_code(exec_list *instructions)
974 {
975    int last_native_insn_offset = p->next_insn_offset;
976    const char *last_annotation_string = NULL;
977    const void *last_annotation_ir = NULL;
978
979    if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
980       if (shader) {
981          printf("Native code for fragment shader %d (%d-wide dispatch):\n",
982                 prog->Name, dispatch_width);
983       } else {
984          printf("Native code for fragment program %d (%d-wide dispatch):\n",
985                 fp->Base.Id, dispatch_width);
986       }
987    }
988
989    cfg_t *cfg = NULL;
990    if (unlikely(INTEL_DEBUG & DEBUG_WM))
991       cfg = new(mem_ctx) cfg_t(mem_ctx, instructions);
992
993    foreach_list(node, instructions) {
994       fs_inst *inst = (fs_inst *)node;
995       struct brw_reg src[3], dst;
996
997       if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
998          foreach_list(node, &cfg->block_list) {
999             bblock_link *link = (bblock_link *)node;
1000             bblock_t *block = link->block;
1001
1002             if (block->start == inst) {
1003                printf("   START B%d", block->block_num);
1004                foreach_list(predecessor_node, &block->parents) {
1005                   bblock_link *predecessor_link =
1006                      (bblock_link *)predecessor_node;
1007                   bblock_t *predecessor_block = predecessor_link->block;
1008                   printf(" <-B%d", predecessor_block->block_num);
1009                }
1010                printf("\n");
1011             }
1012          }
1013
1014          if (last_annotation_ir != inst->ir) {
1015             last_annotation_ir = inst->ir;
1016             if (last_annotation_ir) {
1017                printf("   ");
1018                if (shader)
1019                   ((ir_instruction *)inst->ir)->print();
1020                else {
1021                   const prog_instruction *fpi;
1022                   fpi = (const prog_instruction *)inst->ir;
1023                   printf("%d: ", (int)(fpi - fp->Base.Instructions));
1024                   _mesa_fprint_instruction_opt(stdout,
1025                                                fpi,
1026                                                0, PROG_PRINT_DEBUG, NULL);
1027                }
1028                printf("\n");
1029             }
1030          }
1031          if (last_annotation_string != inst->annotation) {
1032             last_annotation_string = inst->annotation;
1033             if (last_annotation_string)
1034                printf("   %s\n", last_annotation_string);
1035          }
1036       }
1037
1038       for (unsigned int i = 0; i < 3; i++) {
1039          src[i] = brw_reg_from_fs_reg(&inst->src[i]);
1040
1041          /* The accumulator result appears to get used for the
1042           * conditional modifier generation.  When negating a UD
1043           * value, there is a 33rd bit generated for the sign in the
1044           * accumulator value, so now you can't check, for example,
1045           * equality with a 32-bit value.  See piglit fs-op-neg-uvec4.
1046           */
1047          assert(!inst->conditional_mod ||
1048                 inst->src[i].type != BRW_REGISTER_TYPE_UD ||
1049                 !inst->src[i].negate);
1050       }
1051       dst = brw_reg_from_fs_reg(&inst->dst);
1052
1053       brw_set_conditionalmod(p, inst->conditional_mod);
1054       brw_set_predicate_control(p, inst->predicate);
1055       brw_set_predicate_inverse(p, inst->predicate_inverse);
1056       brw_set_flag_reg(p, 0, inst->flag_subreg);
1057       brw_set_saturate(p, inst->saturate);
1058       brw_set_mask_control(p, inst->force_writemask_all);
1059
1060       if (inst->force_uncompressed || dispatch_width == 8) {
1061          brw_set_compression_control(p, BRW_COMPRESSION_NONE);
1062       } else if (inst->force_sechalf) {
1063          brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
1064       } else {
1065          brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
1066       }
1067
1068       switch (inst->opcode) {
1069       case BRW_OPCODE_MOV:
1070          brw_MOV(p, dst, src[0]);
1071          break;
1072       case BRW_OPCODE_ADD:
1073          brw_ADD(p, dst, src[0], src[1]);
1074          break;
1075       case BRW_OPCODE_MUL:
1076          brw_MUL(p, dst, src[0], src[1]);
1077          break;
1078       case BRW_OPCODE_MACH:
1079          brw_set_acc_write_control(p, 1);
1080          brw_MACH(p, dst, src[0], src[1]);
1081          brw_set_acc_write_control(p, 0);
1082          break;
1083
1084       case BRW_OPCODE_MAD:
1085          brw_set_access_mode(p, BRW_ALIGN_16);
1086          if (dispatch_width == 16) {
1087             brw_set_compression_control(p, BRW_COMPRESSION_NONE);
1088             brw_MAD(p, dst, src[0], src[1], src[2]);
1089             brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
1090             brw_MAD(p, sechalf(dst), sechalf(src[0]), sechalf(src[1]), sechalf(src[2]));
1091             brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
1092          } else {
1093             brw_MAD(p, dst, src[0], src[1], src[2]);
1094          }
1095          brw_set_access_mode(p, BRW_ALIGN_1);
1096          break;
1097
1098       case BRW_OPCODE_LRP:
1099          brw_set_access_mode(p, BRW_ALIGN_16);
1100          if (dispatch_width == 16) {
1101             brw_set_compression_control(p, BRW_COMPRESSION_NONE);
1102             brw_LRP(p, dst, src[0], src[1], src[2]);
1103             brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
1104             brw_LRP(p, sechalf(dst), sechalf(src[0]), sechalf(src[1]), sechalf(src[2]));
1105             brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
1106          } else {
1107             brw_LRP(p, dst, src[0], src[1], src[2]);
1108          }
1109          brw_set_access_mode(p, BRW_ALIGN_1);
1110          break;
1111
1112       case BRW_OPCODE_FRC:
1113          brw_FRC(p, dst, src[0]);
1114          break;
1115       case BRW_OPCODE_RNDD:
1116          brw_RNDD(p, dst, src[0]);
1117          break;
1118       case BRW_OPCODE_RNDE:
1119          brw_RNDE(p, dst, src[0]);
1120          break;
1121       case BRW_OPCODE_RNDZ:
1122          brw_RNDZ(p, dst, src[0]);
1123          break;
1124
1125       case BRW_OPCODE_AND:
1126          brw_AND(p, dst, src[0], src[1]);
1127          break;
1128       case BRW_OPCODE_OR:
1129          brw_OR(p, dst, src[0], src[1]);
1130          break;
1131       case BRW_OPCODE_XOR:
1132          brw_XOR(p, dst, src[0], src[1]);
1133          break;
1134       case BRW_OPCODE_NOT:
1135          brw_NOT(p, dst, src[0]);
1136          break;
1137       case BRW_OPCODE_ASR:
1138          brw_ASR(p, dst, src[0], src[1]);
1139          break;
1140       case BRW_OPCODE_SHR:
1141          brw_SHR(p, dst, src[0], src[1]);
1142          break;
1143       case BRW_OPCODE_SHL:
1144          brw_SHL(p, dst, src[0], src[1]);
1145          break;
1146       case BRW_OPCODE_F32TO16:
1147          brw_F32TO16(p, dst, src[0]);
1148          break;
1149       case BRW_OPCODE_F16TO32:
1150          brw_F16TO32(p, dst, src[0]);
1151          break;
1152       case BRW_OPCODE_CMP:
1153          brw_CMP(p, dst, inst->conditional_mod, src[0], src[1]);
1154          break;
1155       case BRW_OPCODE_SEL:
1156          brw_SEL(p, dst, src[0], src[1]);
1157          break;
1158
1159       case BRW_OPCODE_IF:
1160          if (inst->src[0].file != BAD_FILE) {
1161             /* The instruction has an embedded compare (only allowed on gen6) */
1162             assert(intel->gen == 6);
1163             gen6_IF(p, inst->conditional_mod, src[0], src[1]);
1164          } else {
1165             brw_IF(p, dispatch_width == 16 ? BRW_EXECUTE_16 : BRW_EXECUTE_8);
1166          }
1167          break;
1168
1169       case BRW_OPCODE_ELSE:
1170          brw_ELSE(p);
1171          break;
1172       case BRW_OPCODE_ENDIF:
1173          brw_ENDIF(p);
1174          break;
1175
1176       case BRW_OPCODE_DO:
1177          brw_DO(p, BRW_EXECUTE_8);
1178          break;
1179
1180       case BRW_OPCODE_BREAK:
1181          brw_BREAK(p);
1182          brw_set_predicate_control(p, BRW_PREDICATE_NONE);
1183          break;
1184       case BRW_OPCODE_CONTINUE:
1185          /* FINISHME: We need to write the loop instruction support still. */
1186          if (intel->gen >= 6)
1187             gen6_CONT(p);
1188          else
1189             brw_CONT(p);
1190          brw_set_predicate_control(p, BRW_PREDICATE_NONE);
1191          break;
1192
1193       case BRW_OPCODE_WHILE:
1194          brw_WHILE(p);
1195          break;
1196
1197       case SHADER_OPCODE_RCP:
1198       case SHADER_OPCODE_RSQ:
1199       case SHADER_OPCODE_SQRT:
1200       case SHADER_OPCODE_EXP2:
1201       case SHADER_OPCODE_LOG2:
1202       case SHADER_OPCODE_SIN:
1203       case SHADER_OPCODE_COS:
1204          if (intel->gen >= 7) {
1205             generate_math1_gen7(inst, dst, src[0]);
1206          } else if (intel->gen == 6) {
1207             generate_math1_gen6(inst, dst, src[0]);
1208          } else {
1209             generate_math_gen4(inst, dst, src[0]);
1210          }
1211          break;
1212       case SHADER_OPCODE_INT_QUOTIENT:
1213       case SHADER_OPCODE_INT_REMAINDER:
1214       case SHADER_OPCODE_POW:
1215          if (intel->gen >= 7) {
1216             generate_math2_gen7(inst, dst, src[0], src[1]);
1217          } else if (intel->gen == 6) {
1218             generate_math2_gen6(inst, dst, src[0], src[1]);
1219          } else {
1220             generate_math_gen4(inst, dst, src[0]);
1221          }
1222          break;
1223       case FS_OPCODE_PIXEL_X:
1224          generate_pixel_xy(dst, true);
1225          break;
1226       case FS_OPCODE_PIXEL_Y:
1227          generate_pixel_xy(dst, false);
1228          break;
1229       case FS_OPCODE_CINTERP:
1230          brw_MOV(p, dst, src[0]);
1231          break;
1232       case FS_OPCODE_LINTERP:
1233          generate_linterp(inst, dst, src);
1234          break;
1235       case SHADER_OPCODE_TEX:
1236       case FS_OPCODE_TXB:
1237       case SHADER_OPCODE_TXD:
1238       case SHADER_OPCODE_TXF:
1239       case SHADER_OPCODE_TXL:
1240       case SHADER_OPCODE_TXS:
1241          generate_tex(inst, dst, src[0]);
1242          break;
1243       case FS_OPCODE_DDX:
1244          generate_ddx(inst, dst, src[0]);
1245          break;
1246       case FS_OPCODE_DDY:
1247          /* Make sure fp->UsesDFdy flag got set (otherwise there's no
1248           * guarantee that c->key.render_to_fbo is set).
1249           */
1250          assert(fp->UsesDFdy);
1251          generate_ddy(inst, dst, src[0], c->key.render_to_fbo);
1252          break;
1253
1254       case FS_OPCODE_SPILL:
1255          generate_spill(inst, src[0]);
1256          break;
1257
1258       case FS_OPCODE_UNSPILL:
1259          generate_unspill(inst, dst);
1260          break;
1261
1262       case FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD:
1263          generate_uniform_pull_constant_load(inst, dst, src[0], src[1]);
1264          break;
1265
1266       case FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD_GEN7:
1267          generate_uniform_pull_constant_load_gen7(inst, dst, src[0], src[1]);
1268          break;
1269
1270       case FS_OPCODE_VARYING_PULL_CONSTANT_LOAD:
1271          generate_varying_pull_constant_load(inst, dst, src[0]);
1272          break;
1273
1274       case FS_OPCODE_VARYING_PULL_CONSTANT_LOAD_GEN7:
1275          generate_varying_pull_constant_load_gen7(inst, dst, src[0], src[1]);
1276          break;
1277
1278       case FS_OPCODE_FB_WRITE:
1279          generate_fb_write(inst);
1280          break;
1281
1282       case FS_OPCODE_MOV_DISPATCH_TO_FLAGS:
1283          generate_mov_dispatch_to_flags(inst);
1284          break;
1285
1286       case FS_OPCODE_DISCARD_JUMP:
1287          generate_discard_jump(inst);
1288          break;
1289
1290       case SHADER_OPCODE_SHADER_TIME_ADD:
1291          brw_shader_time_add(p, inst->base_mrf, SURF_INDEX_WM_SHADER_TIME);
1292          break;
1293
1294       case FS_OPCODE_SET_GLOBAL_OFFSET:
1295          generate_set_global_offset(inst, dst, src[0], src[1]);
1296          break;
1297
1298       case FS_OPCODE_PACK_HALF_2x16_SPLIT:
1299           generate_pack_half_2x16_split(inst, dst, src[0], src[1]);
1300           break;
1301
1302       case FS_OPCODE_UNPACK_HALF_2x16_SPLIT_X:
1303       case FS_OPCODE_UNPACK_HALF_2x16_SPLIT_Y:
1304          generate_unpack_half_2x16_split(inst, dst, src[0]);
1305          break;
1306
1307       default:
1308          if (inst->opcode < (int) ARRAY_SIZE(opcode_descs)) {
1309             _mesa_problem(ctx, "Unsupported opcode `%s' in FS",
1310                           opcode_descs[inst->opcode].name);
1311          } else {
1312             _mesa_problem(ctx, "Unsupported opcode %d in FS", inst->opcode);
1313          }
1314          abort();
1315       }
1316
1317       if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
1318          brw_dump_compile(p, stdout,
1319                           last_native_insn_offset, p->next_insn_offset);
1320
1321          foreach_list(node, &cfg->block_list) {
1322             bblock_link *link = (bblock_link *)node;
1323             bblock_t *block = link->block;
1324
1325             if (block->end == inst) {
1326                printf("   END B%d", block->block_num);
1327                foreach_list(successor_node, &block->children) {
1328                   bblock_link *successor_link =
1329                      (bblock_link *)successor_node;
1330                   bblock_t *successor_block = successor_link->block;
1331                   printf(" ->B%d", successor_block->block_num);
1332                }
1333                printf("\n");
1334             }
1335          }
1336       }
1337
1338       last_native_insn_offset = p->next_insn_offset;
1339    }
1340
1341    if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
1342       printf("\n");
1343    }
1344
1345    brw_set_uip_jip(p);
1346
1347    /* OK, while the INTEL_DEBUG=wm above is very nice for debugging FS
1348     * emit issues, it doesn't get the jump distances into the output,
1349     * which is often something we want to debug.  So this is here in
1350     * case you're doing that.
1351     */
1352    if (0) {
1353       brw_dump_compile(p, stdout, 0, p->next_insn_offset);
1354    }
1355 }
1356
1357 const unsigned *
1358 fs_generator::generate_assembly(exec_list *simd8_instructions,
1359                                 exec_list *simd16_instructions,
1360                                 unsigned *assembly_size)
1361 {
1362    dispatch_width = 8;
1363    generate_code(simd8_instructions);
1364
1365    if (simd16_instructions) {
1366       /* We have to do a compaction pass now, or the one at the end of
1367        * execution will squash down where our prog_offset start needs
1368        * to be.
1369        */
1370       brw_compact_instructions(p);
1371
1372       /* align to 64 byte boundary. */
1373       while ((p->nr_insn * sizeof(struct brw_instruction)) % 64) {
1374          brw_NOP(p);
1375       }
1376
1377       /* Save off the start of this 16-wide program */
1378       c->prog_data.prog_offset_16 = p->nr_insn * sizeof(struct brw_instruction);
1379
1380       brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
1381
1382       dispatch_width = 16;
1383       generate_code(simd16_instructions);
1384    }
1385
1386    return brw_get_program(p, assembly_size);
1387 }