~ubuntu-branches/ubuntu/precise/mesa/precise-updates

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/i965/brw_fs_visitor.cpp

  • Committer: Package Import Robot
  • Author(s): Robert Hooker
  • Date: 2012-02-02 12:05:48 UTC
  • mfrom: (1.7.1) (3.3.27 sid)
  • Revision ID: package-import@ubuntu.com-20120202120548-nvkma85jq0h4coix
Tags: 8.0~rc2-0ubuntu4
Drop drisearchdir handling, it is no longer needed with multiarch
and dri-alternates being removed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
}
47
47
#include "brw_shader.h"
48
48
#include "brw_fs.h"
49
 
#include "../glsl/glsl_types.h"
50
 
#include "../glsl/ir_optimization.h"
51
 
#include "../glsl/ir_print_visitor.h"
 
49
#include "glsl/glsl_types.h"
 
50
#include "glsl/ir_optimization.h"
 
51
#include "glsl/ir_print_visitor.h"
52
52
 
53
53
void
54
54
fs_visitor::visit(ir_variable *ir)
58
58
   if (variable_storage(ir))
59
59
      return;
60
60
 
61
 
   if (strcmp(ir->name, "gl_FragColor") == 0) {
62
 
      this->frag_color = ir;
63
 
   } else if (strcmp(ir->name, "gl_FragData") == 0) {
64
 
      this->frag_data = ir;
65
 
   } else if (strcmp(ir->name, "gl_FragDepth") == 0) {
66
 
      this->frag_depth = ir;
67
 
   }
68
 
 
69
61
   if (ir->mode == ir_var_in) {
70
62
      if (!strcmp(ir->name, "gl_FragCoord")) {
71
63
         reg = emit_fragcoord_interpolation(ir);
77
69
      assert(reg);
78
70
      hash_table_insert(this->variable_ht, reg, ir);
79
71
      return;
80
 
   }
81
 
 
82
 
   if (ir->mode == ir_var_uniform) {
 
72
   } else if (ir->mode == ir_var_out) {
 
73
      reg = new(this->mem_ctx) fs_reg(this, ir->type);
 
74
 
 
75
      if (ir->location == FRAG_RESULT_COLOR) {
 
76
         /* Writing gl_FragColor outputs to all color regions. */
 
77
         for (int i = 0; i < MAX2(c->key.nr_color_regions, 1); i++) {
 
78
            this->outputs[i] = *reg;
 
79
         }
 
80
      } else if (ir->location == FRAG_RESULT_DEPTH) {
 
81
         this->frag_depth = ir;
 
82
      } else {
 
83
         /* gl_FragData or a user-defined FS output */
 
84
         assert(ir->location >= FRAG_RESULT_DATA0 &&
 
85
                ir->location < FRAG_RESULT_DATA0 + BRW_MAX_DRAW_BUFFERS);
 
86
 
 
87
         /* General color output. */
 
88
         for (unsigned int i = 0; i < MAX2(1, ir->type->length); i++) {
 
89
            int output = ir->location - FRAG_RESULT_DATA0 + i;
 
90
            this->outputs[output] = *reg;
 
91
            this->outputs[output].reg_offset += 4 * i;
 
92
         }
 
93
      }
 
94
   } else if (ir->mode == ir_var_uniform) {
83
95
      int param_index = c->prog_data.nr_params;
84
96
 
85
97
      if (c->dispatch_width == 16) {
142
154
   this->result.type = brw_type_for_base_type(ir->type);
143
155
 
144
156
   if (index) {
145
 
      assert(this->result.file == UNIFORM ||
146
 
             (this->result.file == GRF &&
147
 
              this->result.reg != 0));
 
157
      assert(this->result.file == UNIFORM || this->result.file == GRF);
148
158
      this->result.reg_offset += index->value.i[0] * element_size;
149
159
   } else {
150
160
      assert(!"FINISHME: non-constant array element");
162
172
   if (!sat_val)
163
173
      return false;
164
174
 
165
 
   this->result = reg_undef;
166
175
   sat_val->accept(this);
167
176
   fs_reg src = this->result;
168
177
 
185
194
   if (try_emit_saturate(ir))
186
195
      return;
187
196
 
188
 
   /* This is where our caller would like us to put the result, if possible. */
189
 
   fs_reg saved_result_storage = this->result;
190
 
 
191
197
   for (operand = 0; operand < ir->get_num_operands(); operand++) {
192
 
      this->result = reg_undef;
193
198
      ir->operands[operand]->accept(this);
194
199
      if (this->result.file == BAD_FILE) {
195
200
         ir_print_visitor v;
207
212
      assert(!ir->operands[operand]->type->is_vector());
208
213
   }
209
214
 
210
 
   /* Inherit storage from our parent if possible, and otherwise we
211
 
    * alloc a temporary.
 
215
   /* Storage for our result.  If our result goes into an assignment, it will
 
216
    * just get copy-propagated out, so no worries.
212
217
    */
213
 
   if (saved_result_storage.file == BAD_FILE) {
214
 
      this->result = fs_reg(this, ir->type);
215
 
   } else {
216
 
      this->result = saved_result_storage;
217
 
   }
 
218
   this->result = fs_reg(this, ir->type);
218
219
 
219
220
   switch (ir->operation) {
220
221
   case ir_unop_logic_not:
235
236
   case ir_unop_sign:
236
237
      temp = fs_reg(this, ir->type);
237
238
 
238
 
      /* Unalias the destination.  (imagine a = sign(a)) */
239
 
      this->result = fs_reg(this, ir->type);
240
 
 
241
239
      emit(BRW_OPCODE_MOV, this->result, fs_reg(0.0f));
242
240
 
243
241
      inst = emit(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f));
252
250
 
253
251
      break;
254
252
   case ir_unop_rcp:
255
 
      emit_math(FS_OPCODE_RCP, this->result, op[0]);
 
253
      emit_math(SHADER_OPCODE_RCP, this->result, op[0]);
256
254
      break;
257
255
 
258
256
   case ir_unop_exp2:
259
 
      emit_math(FS_OPCODE_EXP2, this->result, op[0]);
 
257
      emit_math(SHADER_OPCODE_EXP2, this->result, op[0]);
260
258
      break;
261
259
   case ir_unop_log2:
262
 
      emit_math(FS_OPCODE_LOG2, this->result, op[0]);
 
260
      emit_math(SHADER_OPCODE_LOG2, this->result, op[0]);
263
261
      break;
264
262
   case ir_unop_exp:
265
263
   case ir_unop_log:
267
265
      break;
268
266
   case ir_unop_sin:
269
267
   case ir_unop_sin_reduced:
270
 
      emit_math(FS_OPCODE_SIN, this->result, op[0]);
 
268
      emit_math(SHADER_OPCODE_SIN, this->result, op[0]);
271
269
      break;
272
270
   case ir_unop_cos:
273
271
   case ir_unop_cos_reduced:
274
 
      emit_math(FS_OPCODE_COS, this->result, op[0]);
 
272
      emit_math(SHADER_OPCODE_COS, this->result, op[0]);
275
273
      break;
276
274
 
277
275
   case ir_unop_dFdx:
289
287
      break;
290
288
 
291
289
   case ir_binop_mul:
292
 
      emit(BRW_OPCODE_MUL, this->result, op[0], op[1]);
 
290
      if (ir->type->is_integer()) {
 
291
         /* For integer multiplication, the MUL uses the low 16 bits
 
292
          * of one of the operands (src0 on gen6, src1 on gen7).  The
 
293
          * MACH accumulates in the contribution of the upper 16 bits
 
294
          * of that operand.
 
295
          *
 
296
          * FINISHME: Emit just the MUL if we know an operand is small
 
297
          * enough.
 
298
          */
 
299
         struct brw_reg acc = retype(brw_acc_reg(), BRW_REGISTER_TYPE_D);
 
300
 
 
301
         emit(BRW_OPCODE_MUL, acc, op[0], op[1]);
 
302
         emit(BRW_OPCODE_MACH, reg_null_d, op[0], op[1]);
 
303
         emit(BRW_OPCODE_MOV, this->result, fs_reg(acc));
 
304
      } else {
 
305
         emit(BRW_OPCODE_MUL, this->result, op[0], op[1]);
 
306
      }
293
307
      break;
294
308
   case ir_binop_div:
295
 
      assert(!"not reached: should be handled by ir_div_to_mul_rcp");
 
309
      if (intel->gen >= 7 && c->dispatch_width == 16)
 
310
         fail("16-wide INTDIV unsupported\n");
 
311
 
 
312
      /* Floating point should be lowered by DIV_TO_MUL_RCP in the compiler. */
 
313
      assert(ir->type->is_integer());
 
314
      emit_math(SHADER_OPCODE_INT_QUOTIENT, this->result, op[0], op[1]);
296
315
      break;
297
316
   case ir_binop_mod:
298
 
      assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
 
317
      if (intel->gen >= 7 && c->dispatch_width == 16)
 
318
         fail("16-wide INTDIV unsupported\n");
 
319
 
 
320
      /* Floating point should be lowered by MOD_TO_FRACT in the compiler. */
 
321
      assert(ir->type->is_integer());
 
322
      emit_math(SHADER_OPCODE_INT_REMAINDER, this->result, op[0], op[1]);
299
323
      break;
300
324
 
301
325
   case ir_binop_less:
311
335
      if (intel->gen < 5)
312
336
         temp.type = op[0].type;
313
337
 
 
338
      resolve_ud_negate(&op[0]);
 
339
      resolve_ud_negate(&op[1]);
 
340
 
314
341
      inst = emit(BRW_OPCODE_CMP, temp, op[0], op[1]);
315
342
      inst->conditional_mod = brw_conditional_for_comparison(ir->operation);
316
343
      emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(0x1));
342
369
      break;
343
370
 
344
371
   case ir_unop_sqrt:
345
 
      emit_math(FS_OPCODE_SQRT, this->result, op[0]);
 
372
      emit_math(SHADER_OPCODE_SQRT, this->result, op[0]);
346
373
      break;
347
374
 
348
375
   case ir_unop_rsq:
349
 
      emit_math(FS_OPCODE_RSQ, this->result, op[0]);
 
376
      emit_math(SHADER_OPCODE_RSQ, this->result, op[0]);
350
377
      break;
351
378
 
 
379
   case ir_unop_i2u:
 
380
      op[0].type = BRW_REGISTER_TYPE_UD;
 
381
      this->result = op[0];
 
382
      break;
 
383
   case ir_unop_u2i:
 
384
      op[0].type = BRW_REGISTER_TYPE_D;
 
385
      this->result = op[0];
 
386
      break;
352
387
   case ir_unop_i2f:
 
388
   case ir_unop_u2f:
353
389
   case ir_unop_b2f:
354
390
   case ir_unop_b2i:
355
391
   case ir_unop_f2i:
362
398
      if (intel->gen < 5)
363
399
         temp.type = op[0].type;
364
400
 
 
401
      resolve_ud_negate(&op[0]);
 
402
 
365
403
      inst = emit(BRW_OPCODE_CMP, temp, op[0], fs_reg(0.0f));
366
404
      inst->conditional_mod = BRW_CONDITIONAL_NZ;
367
405
      inst = emit(BRW_OPCODE_AND, this->result, this->result, fs_reg(1));
386
424
      break;
387
425
 
388
426
   case ir_binop_min:
 
427
      resolve_ud_negate(&op[0]);
 
428
      resolve_ud_negate(&op[1]);
 
429
 
389
430
      if (intel->gen >= 6) {
390
431
         inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
391
432
         inst->conditional_mod = BRW_CONDITIONAL_L;
401
442
      }
402
443
      break;
403
444
   case ir_binop_max:
 
445
      resolve_ud_negate(&op[0]);
 
446
      resolve_ud_negate(&op[1]);
 
447
 
404
448
      if (intel->gen >= 6) {
405
449
         inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
406
450
         inst->conditional_mod = BRW_CONDITIONAL_GE;
417
461
      break;
418
462
 
419
463
   case ir_binop_pow:
420
 
      emit_math(FS_OPCODE_POW, this->result, op[0], op[1]);
 
464
      emit_math(SHADER_OPCODE_POW, this->result, op[0], op[1]);
421
465
      break;
422
466
 
423
467
   case ir_unop_bit_not:
433
477
      inst = emit(BRW_OPCODE_OR, this->result, op[0], op[1]);
434
478
      break;
435
479
 
436
 
   case ir_unop_u2f:
437
480
   case ir_binop_lshift:
 
481
      inst = emit(BRW_OPCODE_SHL, this->result, op[0], op[1]);
 
482
      break;
 
483
 
438
484
   case ir_binop_rshift:
439
 
      assert(!"GLSL 1.30 features unsupported");
 
485
      if (ir->type->base_type == GLSL_TYPE_INT)
 
486
         inst = emit(BRW_OPCODE_ASR, this->result, op[0], op[1]);
 
487
      else
 
488
         inst = emit(BRW_OPCODE_SHR, this->result, op[0], op[1]);
440
489
      break;
441
490
   }
442
491
}
485
534
   }
486
535
}
487
536
 
 
537
/* If the RHS processing resulted in an instruction generating a
 
538
 * temporary value, and it would be easy to rewrite the instruction to
 
539
 * generate its result right into the LHS instead, do so.  This ends
 
540
 * up reliably removing instructions where it can be tricky to do so
 
541
 * later without real UD chain information.
 
542
 */
 
543
bool
 
544
fs_visitor::try_rewrite_rhs_to_dst(ir_assignment *ir,
 
545
                                   fs_reg dst,
 
546
                                   fs_reg src,
 
547
                                   fs_inst *pre_rhs_inst,
 
548
                                   fs_inst *last_rhs_inst)
 
549
{
 
550
   if (pre_rhs_inst == last_rhs_inst)
 
551
      return false; /* No instructions generated to work with. */
 
552
 
 
553
   /* Only attempt if we're doing a direct assignment. */
 
554
   if (ir->condition ||
 
555
       !(ir->lhs->type->is_scalar() ||
 
556
        (ir->lhs->type->is_vector() &&
 
557
         ir->write_mask == (1 << ir->lhs->type->vector_elements) - 1)))
 
558
      return false;
 
559
 
 
560
   /* Make sure the last instruction generated our source reg. */
 
561
   if (last_rhs_inst->predicated ||
 
562
       last_rhs_inst->force_uncompressed ||
 
563
       last_rhs_inst->force_sechalf ||
 
564
       !src.equals(&last_rhs_inst->dst))
 
565
      return false;
 
566
 
 
567
   /* Success!  Rewrite the instruction. */
 
568
   last_rhs_inst->dst = dst;
 
569
 
 
570
   return true;
 
571
}
 
572
 
488
573
void
489
574
fs_visitor::visit(ir_assignment *ir)
490
575
{
491
 
   struct fs_reg l, r;
 
576
   fs_reg l, r;
492
577
   fs_inst *inst;
493
578
 
494
579
   /* FINISHME: arrays on the lhs */
495
 
   this->result = reg_undef;
496
580
   ir->lhs->accept(this);
497
581
   l = this->result;
498
582
 
499
 
   /* If we're doing a direct assignment, an RHS expression could
500
 
    * drop its result right into our destination.  Otherwise, tell it
501
 
    * not to.
502
 
    */
503
 
   if (ir->condition ||
504
 
       !(ir->lhs->type->is_scalar() ||
505
 
         (ir->lhs->type->is_vector() &&
506
 
          ir->write_mask == (1 << ir->lhs->type->vector_elements) - 1))) {
507
 
      this->result = reg_undef;
508
 
   }
 
583
   fs_inst *pre_rhs_inst = (fs_inst *) this->instructions.get_tail();
509
584
 
510
585
   ir->rhs->accept(this);
511
586
   r = this->result;
512
587
 
 
588
   fs_inst *last_rhs_inst = (fs_inst *) this->instructions.get_tail();
 
589
 
513
590
   assert(l.file != BAD_FILE);
514
591
   assert(r.file != BAD_FILE);
515
592
 
 
593
   if (try_rewrite_rhs_to_dst(ir, l, r, pre_rhs_inst, last_rhs_inst))
 
594
      return;
 
595
 
516
596
   if (ir->condition) {
517
597
      emit_bool_to_cond_code(ir->condition);
518
598
   }
521
601
       ir->lhs->type->is_vector()) {
522
602
      for (int i = 0; i < ir->lhs->type->vector_elements; i++) {
523
603
         if (ir->write_mask & (1 << i)) {
524
 
            if (ir->condition) {
525
 
               inst = emit(BRW_OPCODE_MOV, l, r);
 
604
            inst = emit(BRW_OPCODE_MOV, l, r);
 
605
            if (ir->condition)
526
606
               inst->predicated = true;
527
 
            } else if (!l.equals(&r)) {
528
 
               inst = emit(BRW_OPCODE_MOV, l, r);
529
 
            }
530
 
 
531
607
            r.reg_offset++;
532
608
         }
533
609
         l.reg_offset++;
553
629
      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
554
630
         fs_inst *inst = emit(BRW_OPCODE_MOV,
555
631
                              fs_reg(MRF, base_mrf + mlen + i), coordinate);
556
 
         if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
 
632
         if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler))
557
633
            inst->saturate = true;
558
634
 
559
635
         coordinate.reg_offset++;
568
644
         emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), fs_reg(0.0f));
