From fba020e5af49d9d9a2c6e4d4b79115ed1e74a127 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 1 Sep 2016 13:10:36 -0700 Subject: [PATCH] i965/vec4: Replace dst/src_reg::reg_offset with dst/src_reg::offset expressed in bytes. The dst/src_reg::offset field in byte units introduced in the previous patch is a more straightforward alternative to an offset representation split between ::reg_offset and ::subreg_offset fields. The split representation makes it too easy to forget about one of the offsets while dealing with the other, which has led to multiple FS back-end bugs in the past. To make the matter worse the unit reg_offset was expressed in was rather inconsistent, for uniforms it would be expressed in either 4B or 16B units depending on the back-end, and for most other things it would be expressed in 32B units. This encodes reg_offset as a new offset field expressed consistently in byte units. Each rvalue reference of reg_offset in existing code like 'x = r.reg_offset' is rewritten to 'x = r.offset / reg_unit', and each lvalue reference like 'r.reg_offset = x' is rewritten to 'r.offset = r.offset % reg_unit + x * reg_unit'. Because the change affects a lot of places and is rather non-trivial to verify due to the inconsistent value of reg_unit, I've tried to avoid making any additional changes other than applying the rewrite rule above in order to keep the patch as simple as possible, sometimes at the cost of introducing obvious stupidity (e.g. algebraic expressions that could be simplified given some knowledge of the context) -- I'll clean those up later on in a second pass. v2: Fix division by the wrong reg_unit in the UNIFORM case of convert_to_hw_regs(). (Iago) Reviewed-by: Iago Toral Quiroga --- src/mesa/drivers/dri/i965/brw_ir_vec4.h | 4 +- src/mesa/drivers/dri/i965/brw_vec4.cpp | 61 ++++++++++--------- .../dri/i965/brw_vec4_cmod_propagation.cpp | 2 +- .../dri/i965/brw_vec4_copy_propagation.cpp | 4 +- .../dri/i965/brw_vec4_live_variables.h | 8 +-- src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 2 +- .../dri/i965/brw_vec4_reg_allocate.cpp | 4 +- .../drivers/dri/i965/brw_vec4_visitor.cpp | 14 ++--- 8 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_ir_vec4.h b/src/mesa/drivers/dri/i965/brw_ir_vec4.h index 3813bb8d0ea..4f49428ef3f 100644 --- a/src/mesa/drivers/dri/i965/brw_ir_vec4.h +++ b/src/mesa/drivers/dri/i965/brw_ir_vec4.h @@ -65,7 +65,7 @@ offset(src_reg reg, unsigned delta) { assert(delta == 0 || (reg.file != ARF && reg.file != FIXED_GRF && reg.file != IMM)); - reg.reg_offset += delta; + reg.offset += delta * (reg.file == UNIFORM ? 16 : REG_SIZE); return reg; } @@ -134,7 +134,7 @@ offset(dst_reg reg, unsigned delta) { assert(delta == 0 || (reg.file != ARF && reg.file != FIXED_GRF && reg.file != IMM)); - reg.reg_offset += delta; + reg.offset += delta * (reg.file == UNIFORM ? 16 : REG_SIZE); return reg; } diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp index d52fdc06edd..de5b5d6c838 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp @@ -68,7 +68,7 @@ src_reg::src_reg() src_reg::src_reg(struct ::brw_reg reg) : backend_reg(reg) { - this->reg_offset = 0; + this->offset = 0; this->reladdr = NULL; } @@ -125,7 +125,7 @@ dst_reg::dst_reg(enum brw_reg_file file, int nr, brw_reg_type type, dst_reg::dst_reg(struct ::brw_reg reg) : backend_reg(reg) { - this->reg_offset = 0; + this->offset = 0; this->reladdr = NULL; } @@ -395,7 +395,7 @@ vec4_visitor::opt_vector_float() * sequence. Combine anything we've accumulated so far. */ if (last_reg != inst->dst.nr || - last_reg_offset != inst->dst.reg_offset || + last_reg_offset != inst->dst.offset / REG_SIZE || last_reg_file != inst->dst.file || (vf > 0 && dest_type != need_type)) { @@ -439,7 +439,7 @@ vec4_visitor::opt_vector_float() imm_inst[inst_count++] = inst; last_reg = inst->dst.nr; - last_reg_offset = inst->dst.reg_offset; + last_reg_offset = inst->dst.offset / REG_SIZE; last_reg_file = inst->dst.file; if (vf > 0) dest_type = need_type; @@ -539,8 +539,8 @@ vec4_visitor::split_uniform_registers() assert(!inst->src[i].reladdr); - inst->src[i].nr += inst->src[i].reg_offset; - inst->src[i].reg_offset = 0; + inst->src[i].nr += inst->src[i].offset / 16; + inst->src[i].offset %= 16; } } } @@ -857,7 +857,7 @@ vec4_visitor::move_push_constants_to_pull_constants() inst->src[i].file = temp.file; inst->src[i].nr = temp.nr; - inst->src[i].reg_offset = temp.reg_offset; + inst->src[i].offset %= 16; inst->src[i].reladdr = NULL; } } @@ -948,7 +948,7 @@ vec4_visitor::opt_set_dependency_control() * on, don't do dependency control across the read. */ for (int i = 0; i < 3; i++) { - int reg = inst->src[i].nr + inst->src[i].reg_offset; + int reg = inst->src[i].nr + inst->src[i].offset / REG_SIZE; if (inst->src[i].file == VGRF) { last_grf_write[reg] = NULL; } else if (inst->src[i].file == FIXED_GRF) { @@ -967,7 +967,7 @@ vec4_visitor::opt_set_dependency_control() /* Now, see if we can do dependency control for this instruction * against a previous one writing to its destination. */ - int reg = inst->dst.nr + inst->dst.reg_offset; + int reg = inst->dst.nr + inst->dst.offset / REG_SIZE; if (inst->dst.file == VGRF || inst->dst.file == FIXED_GRF) { if (last_grf_write[reg] && !(inst->dst.writemask & grf_channels_written[reg])) { @@ -1086,7 +1086,7 @@ vec4_visitor::opt_register_coalesce() /* Remove no-op MOVs */ if (inst->dst.file == inst->src[0].file && inst->dst.nr == inst->src[0].nr && - inst->dst.reg_offset == inst->src[0].reg_offset) { + inst->dst.offset / REG_SIZE == inst->src[0].offset / REG_SIZE) { bool is_nop_mov = true; for (unsigned c = 0; c < 4; c++) { @@ -1232,12 +1232,14 @@ vec4_visitor::opt_register_coalesce() while (scan_inst != inst) { if (scan_inst->dst.file == VGRF && scan_inst->dst.nr == inst->src[0].nr && - scan_inst->dst.reg_offset == inst->src[0].reg_offset) { + scan_inst->dst.offset / REG_SIZE == + inst->src[0].offset / REG_SIZE) { scan_inst->reswizzle(inst->dst.writemask, inst->src[0].swizzle); scan_inst->dst.file = inst->dst.file; scan_inst->dst.nr = inst->dst.nr; - scan_inst->dst.reg_offset = inst->dst.reg_offset; + scan_inst->dst.offset = scan_inst->dst.offset % REG_SIZE + + ROUND_DOWN_TO(inst->dst.offset, REG_SIZE); if (inst->saturate && inst->dst.type != scan_inst->dst.type) { /* If we have reached this point, scan_inst is a non @@ -1360,17 +1362,17 @@ vec4_visitor::split_virtual_grfs() foreach_block_and_inst(block, vec4_instruction, inst, cfg) { if (inst->dst.file == VGRF && split_grf[inst->dst.nr] && - inst->dst.reg_offset != 0) { + inst->dst.offset / REG_SIZE != 0) { inst->dst.nr = (new_virtual_grf[inst->dst.nr] + - inst->dst.reg_offset - 1); - inst->dst.reg_offset = 0; + inst->dst.offset / REG_SIZE - 1); + inst->dst.offset %= REG_SIZE; } for (int i = 0; i < 3; i++) { if (inst->src[i].file == VGRF && split_grf[inst->src[i].nr] && - inst->src[i].reg_offset != 0) { + inst->src[i].offset / REG_SIZE != 0) { inst->src[i].nr = (new_virtual_grf[inst->src[i].nr] + - inst->src[i].reg_offset - 1); - inst->src[i].reg_offset = 0; + inst->src[i].offset / REG_SIZE - 1); + inst->src[i].offset %= REG_SIZE; } } } @@ -1411,7 +1413,7 @@ vec4_visitor::dump_instruction(backend_instruction *be_inst, FILE *file) switch (inst->dst.file) { case VGRF: - fprintf(file, "vgrf%d.%d", inst->dst.nr, inst->dst.reg_offset); + fprintf(file, "vgrf%d.%d", inst->dst.nr, inst->dst.offset / REG_SIZE); break; case FIXED_GRF: fprintf(file, "g%d", inst->dst.nr); @@ -1534,10 +1536,10 @@ vec4_visitor::dump_instruction(backend_instruction *be_inst, FILE *file) } /* Don't print .0; and only VGRFs have reg_offsets and sizes */ - if (inst->src[i].reg_offset != 0 && + if (inst->src[i].offset / REG_SIZE != 0 && inst->src[i].file == VGRF && alloc.sizes[inst->src[i].nr] != 1) - fprintf(file, ".%d", inst->src[i].reg_offset); + fprintf(file, ".%d", inst->src[i].offset / REG_SIZE); if (inst->src[i].file != IMM) { static const char *chans[4] = {"x", "y", "z", "w"}; @@ -1596,7 +1598,8 @@ vec4_visitor::lower_attributes_to_hw_regs(const int *attribute_map, if (inst->src[i].file != ATTR) continue; - int grf = attribute_map[inst->src[i].nr + inst->src[i].reg_offset]; + int grf = attribute_map[inst->src[i].nr + + inst->src[i].offset / REG_SIZE]; /* All attributes used in the shader need to have been assigned a * hardware register by the caller @@ -1808,7 +1811,7 @@ vec4_visitor::emit_shader_time_write(int shader_time_subindex, src_reg value) dst_reg offset = dst; dst_reg time = dst; - time.reg_offset++; + time.offset += REG_SIZE; offset.type = BRW_REGISTER_TYPE_UD; int index = shader_time_index * 3 + shader_time_subindex; @@ -1831,7 +1834,7 @@ vec4_visitor::convert_to_hw_regs() struct brw_reg reg; switch (src.file) { case VGRF: - reg = brw_vec8_grf(src.nr + src.reg_offset, 0); + reg = brw_vec8_grf(src.nr + src.offset / REG_SIZE, 0); reg.type = src.type; reg.swizzle = src.swizzle; reg.abs = src.abs; @@ -1840,8 +1843,8 @@ vec4_visitor::convert_to_hw_regs() case UNIFORM: reg = stride(brw_vec4_grf(prog_data->base.dispatch_grf_start_reg + - (src.nr + src.reg_offset) / 2, - ((src.nr + src.reg_offset) % 2) * 4), + (src.nr + src.offset / 16) / 2, + ((src.nr + src.offset / 16) % 2) * 4), 0, 4, 1); reg.type = src.type; reg.swizzle = src.swizzle; @@ -1887,14 +1890,14 @@ vec4_visitor::convert_to_hw_regs() switch (inst->dst.file) { case VGRF: - reg = brw_vec8_grf(dst.nr + dst.reg_offset, 0); + reg = brw_vec8_grf(dst.nr + dst.offset / REG_SIZE, 0); reg.type = dst.type; reg.writemask = dst.writemask; break; case MRF: - assert(((dst.nr + dst.reg_offset) & ~BRW_MRF_COMPR4) < BRW_MAX_MRF(devinfo->gen)); - reg = brw_message_reg(dst.nr + dst.reg_offset); + assert(((dst.nr + dst.offset / REG_SIZE) & ~BRW_MRF_COMPR4) < BRW_MAX_MRF(devinfo->gen)); + reg = brw_message_reg(dst.nr + dst.offset / REG_SIZE); reg.type = dst.type; reg.writemask = dst.writemask; break; diff --git a/src/mesa/drivers/dri/i965/brw_vec4_cmod_propagation.cpp b/src/mesa/drivers/dri/i965/brw_vec4_cmod_propagation.cpp index c376bebbe8e..17f9e15c5a2 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_cmod_propagation.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_cmod_propagation.cpp @@ -71,7 +71,7 @@ opt_cmod_propagation_local(bblock_t *block) if (inst->src[0].in_range(scan_inst->dst, scan_inst->regs_written)) { if ((scan_inst->predicate && scan_inst->opcode != BRW_OPCODE_SEL) || - scan_inst->dst.reg_offset != inst->src[0].reg_offset || + scan_inst->dst.offset / REG_SIZE != inst->src[0].offset / REG_SIZE || (scan_inst->dst.writemask != WRITEMASK_X && scan_inst->dst.writemask != WRITEMASK_XYZW) || (scan_inst->dst.writemask == WRITEMASK_XYZW && diff --git a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp index cc0e44cc8e1..1f77d229a33 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp @@ -441,7 +441,7 @@ vec4_visitor::opt_copy_propagation(bool do_constant_prop) continue; const unsigned reg = (alloc.offsets[inst->src[i].nr] + - inst->src[i].reg_offset); + inst->src[i].offset / REG_SIZE); const copy_entry &entry = entries[reg]; if (do_constant_prop && try_constant_propagate(devinfo, inst, i, &entry)) @@ -453,7 +453,7 @@ vec4_visitor::opt_copy_propagation(bool do_constant_prop) /* Track available source registers. */ if (inst->dst.file == VGRF) { const int reg = - alloc.offsets[inst->dst.nr] + inst->dst.reg_offset; + alloc.offsets[inst->dst.nr] + inst->dst.offset / REG_SIZE; /* Update our destination's current channel values. For a direct copy, * the value is the newly propagated source. Otherwise, we don't know diff --git a/src/mesa/drivers/dri/i965/brw_vec4_live_variables.h b/src/mesa/drivers/dri/i965/brw_vec4_live_variables.h index 12d281eb245..2fbcaa1228a 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_live_variables.h +++ b/src/mesa/drivers/dri/i965/brw_vec4_live_variables.h @@ -83,8 +83,8 @@ var_from_reg(const simple_allocator &alloc, const src_reg ®, unsigned c = 0) { assert(reg.file == VGRF && reg.nr < alloc.count && - reg.reg_offset < alloc.sizes[reg.nr] && c < 4); - return (4 * (alloc.offsets[reg.nr] + reg.reg_offset) + + reg.offset / REG_SIZE < alloc.sizes[reg.nr] && c < 4); + return (4 * (alloc.offsets[reg.nr] + reg.offset / REG_SIZE) + BRW_GET_SWZ(reg.swizzle, c)); } @@ -93,8 +93,8 @@ var_from_reg(const simple_allocator &alloc, const dst_reg ®, unsigned c = 0) { assert(reg.file == VGRF && reg.nr < alloc.count && - reg.reg_offset < alloc.sizes[reg.nr] && c < 4); - return 4 * (alloc.offsets[reg.nr] + reg.reg_offset) + c; + reg.offset / REG_SIZE < alloc.sizes[reg.nr] && c < 4); + return 4 * (alloc.offsets[reg.nr] + reg.offset / REG_SIZE) + c; } } /* namespace brw */ diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp index c29411847e5..60f87834b9f 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp @@ -715,7 +715,7 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr) assert(const_offset->u32[0] % 4 == 0); unsigned offset = const_offset->u32[0] + shift * 4; - src.reg_offset = offset / 16; + src.offset = ROUND_DOWN_TO(offset, 16); shift = (offset % 16) / 4; src.swizzle += BRW_SWIZZLE4(shift, shift, shift, shift); diff --git a/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp index afc326612a2..947bb492bda 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_reg_allocate.cpp @@ -33,8 +33,8 @@ static void assign(unsigned int *reg_hw_locations, backend_reg *reg) { if (reg->file == VGRF) { - reg->nr = reg_hw_locations[reg->nr] + reg->reg_offset; - reg->reg_offset = 0; + reg->nr = reg_hw_locations[reg->nr] + reg->offset / REG_SIZE; + reg->offset %= REG_SIZE; } } diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp index 22991e911ad..b5204e889f5 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -1481,7 +1481,7 @@ vec4_visitor::emit_scratch_read(bblock_t *block, vec4_instruction *inst, dst_reg temp, src_reg orig_src, int base_offset) { - int reg_offset = base_offset + orig_src.reg_offset; + int reg_offset = base_offset + orig_src.offset / REG_SIZE; src_reg index = get_scratch_offset(block, inst, orig_src.reladdr, reg_offset); @@ -1498,7 +1498,7 @@ void vec4_visitor::emit_scratch_write(bblock_t *block, vec4_instruction *inst, int base_offset) { - int reg_offset = base_offset + inst->dst.reg_offset; + int reg_offset = base_offset + inst->dst.offset / REG_SIZE; src_reg index = get_scratch_offset(block, inst, inst->dst.reladdr, reg_offset); @@ -1523,7 +1523,7 @@ vec4_visitor::emit_scratch_write(bblock_t *block, vec4_instruction *inst, inst->dst.file = temp.file; inst->dst.nr = temp.nr; - inst->dst.reg_offset = temp.reg_offset; + inst->dst.offset %= REG_SIZE; inst->dst.reladdr = NULL; } @@ -1553,7 +1553,7 @@ vec4_visitor::emit_resolve_reladdr(int scratch_loc[], bblock_t *block, dst_reg temp = dst_reg(this, glsl_type::vec4_type); emit_scratch_read(block, inst, temp, src, scratch_loc[src.nr]); src.nr = temp.nr; - src.reg_offset = temp.reg_offset; + src.offset %= REG_SIZE; src.reladdr = NULL; } @@ -1649,7 +1649,7 @@ vec4_visitor::emit_pull_constant_load(bblock_t *block, vec4_instruction *inst, dst_reg temp, src_reg orig_src, int base_offset, src_reg indirect) { - int reg_offset = base_offset + orig_src.reg_offset; + int reg_offset = base_offset + orig_src.offset / 16; const unsigned index = prog_data->base.binding_table.pull_constants_start; src_reg offset; @@ -1710,7 +1710,7 @@ vec4_visitor::move_uniform_array_access_to_pull_constants() inst->src[0].file != UNIFORM) continue; - int uniform_nr = inst->src[0].nr + inst->src[0].reg_offset; + int uniform_nr = inst->src[0].nr + inst->src[0].offset / 16; for (unsigned j = 0; j < DIV_ROUND_UP(inst->src[2].ud, 16); j++) pull_constant_loc[uniform_nr + j] = 0; @@ -1740,7 +1740,7 @@ vec4_visitor::move_uniform_array_access_to_pull_constants() inst->src[0].file != UNIFORM) continue; - int uniform_nr = inst->src[0].nr + inst->src[0].reg_offset; + int uniform_nr = inst->src[0].nr + inst->src[0].offset / 16; assert(inst->src[0].swizzle == BRW_SWIZZLE_NOOP); -- 2.30.2