From: Eric Anholt Date: Wed, 16 Oct 2013 19:16:51 +0000 (-0700) Subject: i965/fs: Fix register spilling for 16-wide. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0e20051f54f31f83edba9ac9f8f3a16bb747c698;p=mesa.git 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 --- diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp index ef858370dbb..e16d8748ede 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 35dae843290..64fb78b6bdd 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); } }