569
645
         mlen++;
570
646
      } else if (ir->op == ir_txb) {
571
 
         this->result = reg_undef;
572
647
         ir->lod_info.bias->accept(this);
573
648
         emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
574
649
         mlen++;
575
650
      } else {
576
651
         assert(ir->op == ir_txl);
577
 
         this->result = reg_undef;
578
652
         ir->lod_info.lod->accept(this);
579
653
         emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
580
654
         mlen++;
581
655
      }
582
656
 
583
 
      this->result = reg_undef;
584
657
      ir->shadow_comparitor->accept(this);
585
658
      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
586
659
      mlen++;
588
661
      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
589
662
         fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i),
590
663
                              coordinate);
591
 
         if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
 
664
         if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler))
592
665
            inst->saturate = true;
593
666
         coordinate.reg_offset++;
594
667
      }
595
668
      /* gen4's SIMD8 sampler always has the slots for u,v,r present. */
596
669
      mlen += 3;
597
670
   } else if (ir->op == ir_txd) {
598
 
      this->result = reg_undef;
599
671
      ir->lod_info.grad.dPdx->accept(this);
600
672
      fs_reg dPdx = this->result;
601
673
 
602
 
      this->result = reg_undef;
603
674
      ir->lod_info.grad.dPdy->accept(this);
604
675
      fs_reg dPdy = this->result;
605
676
 
635
706
         dPdy.reg_offset++;
636
707
      }
637
708
      mlen += MAX2(ir->lod_info.grad.dPdy->type->vector_elements, 2);
 
709
   } else if (ir->op == ir_txs) {
 
710
      /* There's no SIMD8 resinfo message on Gen4.  Use SIMD16 instead. */
 
711
      simd16 = true;
 
712
      ir->lod_info.lod->accept(this);
 
713
      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result);
 
714
      mlen += 2;
638
715
   } else {
639
716
      /* Oh joy.  gen4 doesn't have SIMD8 non-shadow-compare bias/lod
640
717
       * instructions.  We'll need to do SIMD16 here.
641
718
       */
642
 
      assert(ir->op == ir_txb || ir->op == ir_txl);
 
719
      simd16 = true;
 
720
      assert(ir->op == ir_txb || ir->op == ir_txl || ir->op == ir_txf);
643
721
 
644
722
      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
645
723
         fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF,
646
 
                                                     base_mrf + mlen + i * 2),
 
724
                                                     base_mrf + mlen + i * 2,
 
725
                                                     coordinate.type),
647
726
                              coordinate);
648
 
         if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
 
727
         if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler))
649
728
            inst->saturate = true;
650
729
         coordinate.reg_offset++;
651
730
      }
652
731
 
 
732
      /* Initialize the rest of u/v/r with 0.0.  Empirically, this seems to
 
733
       * be necessary for TXF (ld), but seems wise to do for all messages.
 
734
       */
 
