[Mesa-dev] [PATCH 10/22] i965/fs: indirect addressing with doubles is not supported in IVB/VLV

Samuel Iglesias Gonsálvez siglesias at igalia.com
Thu Jan 5 13:07:30 UTC 2017


It is tested empirically that IVB/VLV 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 duplicate the stride, since the
hardware will do it internally.

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

diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
index 1e7eccc..095a744 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp
@@ -444,13 +444,22 @@ fs_generator::generate_mov_indirect(fs_inst *inst,
       /* 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/Valleyview, when it operates with DF operands, we
+          * cannot duplicate 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 2ed843b..06fe230 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
@@ -3984,17 +3984,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.9.3



More information about the mesa-dev mailing list