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 <sigles...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev