[Mesa-dev] [PATCH 2/3] i965/fs: Prepare register spilling for reads of more than 1 reg.

Kenneth Graunke kenneth at whitecape.org
Thu Oct 10 23:10:24 CEST 2013


On 10/09/2013 09:38 PM, Eric Anholt wrote:
> When we introduce texture-from-GRF, we'll have instructions where a src
> means more than one virtual grf is being read.  Rearrange things to allow
> src accesses to unspill like partial dst accesses do (which already had to
> do reading more than one vgrf).
> ---
>  src/mesa/drivers/dri/i965/brw_fs.h                |  3 +-
>  src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp | 47 +++++++++++++----------
>  2 files changed, 29 insertions(+), 21 deletions(-)
> 
> diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
> index 360dbad..0ca903d 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs.h
> +++ b/src/mesa/drivers/dri/i965/brw_fs.h
> @@ -354,7 +354,8 @@ public:
>     void try_replace_with_sel();
>     void emit_bool_to_cond_code(ir_rvalue *condition);
>     void emit_if_gen6(ir_if *ir);
> -   void emit_unspill(fs_inst *inst, fs_reg reg, uint32_t spill_offset);
> +   void emit_unspill(fs_inst *inst, fs_reg reg, uint32_t spill_offset,
> +                     int count);
>  
>     void emit_fragment_program_code();
>     void setup_fp_regs();
> 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 ae239ed..1aab0b1 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
> @@ -511,19 +511,25 @@ fs_visitor::assign_regs()
>  }
>  
>  void
> -fs_visitor::emit_unspill(fs_inst *inst, fs_reg dst, uint32_t spill_offset)
> +fs_visitor::emit_unspill(fs_inst *inst, fs_reg dst, uint32_t spill_offset,
> +                         int count)
>  {
> -   fs_inst *unspill_inst = new(mem_ctx) fs_inst(FS_OPCODE_UNSPILL, dst);
> -   unspill_inst->offset = spill_offset;
> -   unspill_inst->ir = inst->ir;
> -   unspill_inst->annotation = inst->annotation;
> +   for (int i = 0; i < count; i++) {
> +      fs_inst *unspill_inst = new(mem_ctx) fs_inst(FS_OPCODE_UNSPILL, dst);
> +      unspill_inst->offset = 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);
>  
> -   /* 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;
> +   }
>  }
>  
>  int
> @@ -622,9 +628,14 @@ fs_visitor::spill_reg(int spill_reg)
>        for (unsigned int i = 0; i < 3; i++) {
>  	 if (inst->src[i].file == GRF &&
>  	     inst->src[i].reg == spill_reg) {
> -	    inst->src[i].reg = virtual_grf_alloc(1);
> -	    emit_unspill(inst, inst->src[i],
> -                         spill_offset + REG_SIZE * inst->src[i].reg_offset);
> +            int regs_read = inst->regs_read(this, i);

Doesn't compile.  You introduce fs_inst::regs_read() in the next patch.

Fix however you like. :)  Assuming you do, all three patches are:
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

and I'm happy to have them pushed any time.

> +
> +            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);
>  	 }
>        }
>  
> @@ -640,12 +651,8 @@ fs_visitor::spill_reg(int spill_reg)
>            * since we write back out all of the regs_written().
>  	  */
>  	 if (inst->predicate || inst->force_uncompressed || inst->force_sechalf) {
> -            fs_reg unspill_reg = inst->dst;
> -            for (int chan = 0; chan < inst->regs_written; chan++) {
> -               emit_unspill(inst, unspill_reg,
> -                            subset_spill_offset + REG_SIZE * chan);
> -               unspill_reg.reg_offset++;
> -            }
> +            emit_unspill(inst, inst->dst, subset_spill_offset,
> +                         inst->regs_written);
>  	 }
>  
>  	 fs_reg spill_src = inst->dst;
> 



More information about the mesa-dev mailing list