735
      for (int i = ir->coordinate->type->vector_elements; i < 3; i++) {
 
736
         emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i * 2), fs_reg(0.0f));
 
737
      }
 
738
 
653
739
      /* lod/bias appears after u/v/r. */
654
740
      mlen += 6;
655
741
 
656
742
      if (ir->op == ir_txb) {
657
 
         this->result = reg_undef;
658
743
         ir->lod_info.bias->accept(this);
659
744
         emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
660
745
         mlen++;
661
746
      } else {
662
 
         this->result = reg_undef;
663
747
         ir->lod_info.lod->accept(this);
664
 
         emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
 
748
         emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, this->result.type),
 
749
                              this->result);
665
750
         mlen++;
666
751
      }
667
752
 
668
753
      /* The unused upper half. */
669
754
      mlen++;
 
755
   }
670
756
 
 
757
   if (simd16) {
671
758
      /* Now, since we're doing simd16, the return is 2 interleaved
672
759
       * vec4s where the odd-indexed ones are junk. We'll need to move
673
760
       * this weirdness around to the expected layout.
674
761
       */
675
 
      simd16 = true;
676
762
      orig_dst = dst;
677
 
      dst = fs_reg(this, glsl_type::get_array_instance(glsl_type::vec4_type,
678
 
                                                       2));
679
 
      dst.type = BRW_REGISTER_TYPE_F;
 
763
      const glsl_type *vec_type =
 
764
         glsl_type::get_instance(ir->type->base_type, 4, 1);
 
765
      dst = fs_reg(this, glsl_type::get_array_instance(vec_type, 2));
 
766
      dst.type = intel->is_g4x ? brw_type_for_base_type(ir->type)
 
767
                               : BRW_REGISTER_TYPE_F;
680
768
   }
681
769
 
682
770
   fs_inst *inst = NULL;
683
771
   switch (ir->op) {
684
772
   case ir_tex:
685
 
      inst = emit(FS_OPCODE_TEX, dst);
 
773
      inst = emit(SHADER_OPCODE_TEX, dst);
686
774
      break;
687
775
   case ir_txb:
688
776
      inst = emit(FS_OPCODE_TXB, dst);
689
777
      break;
690
778
   case ir_txl:
691
 
      inst = emit(FS_OPCODE_TXL, dst);
 
779
      inst = emit(SHADER_OPCODE_TXL, dst);
692
780
      break;
693
781
   case ir_txd:
694
 
      inst = emit(FS_OPCODE_TXD, dst);
 
782
      inst = emit(SHADER_OPCODE_TXD, dst);
 
783
      break;
 
784
   case ir_txs:
 
785
      inst = emit(SHADER_OPCODE_TXS, dst);
695
786
      break;
696
787
   case ir_txf:
697
 
      assert(!"GLSL 1.30 features unsupported");
 
788
      inst = emit(SHADER_OPCODE_TXF, dst);
698
789
      break;
699
790
   }
700
791
   inst->base_mrf = base_mrf;
728
819
   int base_mrf = 2;
729
820
   int reg_width = c->dispatch_width / 8;
730
821
   bool header_present = false;
 
822
   const int vector_elements =
 
823
      ir->coordinate ? ir->coordinate->type->vector_elements : 0;
731
824
 
732
825
   if (ir->offset) {
733
826
      /* The offsets set up by the ir_texture visitor are in the
738
831
      base_mrf--;
739
832
   }
740
833
 
741
 
   for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
 
834
   for (int i = 0; i < vector_elements; i++) {
742
835
      fs_inst *inst = emit(BRW_OPCODE_MOV,
743
 
                           fs_reg(MRF, base_mrf + mlen + i * reg_width),
 
836
                           fs_reg(MRF, base_mrf + mlen + i * reg_width,
 
837
                                  coordinate.type),
744
838
                           coordinate);
745
 
      if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
 
839
      if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler))
746
840
         inst->saturate = true;
747
841
      coordinate.reg_offset++;
748
842
   }
749
 
   mlen += ir->coordinate->type->vector_elements * reg_width;
 
843
   mlen += vector_elements * reg_width;
750
844
 
751
845
   if (ir->shadow_comparitor && ir->op != ir_txd) {
752
846
      mlen = MAX2(mlen, header_present + 4 * reg_width);
753
847
 
754
 
      this->result = reg_undef;
755
848
      ir->shadow_comparitor->accept(this);
756
849
      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
757
850
      mlen += reg_width;
760
853
   fs_inst *inst = NULL;
761
854
   switch (ir->op) {
762
855
   case ir_tex:
763
 
      inst = emit(FS_OPCODE_TEX, dst);
 
856
      inst = emit(SHADER_OPCODE_TEX, dst);
764
857
      break;
765
858
   case ir_txb:
766
 
      this->result = reg_undef;
767
859
      ir->lod_info.bias->accept(this);
768
860
      mlen = MAX2(mlen, header_present + 4 * reg_width);
769
861
      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
773
865
 
774
866
      break;
775
867
   case ir_txl:
776
 
      this->result = reg_undef;
777
868
      ir->lod_info.lod->accept(this);
778
869
      mlen = MAX2(mlen, header_present + 4 * reg_width);
779
870
      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
780
871
      mlen += reg_width;
781
872
 
782
 
      inst = emit(FS_OPCODE_TXL, dst);
 
873
      inst = emit(SHADER_OPCODE_TXL, dst);
783
874
      break;
784
875
   case ir_txd: {
785
 
      this->result = reg_undef;
786
876
      ir->lod_info.grad.dPdx->accept(this);
787
877
      fs_reg dPdx = this->result;
788
878
 
789
 
      this->result = reg_undef;
790
879
      ir->lod_info.grad.dPdy->accept(this);
791
880
      fs_reg dPdy = this->result;
792
881
 
811
900
         mlen += reg_width;
812
901
      }
813
902
 
814
 
      inst = emit(FS_OPCODE_TXD, dst);
 
903
      inst = emit(SHADER_OPCODE_TXD, dst);
815
904
      break;
816
905
   }
 
906
   case ir_txs:
 
907
      ir->lod_info.lod->accept(this);
 
908
      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result);
 
909
      mlen += reg_width;
 
910
      inst = emit(SHADER_OPCODE_TXS, dst);
 
911
      break;
817
912
   case ir_txf:
818
 
      assert(!"GLSL 1.30 features unsupported");
 
913
      mlen = header_present + 4 * reg_width;
 
914
 
 
915
      ir->lod_info.lod->accept(this);
 
916
      emit(BRW_OPCODE_MOV,
 
917
           fs_reg(MRF, base_mrf + mlen - reg_width, BRW_REGISTER_TYPE_UD),
 
918
           this->result);
 
919
      inst = emit(SHADER_OPCODE_TXF, dst);
819
920
      break;
820
921
   }
821
922
   inst->base_mrf = base_mrf;
848
949
   }
849
950
 
850
951
   if (ir->shadow_comparitor && ir->op != ir_txd) {
851
 
      this->result = reg_undef;
852
952
      ir->shadow_comparitor->accept(this);
853
953
      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
854
954
      mlen += reg_width;
859
959
   case ir_tex:
860
960
      break;
861
961
   case ir_txb:
862
 
      this->result = reg_undef;
863
962
      ir->lod_info.bias->accept(this);
864
963
      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
865
964
      mlen += reg_width;
866
965
      break;
867
966
   case ir_txl:
868
 
      this->result = reg_undef;
869
967
      ir->lod_info.lod->accept(this);
870
968
      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
871
969
      mlen += reg_width;
874
972
      if (c->dispatch_width == 16)
875
973
         fail("Gen7 does not support sample_d/sample_d_c in SIMD16 mode.");
876
974
 
877
 
      this->result = reg_undef;
878
975
      ir->lod_info.grad.dPdx->accept(this);
879
976
      fs_reg dPdx = this->result;
880
977
 
881
 
      this->result = reg_undef;
882
978
      ir->lod_info.grad.dPdy->accept(this);
883
979
      fs_reg dPdy = this->result;
884
980
 
888
984
      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
889
985
         fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen),
890
986
                              coordinate);
891
 
         if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
 
987
         if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler))
892
988
            inst->saturate = true;
893
989
         coordinate.reg_offset++;
894
990
         mlen += reg_width;
903
999
      }
904
1000
      break;
905
1001
   }
 
1002
   case ir_txs:
 
1003
      ir->lod_info.lod->accept(this);
 
1004
      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result);
 
1005
      mlen += reg_width;
 
1006
      break;
906
1007
   case ir_txf:
907
 
      assert(!"GLSL 1.30 features unsupported");
 
1008
      /* Unfortunately, the parameters for LD are intermixed: u, lod, v, r. */
 
1009
      emit(BRW_OPCODE_MOV,
 
1010
           fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate);
 
1011
      coordinate.reg_offset++;
 
1012
      mlen += reg_width;
 
1013
 
 
1014
      ir->lod_info.lod->accept(this);
 
1015
      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), this->result);
 
