[Mesa-dev] [PATCH v2 09/20] i965/fs: indirect addressing with doubles is not supported in IVB/BYT

Samuel Iglesias Gonsálvez siglesias at igalia.com
Tue Jan 17 09:49:23 UTC 2017


It is tested empirically that IVB/BYT don't support indirect addressing
with doubles but it is not documented in the PRM.

This patch applies the same solution than for Cherryview/Broxton and
takes into account that we cannot double the stride, since the
hardware will do it internally.

v2:
- Fix assert to take into account Indirect DF MOVs in IVB and HSW.

Signed-off-by: Samuel Iglesias Gonsálvez <siglesias at igalia.com>
---
 src/mesa/drivers/dri/i965/brw_fs_generator.cpp | 27 ++++++++++++++++++--------
 src/mesa/drivers/dri/i965/brw_fs_nir.cpp       | 11 ++++++-----
 2 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
index 487f2e90224..dd6cbab773c 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
@@ -418,18 +418,29 @@ fs_generator::generate_mov_indirect(fs_inst *inst,
       brw_MOV(p, dst, reg);
    } else {
       /* Prior to Broadwell, there are only 8 address registers. */
-      assert(inst->exec_size == 8 || devinfo->gen >= 8);
+      assert(inst->exec_size == 8 || devinfo->gen >= 8 ||
+             (devinfo->gen == 7 && inst->exec_size < 8 &&
+              (type_sz(reg.type) == 8 || type_sz(dst.type) == 8)));
 
       /* We use VxH indirect addressing, clobbering a0.0 through a0.7. */
       struct brw_reg addr = vec8(brw_address_reg(0));
 
-      /* The destination stride of an instruction (in bytes) must be greater
-       * than or equal to the size of the rest of the instruction.  Since the
-       * address register is of type UW, we can't use a D-type instruction.
-       * In order to get around this, re retype to UW and use a stride.
-       */
-      indirect_byte_offset =
-         retype(spread(indirect_byte_offset, 2), BRW_REGISTER_TYPE_UW);
+      if (devinfo->gen != 7 || devinfo->is_haswell || type_sz(reg.type) != 8) {
+         /* The destination stride of an instruction (in bytes) must be greater
+          * than or equal to the size of the rest of the instruction.  Since the
+          * address register is of type UW, we can't use a D-type instruction.
+          * In order to get around this, re retype to UW and use a stride.
+          */
+         indirect_byte_offset =
+            retype(spread(indirect_byte_offset, 2), BRW_REGISTER_TYPE_UW);
+      } else {
+         /* In Ivybridge/Baytrail, when it operates with DF operands, we
+          * cannot double the stride, since the hardware will do it
+          * internally. Tested empirically.
+          */
+         indirect_byte_offset =
+            retype(indirect_byte_offset, BRW_REGISTER_TYPE_UW);
+      }
 
       /* There are a number of reasons why we don't use the base offset here.
        * One reason is that the field is only 9 bits which means we can only
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
index 8f745dff440..85f43b7b144 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -3822,17 +3822,18 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
             (instr->num_components - 1) * type_sz(dest.type);
 
          fs_reg indirect_chv_high_32bit;
-         bool is_chv_bxt_64bit =
-            (devinfo->is_cherryview || devinfo->is_broxton) &&
-            type_sz(dest.type) == 8;
-         if (is_chv_bxt_64bit) {
+         bool is_ivb_byt_chv_bxt_64bit =
+            (devinfo->is_cherryview || devinfo->is_broxton ||
+             devinfo->is_ivybridge || devinfo->is_baytrail) &&
+           type_sz(dest.type) == 8;
+         if (is_ivb_byt_chv_bxt_64bit) {
             indirect_chv_high_32bit = vgrf(glsl_type::uint_type);
             /* Calculate indirect address to read high 32 bits */
             bld.ADD(indirect_chv_high_32bit, indirect, brw_imm_ud(4));
          }
 
          for (unsigned j = 0; j < instr->num_components; j++) {
-            if (!is_chv_bxt_64bit) {
+            if (!is_ivb_byt_chv_bxt_64bit) {
                bld.emit(SHADER_OPCODE_MOV_INDIRECT,
                         offset(dest, bld, j), offset(src, bld, j),
                         indirect, brw_imm_ud(read_size));
-- 
2.11.0



More information about the mesa-dev mailing list