i965: Use sample barycentric coordinates with per sample shading
[mesa.git] / src / mesa / drivers / dri / i965 / brw_fs_reg_allocate.cpp
index 64fb78b6bdd41c5a85a647ef0aadda96e1ab076d..2494b117e57506e2c9d4336148600e17a914e97a 100644 (file)
@@ -78,7 +78,7 @@ brw_alloc_reg_set(struct brw_context *brw, int reg_width)
 
    /* The registers used to make up almost all values handled in the compiler
     * are a scalar value occupying a single register (or 2 registers in the
-    * case of 16-wide, which is handled by dividing base_reg_count by 2 and
+    * case of SIMD16, which is handled by dividing base_reg_count by 2 and
     * multiplying allocated register numbers by 2).  Things that were
     * aggregates of scalar values at the GLSL level were split to scalar
     * values by split_virtual_grfs().
@@ -103,7 +103,8 @@ brw_alloc_reg_set(struct brw_context *brw, int reg_width)
    int class_sizes[BRW_MAX_MRF];
 
    if (brw->gen >= 7) {
-      for (class_count = 0; class_count < 11; class_count++)
+      for (class_count = 0; class_count < MAX_SAMPLER_MESSAGE_SIZE;
+           class_count++)
          class_sizes[class_count] = class_count + 1;
    } else {
       for (class_count = 0; class_count < 4; class_count++)
@@ -225,7 +226,7 @@ count_to_loop_end(fs_inst *do_inst)
  * nr_payload_regs+curb_read_lengh..first_non_payload_grf-1: setup coefficients.
  *
  * And we have payload_node_count nodes covering these registers in order
- * (note that in 16-wide, a node is two registers).
+ * (note that in SIMD16, a node is two registers).
  */
 void
 fs_visitor::setup_payload_interference(struct ra_graph *g,
@@ -295,7 +296,7 @@ fs_visitor::setup_payload_interference(struct ra_graph *g,
          break;
 
       case FS_OPCODE_LINTERP:
-         /* On gen6+ in 16-wide, there are 4 adjacent registers (so 2 nodes)
+         /* On gen6+ in SIMD16, there are 4 adjacent registers (so 2 nodes)
           * used by PLN's sourcing of the deltas, while we list only the first
           * two in the arguments (1 node).  Pre-gen6, the deltas are computed
           * in normal VGRFs.
@@ -417,10 +418,10 @@ fs_visitor::setup_mrf_hack_interference(struct ra_graph *g, int first_mrf_node)
 }
 
 bool
-fs_visitor::assign_regs()
+fs_visitor::assign_regs(bool allow_spilling)
 {
    /* Most of this allocation was written for a reg_width of 1
-    * (dispatch_width == 8).  In extending to 16-wide, the code was
+    * (dispatch_width == 8).  In extending to SIMD16, the code was
     * left in place and it was converted to have the hardware
     * registers it's allocating be contiguous physical pairs of regs
     * for reg_width == 2.
@@ -496,14 +497,10 @@ fs_visitor::assign_regs()
       if (reg == -1) {
          fail("no register to spill:\n");
          dump_instructions();
-      } else if (dispatch_width == 16) {
-        fail("Failure to register allocate.  Reduce number of live scalar "
-              "values to avoid this.");
-      } else {
-        spill_reg(reg);
+      } else if (allow_spilling) {
+         spill_reg(reg);
       }
 
-
       ralloc_free(g);
 
       return false;
@@ -542,13 +539,22 @@ fs_visitor::emit_unspill(fs_inst *inst, fs_reg dst, uint32_t spill_offset,
                          int count)
 {
    for (int i = 0; i < count; i++) {
-      fs_inst *unspill_inst = new(mem_ctx) fs_inst(FS_OPCODE_UNSPILL, dst);
+      /* The gen7 descriptor-based offset is 12 bits of HWORD units. */
+      bool gen7_read = brw->gen >= 7 && spill_offset < (1 << 12) * REG_SIZE;
+
+      fs_inst *unspill_inst =
+         new(mem_ctx) fs_inst(gen7_read ?
+                              SHADER_OPCODE_GEN7_SCRATCH_READ :
+                              SHADER_OPCODE_GEN4_SCRATCH_READ,
+                              dst);
       unspill_inst->offset = spill_offset;
       unspill_inst->ir = inst->ir;
       unspill_inst->annotation = inst->annotation;
 
-      unspill_inst->base_mrf = 14;
-      unspill_inst->mlen = 1; /* header contains offset */
+      if (!gen7_read) {
+         unspill_inst->base_mrf = 14;
+         unspill_inst->mlen = 1; /* header contains offset */
+      }
       inst->insert_before(unspill_inst);
 
       dst.reg_offset++;
@@ -610,12 +616,13 @@ fs_visitor::choose_spill_reg(struct ra_graph *g)
         loop_scale /= 10;
         break;
 
-      case FS_OPCODE_SPILL:
+      case SHADER_OPCODE_GEN4_SCRATCH_WRITE:
         if (inst->src[0].file == GRF)
            no_spill[inst->src[0].reg] = true;
         break;
 
-      case FS_OPCODE_UNSPILL:
+      case SHADER_OPCODE_GEN4_SCRATCH_READ:
+      case SHADER_OPCODE_GEN7_SCRATCH_READ:
         if (inst->dst.file == GRF)
            no_spill[inst->dst.reg] = true;
         break;
@@ -677,13 +684,13 @@ fs_visitor::spill_reg(int spill_reg)
         if (inst->src[i].file == GRF &&
             inst->src[i].reg == spill_reg) {
             int regs_read = inst->regs_read(this, i);
+            int subset_spill_offset = (spill_offset +
+                                       reg_size * inst->src[i].reg_offset);
 
             inst->src[i].reg = virtual_grf_alloc(regs_read);
             inst->src[i].reg_offset = 0;
 
-            emit_unspill(inst, inst->src[i],
-                         spill_offset + reg_size * inst->src[i].reg_offset,
-                         regs_read);
+            emit_unspill(inst, inst->src[i], subset_spill_offset, regs_read);
         }
       }
 
@@ -710,8 +717,9 @@ fs_visitor::spill_reg(int spill_reg)
         spill_src.smear = -1;
 
         for (int chan = 0; chan < inst->regs_written; chan++) {
-           fs_inst *spill_inst = new(mem_ctx) fs_inst(FS_OPCODE_SPILL,
-                                                      reg_null_f, spill_src);
+           fs_inst *spill_inst =
+               new(mem_ctx) fs_inst(SHADER_OPCODE_GEN4_SCRATCH_WRITE,
+                                    reg_null_f, spill_src);
            spill_src.reg_offset++;
            spill_inst->offset = subset_spill_offset + chan * reg_size;
            spill_inst->ir = inst->ir;