From: Francisco Jerez Date: Tue, 10 May 2016 23:01:56 +0000 (-0700) Subject: i965/fs: Simplify and fix register offset calculation of try_copy_propagate(). X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0fb19806c069cbf34aaf02e77f5ae37a9e4cf3b0;p=mesa.git i965/fs: Simplify and fix register offset calculation of try_copy_propagate(). try_copy_propagate() was special-casing UNIFORM registers (the BAD_FILE, ARF and FIXED_GRF cases are dead, see the assertion at the top of the function) and then failing to take into account the possibility of the instruction reading from a non-zero offset of the destination of the copy. The VGRF/ATTR handling takes it into account correctly, and there is no reason we couldn't use the exact same logic for the UNIFORM file aside from the fact that uniforms represent reg_offset in different units. We can work around that easily by defining an additional constant with the right unit reg_offset is expressed in. Reviewed-by: Kenneth Graunke --- diff --git a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp index b9ff031bf82..bfaeaaa8452 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp @@ -446,27 +446,6 @@ fs_visitor::try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry) inst->src[arg].stride *= entry->src.stride; inst->saturate = inst->saturate || entry->saturate; - switch (entry->src.file) { - case UNIFORM: - case BAD_FILE: - case ARF: - case FIXED_GRF: - inst->src[arg].reg_offset = entry->src.reg_offset; - inst->src[arg].subreg_offset = entry->src.subreg_offset; - break; - case ATTR: - case VGRF: - { - /* In this case, we'll just leave the width alone. The source - * register could have different widths depending on how it is - * being used. For instance, if only half of the register was - * used then we want to preserve that and continue to only use - * half. - * - * Also, we have to deal with mapping parts of vgrfs to other - * parts of vgrfs so we have to do some reg_offset magic. - */ - /* Compute the offset of inst->src[arg] relative to entry->dst */ const unsigned rel_offset = (inst->src[arg].reg_offset - entry->dst.reg_offset) * REG_SIZE + @@ -479,21 +458,20 @@ fs_visitor::try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry) const unsigned component = rel_offset / type_sz(entry->dst.type); const unsigned suboffset = rel_offset % type_sz(entry->dst.type); + /* Account for the inconsistent units reg_offset is expressed in. + * FINISHME -- Make the units of reg_offset consistent (e.g. bytes?) + * for all register files. + */ + const unsigned reg_size = (entry->src.file == UNIFORM ? 4 : REG_SIZE); + /* Calculate the byte offset at the origin of the copy of the given * component and suboffset. */ const unsigned offset = suboffset + component * entry->src.stride * type_sz(entry->src.type) + - entry->src.reg_offset * REG_SIZE + entry->src.subreg_offset; - inst->src[arg].reg_offset = offset / REG_SIZE; - inst->src[arg].subreg_offset = offset % REG_SIZE; - } - break; - - case MRF: - case IMM: - unreachable("not reached"); - } + entry->src.reg_offset * reg_size + entry->src.subreg_offset; + inst->src[arg].reg_offset = offset / reg_size; + inst->src[arg].subreg_offset = offset % reg_size; if (has_source_modifiers) { if (entry->dst.type != inst->src[arg].type) {