1016
      mlen += reg_width;
 
1017
 
 
1018
      for (int i = 1; i < ir->coordinate->type->vector_elements; i++) {
 
1019
         emit(BRW_OPCODE_MOV,
 
1020
              fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_D), coordinate);
 
1021
         coordinate.reg_offset++;
 
1022
         mlen += reg_width;
 
1023
      }
908
1024
      break;
909
1025
   }
910
1026
 
911
 
   /* Set up the coordinate (except for TXD where it was done earlier) */
912
 
   if (ir->op != ir_txd) {
 
1027
   /* Set up the coordinate (except for cases where it was done above) */
 
1028
   if (ir->op != ir_txd && ir->op != ir_txs && ir->op != ir_txf) {
913
1029
      for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
914
1030
         fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen),
915
1031
                              coordinate);
916
 
         if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
 
1032
         if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler))
917
1033
            inst->saturate = true;
918
1034
         coordinate.reg_offset++;
919
1035
         mlen += reg_width;
923
1039
   /* Generate the SEND */
924
1040
   fs_inst *inst = NULL;
925
1041
   switch (ir->op) {
926
 
   case ir_tex: inst = emit(FS_OPCODE_TEX, dst); break;
 
1042
   case ir_tex: inst = emit(SHADER_OPCODE_TEX, dst); break;
927
1043
   case ir_txb: inst = emit(FS_OPCODE_TXB, dst); break;
928
 
   case ir_txl: inst = emit(FS_OPCODE_TXL, dst); break;
929
 
   case ir_txd: inst = emit(FS_OPCODE_TXD, dst); break;
930
 
   case ir_txf: assert(!"TXF unsupported.");
 
1044
   case ir_txl: inst = emit(SHADER_OPCODE_TXL, dst); break;
 
1045
   case ir_txd: inst = emit(SHADER_OPCODE_TXD, dst); break;
 
1046
   case ir_txf: inst = emit(SHADER_OPCODE_TXF, dst); break;
 
1047
   case ir_txs: inst = emit(SHADER_OPCODE_TXS, dst); break;
931
1048
   }
932
1049
   inst->base_mrf = base_mrf;
933
1050
   inst->mlen = mlen;
953
1070
    */
954
1071
   bool hw_compare_supported = ir->op != ir_txd;
955
1072
   if (ir->shadow_comparitor && !hw_compare_supported) {
956
 
      assert(c->key.compare_funcs[sampler] != GL_NONE);
 
1073
      assert(c->key.tex.compare_funcs[sampler] != GL_NONE);
957
1074
      /* No need to even sample for GL_ALWAYS or GL_NEVER...bail early */
958
 
      if (c->key.compare_funcs[sampler] == GL_ALWAYS)
 
1075
      if (c->key.tex.compare_funcs[sampler] == GL_ALWAYS)
959
1076
         return swizzle_result(ir, fs_reg(1.0f), sampler);
960
 
      else if (c->key.compare_funcs[sampler] == GL_NEVER)
 
1077
      else if (c->key.tex.compare_funcs[sampler] == GL_NEVER)
961
1078
         return swizzle_result(ir, fs_reg(0.0f), sampler);
962
1079
   }
963
1080
 
964
 
   this->result = reg_undef;
965
 
   ir->coordinate->accept(this);
 
1081
   if (ir->coordinate)
 
1082
      ir->coordinate->accept(this);
966
1083
   fs_reg coordinate = this->result;
967
1084
 
968
1085
   if (ir->offset != NULL) {
969
 
      ir_constant *offset = ir->offset->as_constant();
970
 
      assert(offset != NULL);
971
 
 
972
 
      signed char offsets[3];
973
 
      for (unsigned i = 0; i < ir->offset->type->vector_elements; i++)
974
 
         offsets[i] = (signed char) offset->value.i[i];
975
 
 
976
 
      /* Combine all three offsets into a single unsigned dword:
977
 
       *
978
 
       *    bits 11:8 - U Offset (X component)
979
 
       *    bits  7:4 - V Offset (Y component)
980
 
       *    bits  3:0 - R Offset (Z component)
981
 
       */
982
 
      unsigned offset_bits = 0;
983
 
      for (unsigned i = 0; i < ir->offset->type->vector_elements; i++) {
984
 
         const unsigned shift = 4 * (2 - i);
985
 
         offset_bits |= (offsets[i] << shift) & (0xF << shift);
986
 
      }
 
1086
      uint32_t offset_bits = brw_texture_offset(ir->offset->as_constant());
987
1087
 
988
1088
      /* Explicitly set up the message header by copying g0 to msg reg m1. */
989
1089
      emit(BRW_OPCODE_MOV, fs_reg(MRF, 1, BRW_REGISTER_TYPE_UD),
990
 
           fs_reg(GRF, 0, BRW_REGISTER_TYPE_UD));
 
1090
           fs_reg(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD)));
