i965/fs: Fix bogus sub-MRF offset calculation in compute-to-mrf.
authorFrancisco Jerez <currojerez@riseup.net>
Sat, 3 Sep 2016 20:14:28 +0000 (13:14 -0700)
committerFrancisco Jerez <currojerez@riseup.net>
Wed, 14 Sep 2016 21:50:56 +0000 (14:50 -0700)
The 'scan_inst->dst.offset % REG_SIZE' term in the final
'scan_inst->dst.offset' calculation is obviously bogus.  The offset
from the start of the copy destination register 'inst->dst' where the
destination of the generating instruction 'scan_inst' would be written
to (before compute-to-mrf runs) is just the offset of 'scan_inst->dst'
relative to the source of the copy instruction (AKA rel_offset in the
code below).

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
src/mesa/drivers/dri/i965/brw_fs.cpp

index ee196665fce30ca947a972d24f599183fa551d91..ff81e7145b30cc1bd542575acee5eaa781298061 100644 (file)
@@ -2797,15 +2797,15 @@ fs_visitor::compute_to_mrf()
                inst->src[0], scan_inst->dst, DIV_ROUND_UP(scan_inst->size_written,
                                                           REG_SIZE));
 
-            const unsigned rel_offset = (reg_offset(scan_inst->dst) -
-                                         reg_offset(inst->src[0])) / REG_SIZE;
+            const unsigned rel_offset = reg_offset(scan_inst->dst) -
+                                        reg_offset(inst->src[0]);
 
             if (inst->dst.nr & BRW_MRF_COMPR4) {
                /* Apply the same address transformation done by the hardware
                 * for COMPR4 MRF writes.
                 */
-               assert(rel_offset < 2);
-               scan_inst->dst.nr = inst->dst.nr + rel_offset * 4;
+               assert(rel_offset < 2 * REG_SIZE);
+               scan_inst->dst.nr = inst->dst.nr + rel_offset / REG_SIZE * 4;
 
                /* Clear the COMPR4 bit if the generating instruction is not
                 * compressed.
@@ -2817,11 +2817,11 @@ fs_visitor::compute_to_mrf()
                /* Calculate the MRF number the result of this instruction is
                 * ultimately written to.
                 */
-               scan_inst->dst.nr = inst->dst.nr + rel_offset;
+               scan_inst->dst.nr = inst->dst.nr + rel_offset / REG_SIZE;
             }
 
             scan_inst->dst.file = MRF;
-            scan_inst->dst.offset = inst->dst.offset + scan_inst->dst.offset % REG_SIZE;
+            scan_inst->dst.offset = inst->dst.offset + rel_offset % REG_SIZE;
             scan_inst->saturate |= inst->saturate;
             if (!regs_left)
                break;