Mesa (master): i965/fs: Fix register spilling for 16-wide.

Eric Anholt anholt at kemper.freedesktop.org
Thu Oct 31 01:09:52 UTC 2013


Module: Mesa
Branch: master
Commit: 0e20051f54f31f83edba9ac9f8f3a16bb747c698
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0e20051f54f31f83edba9ac9f8f3a16bb747c698

Author: Eric Anholt <eric at anholt.net>
Date:   Wed Oct 16 12:16:51 2013 -0700

i965/fs: Fix register spilling for 16-wide.

Things blew up when I enabled the debug register spill code without
disabling 16-wide, so I decided to just fix 16-wide spilling.

We still don't generate 16-wide when register spilling happens as part of
allocation (since we expect it to be slower), but now we can experiment
with allowing it in some cases in the future.

Reviewed-by: Paul Berry <stereotype441 at gmail.com>

---

 src/mesa/drivers/dri/i965/brw_fs_generator.cpp    |    8 ++++----
 src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp |   19 +++++++++----------
 2 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
index ef85837..e16d874 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
@@ -756,8 +756,8 @@ fs_generator::generate_spill(fs_inst *inst, struct brw_reg src)
    brw_MOV(p,
 	   retype(brw_message_reg(inst->base_mrf + 1), BRW_REGISTER_TYPE_UD),
 	   retype(src, BRW_REGISTER_TYPE_UD));
-   brw_oword_block_write_scratch(p, brw_message_reg(inst->base_mrf), 1,
-				 inst->offset);
+   brw_oword_block_write_scratch(p, brw_message_reg(inst->base_mrf),
+                                 inst->mlen, inst->offset);
 }
 
 void
@@ -765,8 +765,8 @@ fs_generator::generate_unspill(fs_inst *inst, struct brw_reg dst)
 {
    assert(inst->mlen != 0);
 
-   brw_oword_block_read_scratch(p, dst, brw_message_reg(inst->base_mrf), 1,
-				inst->offset);
+   brw_oword_block_read_scratch(p, dst, brw_message_reg(inst->base_mrf),
+                                dispatch_width / 8, inst->offset);
 }
 
 void
diff --git a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
index 35dae84..64fb78b 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
@@ -547,15 +547,12 @@ fs_visitor::emit_unspill(fs_inst *inst, fs_reg dst, uint32_t spill_offset,
       unspill_inst->ir = inst->ir;
       unspill_inst->annotation = inst->annotation;
 
-      /* Choose a MRF that won't conflict with an MRF that's live across the
-       * spill.  Nothing else will make it up to MRF 14/15.
-       */
       unspill_inst->base_mrf = 14;
       unspill_inst->mlen = 1; /* header contains offset */
       inst->insert_before(unspill_inst);
 
       dst.reg_offset++;
-      spill_offset += REG_SIZE;
+      spill_offset += dispatch_width * sizeof(float);
    }
 }
 
@@ -639,10 +636,10 @@ fs_visitor::choose_spill_reg(struct ra_graph *g)
 void
 fs_visitor::spill_reg(int spill_reg)
 {
+   int reg_size = dispatch_width * sizeof(float);
    int size = virtual_grf_sizes[spill_reg];
    unsigned int spill_offset = c->last_scratch;
    assert(ALIGN(spill_offset, 16) == spill_offset); /* oword read/write req. */
-   c->last_scratch += size * REG_SIZE;
    int spill_base_mrf = dispatch_width > 8 ? 13 : 14;
 
    /* Spills may use MRFs 13-15 in the SIMD16 case.  Our texturing is done
@@ -666,6 +663,8 @@ fs_visitor::spill_reg(int spill_reg)
       spilled_any_registers = true;
    }
 
+   c->last_scratch += size * reg_size;
+
    /* Generate spill/unspill instructions for the objects being
     * spilled.  Right now, we spill or unspill the whole thing to a
     * virtual grf of the same size.  For most instructions, though, we
@@ -683,7 +682,7 @@ fs_visitor::spill_reg(int spill_reg)
             inst->src[i].reg_offset = 0;
 
             emit_unspill(inst, inst->src[i],
-                         spill_offset + REG_SIZE * inst->src[i].reg_offset,
+                         spill_offset + reg_size * inst->src[i].reg_offset,
                          regs_read);
 	 }
       }
@@ -691,7 +690,7 @@ fs_visitor::spill_reg(int spill_reg)
       if (inst->dst.file == GRF &&
 	  inst->dst.reg == spill_reg) {
          int subset_spill_offset = (spill_offset +
-                                    REG_SIZE * inst->dst.reg_offset);
+                                    reg_size * inst->dst.reg_offset);
          inst->dst.reg = virtual_grf_alloc(inst->regs_written);
          inst->dst.reg_offset = 0;
 
@@ -714,11 +713,11 @@ fs_visitor::spill_reg(int spill_reg)
 	    fs_inst *spill_inst = new(mem_ctx) fs_inst(FS_OPCODE_SPILL,
 						       reg_null_f, spill_src);
 	    spill_src.reg_offset++;
-	    spill_inst->offset = subset_spill_offset + chan * REG_SIZE;
+	    spill_inst->offset = subset_spill_offset + chan * reg_size;
 	    spill_inst->ir = inst->ir;
 	    spill_inst->annotation = inst->annotation;
-	    spill_inst->base_mrf = 14;
-	    spill_inst->mlen = 2; /* header, value */
+	    spill_inst->mlen = 1 + dispatch_width / 8; /* header, value */
+	    spill_inst->base_mrf = spill_base_mrf;
 	    inst->insert_after(spill_inst);
 	 }
       }




More information about the mesa-commit mailing list