diff --git a/src/intel/compiler/brw_fs_lower_regioning.cpp b/src/intel/compiler/brw_fs_lower_regioning.cpp index 89f3d20171a..e0a10e17cde 100644 --- a/src/intel/compiler/brw_fs_lower_regioning.cpp +++ b/src/intel/compiler/brw_fs_lower_regioning.cpp @@ -58,9 +58,8 @@ namespace { return MAX2(brw_type_size_bytes(inst->dst.type), byte_stride(inst->dst)); - } else if (has_subdword_integer_region_restriction(devinfo, inst) && - brw_type_size_bytes(inst->src[i].type) < 4 && - byte_stride(inst->src[i]) >= 4) { + } else if (has_subdword_integer_region_restriction(devinfo, inst, + &inst->src[i], 1)) { /* Use a stride of 32bits if possible, since that will guarantee that * the copy emitted to lower this region won't be affected by the * sub-dword integer region restrictions. This may not be possible @@ -85,9 +84,8 @@ namespace { if (has_dst_aligned_region_restriction(devinfo, inst)) { return reg_offset(inst->dst) % (reg_unit(devinfo) * REG_SIZE); - } else if (has_subdword_integer_region_restriction(devinfo, inst) && - brw_type_size_bytes(inst->src[i].type) < 4 && - byte_stride(inst->src[i]) >= 4) { + } else if (has_subdword_integer_region_restriction(devinfo, inst, + &inst->src[i], 1)) { const unsigned dst_byte_stride = MAX2(byte_stride(inst->dst), brw_type_size_bytes(inst->dst.type)); const unsigned src_byte_stride = required_src_byte_stride(devinfo, inst, i); @@ -650,9 +648,16 @@ namespace { subscript(inst->dst, raw_type, j)); } - for (unsigned j = 0; j < n; j++) - ibld.at(block, inst->next).MOV(subscript(inst->dst, raw_type, j), - subscript(tmp, raw_type, j)); + for (unsigned j = 0; j < n; j++) { + fs_inst *jnst = ibld.at(block, inst->next).MOV(subscript(inst->dst, raw_type, j), + subscript(tmp, raw_type, j)); + if (has_subdword_integer_region_restriction(v->devinfo, jnst)) { + /* The copy isn't guaranteed to comply with all subdword integer + * regioning restrictions in some cases. Lower it recursively. + */ + lower_instruction(v, block, jnst); + } + } /* If the destination was an accumulator, after lowering it will be a * GRF. Clear writes_accumulator for the instruction. diff --git a/src/intel/compiler/brw_ir_fs.h b/src/intel/compiler/brw_ir_fs.h index b0120178503..997927c9ae9 100644 --- a/src/intel/compiler/brw_ir_fs.h +++ b/src/intel/compiler/brw_ir_fs.h @@ -445,8 +445,12 @@ has_subdword_integer_region_restriction(const intel_device_info *devinfo, brw_type_size_bytes(inst->dst.type)) < 4) { for (unsigned i = 0; i < num_srcs; i++) { if (brw_type_is_int(srcs[i].type) && - brw_type_size_bytes(srcs[i].type) < 4 && - byte_stride(srcs[i]) >= 4) + ((brw_type_size_bytes(srcs[i].type) < 4 && + byte_stride(srcs[i]) >= 4) || + (MAX2(byte_stride(inst->dst), + brw_type_size_bytes(inst->dst.type)) == 1 && + brw_type_size_bytes(srcs[i].type) == 1 && + byte_stride(srcs[i]) >= 2))) return true; } }