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 <[email protected]> --- 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 _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