991
1091
 
992
1092
      /* Then set the offset bits in DWord 2 of the message header. */
993
1093
      emit(BRW_OPCODE_MOV,
1003
1103
    * texture coordinates.  We use the program parameter state
1004
1104
    * tracking to get the scaling factor.
1005
1105
    */
1006
 
   if (ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT) {
 
1106
   if (intel->gen < 6 &&
 
1107
       ir->sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_RECT) {
1007
1108
      struct gl_program_parameter_list *params = c->fp->program.Base.Parameters;
1008
1109
      int tokens[STATE_LENGTH] = {
1009
1110
         STATE_INTERNAL,
1049
1150
   /* Writemasking doesn't eliminate channels on SIMD8 texture
1050
1151
    * samples, so don't worry about them.
1051
1152
    */
1052
 
   fs_reg dst = fs_reg(this, glsl_type::vec4_type);
 
1153
   fs_reg dst = fs_reg(this, glsl_type::get_instance(ir->type->base_type, 4, 1));
1053
1154
 
1054
1155
   if (intel->gen >= 7) {
1055
1156
      inst = emit_texture_gen7(ir, dst, coordinate, sampler);
1073
1174
      if (hw_compare_supported) {
1074
1175
         inst->shadow_compare = true;
1075
1176
      } else {
1076
 
         this->result = reg_undef;
1077
1177
         ir->shadow_comparitor->accept(this);
1078
1178
         fs_reg ref = this->result;
1079
1179
 
1083
1183
         /* FINISHME: This needs to be done pre-filtering. */
1084
1184
 
1085
1185
         uint32_t conditional = 0;
1086
 
         switch (c->key.compare_funcs[sampler]) {
 
1186
         switch (c->key.tex.compare_funcs[sampler]) {
1087
1187
         /* GL_ALWAYS and GL_NEVER were handled at the top of the function */
1088
1188
         case GL_LESS:     conditional = BRW_CONDITIONAL_L;   break;
1089
1189
         case GL_GREATER:  conditional = BRW_CONDITIONAL_G;   break;
1124
1224
{
1125
1225
   this->result = orig_val;
1126
1226
 
 
1227
   if (ir->op == ir_txs)
 
1228
      return;
 
1229
 
1127
1230
   if (ir->type == glsl_type::float_type) {
1128
1231
      /* Ignore DEPTH_TEXTURE_MODE swizzling. */
1129
1232
      assert(ir->sampler->type->sampler_shadow);
1130
 
   } else if (c->key.tex_swizzles[sampler] != SWIZZLE_NOOP) {
 
1233
   } else if (c->key.tex.swizzles[sampler] != SWIZZLE_NOOP) {
1131
1234
      fs_reg swizzled_result = fs_reg(this, glsl_type::vec4_type);
1132
1235
 
1133
1236
      for (int i = 0; i < 4; i++) {
1134
 
         int swiz = GET_SWZ(c->key.tex_swizzles[sampler], i);
 
1237
         int swiz = GET_SWZ(c->key.tex.swizzles[sampler], i);
1135
1238
         fs_reg l = swizzled_result;
1136
1239
         l.reg_offset += i;
1137
1240
 
1141
1244
            emit(BRW_OPCODE_MOV, l, fs_reg(1.0f));
1142
1245
         } else {
1143
1246
            fs_reg r = orig_val;
1144
 
            r.reg_offset += GET_SWZ(c->key.tex_swizzles[sampler], i);
 
1247
            r.reg_offset += GET_SWZ(c->key.tex.swizzles[sampler], i);
1145
1248
            emit(BRW_OPCODE_MOV, l, r);
1146
1249
         }
1147
1250
      }
1152
1255
void
1153
1256
fs_visitor::visit(ir_swizzle *ir)
1154
1257
{
1155
 
   this->result = reg_undef;
1156
1258
   ir->val->accept(this);
1157
1259
   fs_reg val = this->result;
1158
1260
 
1215
1317
      const unsigned size = type_size(ir->type->fields.array);
1216
1318
 
1217
1319
      for (unsigned i = 0; i < ir->type->length; i++) {
1218
 
         this->result = reg_undef;
1219
1320
         ir->array_elements[i]->accept(this);
1220
1321
         fs_reg src_reg = this->result;
1221
1322
 
1231
1332
         ir_instruction *const field = (ir_instruction *) node;
1232
1333
         const unsigned size = type_size(field->type);
1233
1334
 
1234
 
         this->result = reg_undef;
1235
1335
         field->accept(this);
1236
1336
         fs_reg src_reg = this->result;
1237
1337
 
1282
1382
      for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
1283
1383
         assert(expr->operands[i]->type->is_scalar());
1284
1384
 
1285
 
         this->result = reg_undef;
1286
1385
         expr->operands[i]->accept(this);
1287
1386
         op[i] = this->result;
 
1387
 
 
1388
         resolve_ud_negate(&op[i]);
1288
1389
      }
1289
1390
 
1290
1391
      switch (expr->operation) {
1347
1448
      return;
1348
1449
   }
1349
1450
 
1350
 
   this->result = reg_undef;
1351
1451
   ir->accept(this);
1352
1452
 
1353
1453
   if (intel->gen >= 6) {
1377
1477
      for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
1378
1478
         assert(expr->operands[i]->type->is_scalar());
1379
1479
 
1380
 
         this->result = reg_undef;
1381
1480
         expr->operands[i]->accept(this);
1382
1481
         op[i] = this->result;
1383
1482
      }
1439
1538
      return;
1440
1539
   }
1441
1540
 
1442
 
   this->result = reg_undef;
1443
1541
   ir->condition->accept(this);
1444
1542
 
1445
1543
   fs_inst *inst = emit(BRW_OPCODE_IF, reg_null_d, this->result, fs_reg(0));
1451
1549
{
1452
1550
   fs_inst *inst;
1453
1551
 
1454
 
   if (intel->gen != 6 && c->dispatch_width == 16) {
 
1552
   if (intel->gen < 6 && c->dispatch_width == 16) {
1455
1553
      fail("Can't support (non-uniform) control flow on 16-wide\n");
1456
1554
   }
1457
1555
 
1469
1567
      inst->predicated = true;
1470
1568
   }
1471
1569
 
1472
 
   foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
1473
 
      ir_instruction *ir = (ir_instruction *)iter.get();
 
1570
   foreach_list(node, &ir->then_instructions) {
 
1571
      ir_instruction *ir = (ir_instruction *)node;
1474
1572
      this->base_ir = ir;
1475
 
      this->result = reg_undef;
 
1573
 
1476
1574
      ir->accept(this);
1477
1575
   }
1478
1576
 
1479
1577
   if (!ir->else_instructions.is_empty()) {
1480
1578
      emit(BRW_OPCODE_ELSE);
1481
1579
 
1482
 
      foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
1483
 
         ir_instruction *ir = (ir_instruction *)iter.get();
 
1580
      foreach_list(node, &ir->else_instructions) {
 
1581
         ir_instruction *ir = (ir_instruction *)node;
1484
1582
         this->base_ir = ir;
1485
 
         this->result = reg_undef;
 
1583
 
1486
1584
         ir->accept(this);
1487
1585
      }
1488
1586
   }
1505
1603
      counter = *(variable_storage(ir->counter));
1506
1604
 
1507
1605
      if (ir->from) {
1508
 
         this->result = counter;
1509
 
 
1510
1606
         this->base_ir = ir->from;
1511
 
         this->result = counter;
1512
1607
         ir->from->accept(this);
1513
1608
 
1514
 
         if (!this->result.equals(&counter))
1515
 
            emit(BRW_OPCODE_MOV, counter, this->result);
 
1609
         emit(BRW_OPCODE_MOV, counter, this->result);
1516
1610
      }
1517
1611
   }
1518
1612
 
1520
1614
 
1521
1615
   if (ir->to) {
1522
1616
      this->base_ir = ir->to;
1523
 
      this->result = reg_undef;
1524
1617
      ir->to->accept(this);
1525
1618
 
1526
1619
      fs_inst *inst = emit(BRW_OPCODE_CMP, reg_null_cmp, counter, this->result);
1530
1623
      inst->predicated = true;
1531
1624
   }
1532
1625
 
1533
 
   foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
1534
 
      ir_instruction *ir = (ir_instruction *)iter.get();
 
1626
   foreach_list(node, &ir->body_instructions) {
 
1627
      ir_instruction *ir = (ir_instruction *)node;
1535
1628
 
1536
1629
      this->base_ir = ir;
1537
 
      this->result = reg_undef;
1538
1630
      ir->accept(this);
1539
1631
   }
1540
1632
 
1541
1633
   if (ir->increment) {
1542
1634
      this->base_ir = ir->increment;
1543
 
      this->result = reg_undef;
1544
1635
      ir->increment->accept(this);
1545
1636
      emit(BRW_OPCODE_ADD, counter, counter, this->result);
1546
1637
   }
1587
1678
 
1588
1679
      assert(sig);
1589
1680
 
1590
 
      foreach_iter(exec_list_iterator, iter, sig->body) {
1591
 
         ir_instruction *ir = (ir_instruction *)iter.get();
 
1681
      foreach_list(node, &sig->body) {
 
1682
         ir_instruction *ir = (ir_instruction *)node;
1592
1683
         this->base_ir = ir;
1593
 
         this->result = reg_undef;
 
1684
 
1594
1685
         ir->accept(this);
1595
1686
      }
1596
1687
   }
1634
1725
 
1635
1726
   fs_inst *write;
1636
1727
   write = emit(FS_OPCODE_FB_WRITE, fs_reg(0), fs_reg(0));
1637
 
   write->base_mrf = 0;
 
1728
   write->base_mrf = 2;
1638
1729
}
1639
1730
 
1640
1731
/* The register location here is relative to the start of the URB
1667
1758
 
1668
1759
   this->current_annotation = "compute pixel deltas from v0";
1669
1760
   if (brw->has_pln) {
1670
 
      this->delta_x = fs_reg(this, glsl_type::vec2_type);
1671
 
      this->delta_y = this->delta_x;
1672
 
      this->delta_y.reg_offset++;
 
1761
      this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] =
 
1762
         fs_reg(this, glsl_type::vec2_type);
 
1763
      this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] =
 
1764
         this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC];
 
1765
      this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC].reg_offset++;
1673
1766
   } else {
1674
 
      this->delta_x = fs_reg(this, glsl_type::float_type);
1675
 
      this->delta_y = fs_reg(this, glsl_type::float_type);
 
1767
      this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] =
 
1768
         fs_reg(this, glsl_type::float_type);
 
1769
      this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC] =
 
1770
         fs_reg(this, glsl_type::float_type);
1676
1771
   }
1677
 
   emit(BRW_OPCODE_ADD, this->delta_x,
 
1772
   emit(BRW_OPCODE_ADD, this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC],
1678
1773
        this->pixel_x, fs_reg(negate(brw_vec1_grf(1, 0))));
1679
 
   emit(BRW_OPCODE_ADD, this->delta_y,
 
1774
   emit(BRW_OPCODE_ADD, this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC],
1680
1775
        this->pixel_y, fs_reg(negate(brw_vec1_grf(1, 1))));
1681
1776
 
1682
1777
   this->current_annotation = "compute pos.w and 1/pos.w";
1684
1779
    * interpolate the other attributes.
1685
1780
    */
1686
1781
   this->wpos_w = fs_reg(this, glsl_type::float_type);
1687
 
   emit(FS_OPCODE_LINTERP, wpos_w, this->delta_x, this->delta_y,
 
1782
   emit(FS_OPCODE_LINTERP, wpos_w,
 
1783
        this->delta_x[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC],
 
1784
        this->delta_y[BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC],
1688
1785
        interp_reg(FRAG_ATTRIB_WPOS, 3));
1689
1786
   /* Compute the pixel 1/W value from wpos.w. */
1690
1787
   this->pixel_w = fs_reg(this, glsl_type::float_type);
1691
 
   emit_math(FS_OPCODE_RCP, this->pixel_w, wpos_w);
 
1788
   emit_math(SHADER_OPCODE_RCP, this->pixel_w, wpos_w);
1692
1789
   this->current_annotation = NULL;
1693
1790
}
1694
1791
 
1725
1822
   this->current_annotation = "compute pos.w";
1726
1823
   this->pixel_w = fs_reg(brw_vec8_grf(c->source_w_reg, 0));
1727
1824
   this->wpos_w = fs_reg(this, glsl_type::float_type);
1728
 
   emit_math(FS_OPCODE_RCP, this->wpos_w, this->pixel_w);
 
1825
   emit_math(SHADER_OPCODE_RCP, this->wpos_w, this->pixel_w);
1729
1826
 
1730
 
   this->delta_x = fs_reg(brw_vec8_grf(2, 0));
1731
 
   this->delta_y = fs_reg(brw_vec8_grf(3, 0));
 
1827
   for (int i = 0; i < BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT; ++i) {
 
1828
      uint8_t reg = c->barycentric_coord_reg[i];
 
1829
      this->delta_x[i] = fs_reg(brw_vec8_grf(reg, 0));
 
1830
      this->delta_y[i] = fs_reg(brw_vec8_grf(reg + 1, 0));
 
1831
   }
1732
1832
 
1733
1833
   this->current_annotation = NULL;
1734
1834
}
1735
1835
 
1736
1836
void
1737
 
fs_visitor::emit_color_write(int index, int first_color_mrf, fs_reg color)
 
1837
fs_visitor::emit_color_write(int target, int index, int first_color_mrf)
1738
1838
{
1739
1839
   int reg_width = c->dispatch_width / 8;
1740
 
 
1741
 
   if (c->dispatch_width == 8 || intel->gen == 6) {
 
1840
   fs_inst *inst;
 
1841
   fs_reg color = outputs[target];
 
1842
   fs_reg mrf;
 
1843
 
 
1844
   /* If there's no color data to be written, skip it. */
 
1845
   if (color.file == BAD_FILE)
 
1846
      return;
 
1847
 
 
1848
   color.reg_offset += index;
 
1849
 
 
1850
   if (c->dispatch_width == 8 || intel->gen >= 6) {
1742
1851
      /* SIMD8 write looks like:
1743
1852
       * m + 0: r0
1744
1853
       * m + 1: r1
1755
1864
       * m + 6: a0
1756
1865
       * m + 7: a1
1757
1866
       */
1758
 
      emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index * reg_width),
1759
 
           color);
 
1867
      inst = emit(BRW_OPCODE_MOV,
 
1868
                  fs_reg(MRF, first_color_mrf + index * reg_width, color.type),
 
1869
                  color);
 
1870
      inst->saturate = c->key.clamp_fragment_color;
1760
1871
   } else {
1761
1872
      /* pre-gen6 SIMD16 single source DP write looks like:
1762
1873
       * m + 0: r0
1774
1885
          * usual destination + 1 for the second half we get
1775
1886
          * destination + 4.
1776
1887
          */
1777
 
         emit(BRW_OPCODE_MOV,
1778
 
              fs_reg(MRF, BRW_MRF_COMPR4 + first_color_mrf + index), color);
 
1888
         inst = emit(BRW_OPCODE_MOV,
 
1889
                     fs_reg(MRF, BRW_MRF_COMPR4 + first_color_mrf + index,
 
1890
                            color.type),
 
1891
                     color);
 
1892
         inst->saturate = c->key.clamp_fragment_color;
1779
1893
      } else {
1780
1894
         push_force_uncompressed();
1781
 
         emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index), color);
 
1895
         inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index,
 
1896
                                            color.type),
 
1897
                     color);
 
1898
         inst->saturate = c->key.clamp_fragment_color;
1782
1899
         pop_force_uncompressed();
1783
1900
 
1784
1901
         push_force_sechalf();
1785
1902
         color.sechalf = true;
1786
 
         emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index + 4), color);
 
1903
         inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, first_color_mrf + index + 4,
 
1904
                                            color.type),
 
1905
                     color);
 
