--- src/mesa/drivers/dri/i965/brw_fs.cpp | 56 +++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-)
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 444cc32..4d97594 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -2865,10 +2865,44 @@ fs_visitor::lower_load_payload() { bool progress = false; + int vgrf_to_reg[virtual_grf_count]; + int reg_count = 16; /* Leave room for MRF */ + for (int i = 0; i < virtual_grf_count; ++i) { + vgrf_to_reg[i] = reg_count; + reg_count += virtual_grf_sizes[i]; + } + + struct { + bool written:1; /* Whether this register has ever been written */ + bool force_writemask_all:1; + bool force_sechalf:1; + } metadata[reg_count]; + memset(metadata, 0, sizeof(metadata)); + calculate_cfg(); foreach_block_and_inst_safe (block, fs_inst, inst, cfg) { + int dst_reg; + if (inst->dst.file == MRF) { + dst_reg = inst->dst.reg; + } else if (inst->dst.file == GRF) { + dst_reg = vgrf_to_reg[inst->dst.reg]; + } + + if (inst->dst.file == MRF || inst->dst.file == GRF) { + bool force_sechalf = inst->force_sechalf; + bool toggle_sechalf = inst->dst.width == 16 && + type_sz(inst->dst.type) == 4; + for (int i = 0; i < inst->regs_written; ++i) { + metadata[dst_reg + i].written = true; + metadata[dst_reg + i].force_sechalf = force_sechalf; + metadata[dst_reg + i].force_writemask_all = inst->force_writemask_all; + force_sechalf = (toggle_sechalf != force_sechalf); + } + } + if (inst->opcode == SHADER_OPCODE_LOAD_PAYLOAD) { + assert(inst->dst.file == MRF || inst->dst.file == GRF); fs_reg dst = inst->dst; for (int i = 0; i < inst->sources; i++) { @@ -2879,7 +2913,27 @@ fs_visitor::lower_load_payload() /* Do nothing but otherwise increment as normal */ } else { fs_inst *mov = MOV(dst, inst->src[i]); - mov->force_writemask_all = true; + if (inst->src[i].file == GRF) { + int src_reg = vgrf_to_reg[inst->src[i].reg] + + inst->src[i].reg_offset; + mov->force_sechalf = metadata[src_reg].force_sechalf; + mov->force_writemask_all = metadata[src_reg].force_writemask_all; + metadata[dst_reg] = metadata[src_reg]; + if (dst.width * type_sz(dst.type) > 32) { + assert((!metadata[src_reg].written || + !metadata[src_reg].force_sechalf) && + (!metadata[src_reg + 1].written || + metadata[src_reg + 1].force_sechalf)); + metadata[dst_reg + 1] = metadata[src_reg + 1]; + } + } else { + metadata[dst_reg].force_writemask_all = false; + metadata[dst_reg].force_sechalf = false; + if (dst.width == 16) { + metadata[dst_reg + 1].force_writemask_all = false; + metadata[dst_reg + 1].force_sechalf = true; + } + } inst->insert_before(block, mov); } -- 2.1.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev