diff --git a/src/intel/compiler/brw_fs_generator.cpp b/src/intel/compiler/brw_fs_generator.cpp index cfc96570cca..936da06576e 100644 --- a/src/intel/compiler/brw_fs_generator.cpp +++ b/src/intel/compiler/brw_fs_generator.cpp @@ -606,7 +606,8 @@ fs_generator::generate_shuffle(fs_inst *inst, /* Ivy bridge has some strange behavior that makes this a real pain to * implement for 64-bit values so we just don't bother. */ - assert(devinfo->verx10 >= 75 || type_sz(src.type) <= 4); + assert((devinfo->verx10 >= 75 && devinfo->has_64bit_float) || + type_sz(src.type) <= 4); /* Because we're using the address register, we're limited to 8-wide * execution on gfx7. On gfx8, we're limited to 16-wide by the address @@ -632,15 +633,7 @@ fs_generator::generate_shuffle(fs_inst *inst, const unsigned i = idx.file == BRW_IMMEDIATE_VALUE ? idx.ud : 0; struct brw_reg group_src = stride(suboffset(src, i), 0, 1, 0); struct brw_reg group_dst = suboffset(dst, group << (dst.hstride - 1)); - if (type_sz(src.type) > 4 && !devinfo->has_64bit_float) { - brw_MOV(p, subscript(group_dst, BRW_REGISTER_TYPE_UD, 0), - subscript(group_src, BRW_REGISTER_TYPE_UD, 0)); - brw_set_default_swsb(p, tgl_swsb_null()); - brw_MOV(p, subscript(group_dst, BRW_REGISTER_TYPE_UD, 1), - subscript(group_src, BRW_REGISTER_TYPE_UD, 1)); - } else { - brw_MOV(p, group_dst, group_src); - } + brw_MOV(p, group_dst, group_src); } else { /* We use VxH indirect addressing, clobbering a0.0 through a0.7. */ struct brw_reg addr = vec8(brw_address_reg(0)); @@ -712,40 +705,8 @@ fs_generator::generate_shuffle(fs_inst *inst, /* Add on the register start offset */ brw_ADD(p, addr, addr, brw_imm_uw(src_start_offset)); - - if (type_sz(src.type) > 4 && - ((devinfo->verx10 == 70) || - devinfo->platform == INTEL_PLATFORM_CHV || intel_device_info_is_9lp(devinfo) || - !devinfo->has_64bit_float)) { - /* IVB has an issue (which we found empirically) where it reads - * two address register components per channel for indirectly - * addressed 64-bit sources. - * - * From the Cherryview PRM Vol 7. "Register Region Restrictions": - * - * "When source or destination datatype is 64b or operation is - * integer DWord multiply, indirect addressing must not be - * used." - * - * To work around both of these, we do two integer MOVs insead of - * one 64-bit MOV. Because no double value should ever cross a - * register boundary, it's safe to use the immediate offset in the - * indirect here to handle adding 4 bytes to the offset and avoid - * the extra ADD to the register file. - */ - struct brw_reg gdst = suboffset(dst, group); - struct brw_reg dst_d = retype(spread(gdst, 2), - BRW_REGISTER_TYPE_D); - assert(dst.hstride == 1); - brw_MOV(p, dst_d, - retype(brw_VxH_indirect(0, 0), BRW_REGISTER_TYPE_D)); - brw_set_default_swsb(p, tgl_swsb_null()); - brw_MOV(p, byte_offset(dst_d, 4), - retype(brw_VxH_indirect(0, 4), BRW_REGISTER_TYPE_D)); - } else { - brw_MOV(p, suboffset(dst, group << (dst.hstride - 1)), - retype(brw_VxH_indirect(0, 0), src.type)); - } + brw_MOV(p, suboffset(dst, group << (dst.hstride - 1)), + retype(brw_VxH_indirect(0, 0), src.type)); } brw_set_default_swsb(p, tgl_swsb_null()); diff --git a/src/intel/compiler/brw_fs_lower_regioning.cpp b/src/intel/compiler/brw_fs_lower_regioning.cpp index b5eed86b6fa..ff418283458 100644 --- a/src/intel/compiler/brw_fs_lower_regioning.cpp +++ b/src/intel/compiler/brw_fs_lower_regioning.cpp @@ -127,9 +127,33 @@ namespace { required_exec_type(const intel_device_info *devinfo, const fs_inst *inst) { const brw_reg_type t = get_exec_type(inst); + const bool has_64bit = brw_reg_type_is_floating_point(t) ? + devinfo->has_64bit_float : devinfo->has_64bit_int; switch (inst->opcode) { case SHADER_OPCODE_SHUFFLE: + /* IVB has an issue (which we found empirically) where it reads + * two address register components per channel for indirectly + * addressed 64-bit sources. + * + * From the Cherryview PRM Vol 7. "Register Region Restrictions": + * + * "When source or destination datatype is 64b or operation is + * integer DWord multiply, indirect addressing must not be + * used." + * + * Work around both of the above and handle platforms that + * don't support 64-bit types at all. + */ + if ((!has_64bit || devinfo->verx10 == 70 || + devinfo->platform == INTEL_PLATFORM_CHV || + intel_device_info_is_9lp(devinfo)) && type_sz(t) > 4) + return BRW_REGISTER_TYPE_UD; + else if (has_dst_aligned_region_restriction(devinfo, inst)) + return brw_int_type(type_sz(t), false); + else + return t; + case SHADER_OPCODE_QUAD_SWIZZLE: if (has_dst_aligned_region_restriction(devinfo, inst)) return brw_int_type(type_sz(t), false);