1906
         inst->saturate = c->key.clamp_fragment_color;
1787
1907
         pop_force_sechalf();
1788
1908
         color.sechalf = false;
1789
1909
      }
1794
1914
fs_visitor::emit_fb_writes()
1795
1915
{
1796
1916
   this->current_annotation = "FB write header";
1797
 
   GLboolean header_present = GL_TRUE;
1798
 
   int nr = 0;
 
1917
   bool header_present = true;
 
1918
   int base_mrf = 2;
 
1919
   int nr = base_mrf;
1799
1920
   int reg_width = c->dispatch_width / 8;
1800
1921
 
1801
1922
   if (intel->gen >= 6 &&
1805
1926
   }
1806
1927
 
1807
1928
   if (header_present) {
1808
 
      /* m0, m1 header */
 
1929
      /* m2, m3 header */
1809
1930
      nr += 2;
1810
1931
   }
1811
1932
 
1850
1971
      nr += reg_width;
1851
1972
   }
1852
1973
 
1853
 
   fs_reg color = reg_undef;
1854
 
   if (this->frag_color)
1855
 
      color = *(variable_storage(this->frag_color));
1856
 
   else if (this->frag_data) {
1857
 
      color = *(variable_storage(this->frag_data));
1858
 
      color.type = BRW_REGISTER_TYPE_F;
1859
 
   }
