[Mesa-dev] [PATCH 02/57] i965/vec4: Replace dst/src_reg::reg_offset with dst/src_reg::offset expressed in bytes.

Francisco Jerez currojerez at riseup.net
Thu Sep 8 01:48:29 UTC 2016


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.
---
 src/mesa/drivers/dri/i965/brw_ir_vec4.h            |  4 +-
 src/mesa/drivers/dri/i965/brw_vec4.cpp             | 61 ++++++++++++----------
 .../drivers/dri/i965/brw_vec4_cmod_propagation.cpp |  2 +-
 .../drivers/dri/i965/brw_vec4_copy_propagation.cpp |  4 +-
 .../drivers/dri/i965/brw_vec4_live_variables.h     |  8 +--
 src/mesa/drivers/dri/i965/brw_vec4_nir.cpp         |  2 +-
 .../drivers/dri/i965/brw_vec4_reg_allocate.cpp     |  4 +-
 src/mesa/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 3813bb8..4f49428 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 d52fdc0..dd058db 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 / 4) / 2,
+                                      ((src.nr + src.offset / 4) % 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 c376beb..17f9e15 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 cc0e44c..1f77d22 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 12d281e..2fbcaa1 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 &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 &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 c294118..60f8783 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 afc3266..947bb49 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 22991e9..b5204e8 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.9.0



More information about the mesa-dev mailing list