1860
 
 
1861
1974
   for (int target = 0; target < c->key.nr_color_regions; target++) {
1862
1975
      this->current_annotation = ralloc_asprintf(this->mem_ctx,
1863
1976
                                                 "FB write target %d",
1864
1977
                                                 target);
1865
 
      if (this->frag_color || this->frag_data) {
1866
 
         for (int i = 0; i < 4; i++) {
1867
 
            emit_color_write(i, color_mrf, color);
1868
 
            color.reg_offset++;
1869
 
         }
1870
 
      }
1871
 
 
1872
 
      if (this->frag_color)
1873
 
         color.reg_offset -= 4;
 
1978
      for (int i = 0; i < 4; i++)
 
1979
         emit_color_write(target, i, color_mrf);
1874
1980
 
1875
1981
      fs_inst *inst = emit(FS_OPCODE_FB_WRITE);
1876
1982
      inst->target = target;
1877
 
      inst->base_mrf = 0;
1878
 
      inst->mlen = nr;
 
1983
      inst->base_mrf = base_mrf;
 
1984
      inst->mlen = nr - base_mrf;
1879
1985
      if (target == c->key.nr_color_regions - 1)
1880
1986
         inst->eot = true;
1881
1987
      inst->header_present = header_present;
1882
1988
   }
1883
1989
 
1884
1990
   if (c->key.nr_color_regions == 0) {
1885
 
      if (c->key.alpha_test && (this->frag_color || this->frag_data)) {
 
1991
      if (c->key.alpha_test) {
1886
1992
         /* If the alpha test is enabled but there's no color buffer,
1887
1993
          * we still need to send alpha out the pipeline to our null
1888
1994
          * renderbuffer.
1889
1995
          */
1890
 
         color.reg_offset += 3;
1891
 
         emit_color_write(3, color_mrf, color);
 
1996
         emit_color_write(0, 3, color_mrf);
1892
1997
      }
1893
1998
 
1894
1999
      fs_inst *inst = emit(FS_OPCODE_FB_WRITE);
1895
 
      inst->base_mrf = 0;
1896
 
      inst->mlen = nr;
 
2000
      inst->base_mrf = base_mrf;
 
2001
      inst->mlen = nr - base_mrf;
1897
2002
      inst->eot = true;
1898
2003
      inst->header_present = header_present;
1899
2004
   }
1900
2005
 
1901
2006
   this->current_annotation = NULL;
1902
2007
}
 
2008
 
 
2009
void
 
2010
fs_visitor::resolve_ud_negate(fs_reg *reg)
 
2011
{
 
2012
   if (reg->type != BRW_REGISTER_TYPE_UD ||
 
2013
       !reg->negate)
 
2014
      return;
 
2015
 
 
2016
   fs_reg temp = fs_reg(this, glsl_type::uint_type);
 
2017
   emit(BRW_OPCODE_MOV, temp, *reg);
 
2018
   *reg = temp;
 
2019
}