From 47b1aac1cf0aefae4df58a60bb7eb26d21e25913 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Nov 2010 15:03:50 +0800 Subject: [PATCH] i965: Improve compute-to-mrf. We were skipping it if the instruction producing the value we were going to compute-to-mrf used its result reg as a source reg. This meant that the typical "write interpolated color to fragment color" or "texture from interpolated texcoord" shader didn't compute-to-MRF. Just don't check for the interference cases until after we've checked if this is the instruction we wanted to compute-to-MRF. Improves nexuiz high-settings performance on my laptop 0.48% +- 0.08% (n=3). --- src/mesa/drivers/dri/i965/brw_fs.cpp | 102 +++++++++++++-------------- 1 file changed, 49 insertions(+), 53 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 1b2989f46ec..76794fa414b 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -2963,55 +2963,10 @@ fs_visitor::compute_to_mrf() /* Found a move of a GRF to a MRF. Let's see if we can go * rewrite the thing that made this GRF to write into the MRF. */ - bool found = false; fs_inst *scan_inst; for (scan_inst = (fs_inst *)inst->prev; scan_inst->prev != NULL; scan_inst = (fs_inst *)scan_inst->prev) { - /* We don't handle flow control here. Most computation of - * values that end up in MRFs are shortly before the MRF - * write anyway. - */ - if (scan_inst->opcode == BRW_OPCODE_DO || - scan_inst->opcode == BRW_OPCODE_WHILE || - scan_inst->opcode == BRW_OPCODE_ENDIF) { - break; - } - - /* You can't read from an MRF, so if someone else reads our - * MRF's source GRF that we wanted to rewrite, that stops us. - */ - bool interfered = false; - for (int i = 0; i < 3; i++) { - if (scan_inst->src[i].file == GRF && - scan_inst->src[i].reg == inst->src[0].reg && - scan_inst->src[i].reg_offset == inst->src[0].reg_offset) { - interfered = true; - } - } - if (interfered) - break; - - if (scan_inst->dst.file == MRF && - scan_inst->dst.hw_reg == inst->dst.hw_reg) { - /* Somebody else wrote our MRF here, so we can't can't - * compute-to-MRF before that. - */ - break; - } - - if (scan_inst->mlen > 0) { - /* Found a SEND instruction, which means that there are - * live values in MRFs from base_mrf to base_mrf + - * scan_inst->mlen - 1. Don't go pushing our MRF write up - * above it. - */ - if (inst->dst.hw_reg >= scan_inst->base_mrf && - inst->dst.hw_reg < scan_inst->base_mrf + scan_inst->mlen) { - break; - } - } - if (scan_inst->dst.file == GRF && scan_inst->dst.reg == inst->src[0].reg) { /* Found the last thing to write our reg we want to turn @@ -3053,18 +3008,59 @@ fs_visitor::compute_to_mrf() if (scan_inst->dst.reg_offset == inst->src[0].reg_offset) { /* Found the creator of our MRF's source value. */ - found = true; + scan_inst->dst.file = MRF; + scan_inst->dst.hw_reg = inst->dst.hw_reg; + scan_inst->saturate |= inst->saturate; + inst->remove(); + progress = true; + } + break; + } + + /* We don't handle flow control here. Most computation of + * values that end up in MRFs are shortly before the MRF + * write anyway. + */ + if (scan_inst->opcode == BRW_OPCODE_DO || + scan_inst->opcode == BRW_OPCODE_WHILE || + scan_inst->opcode == BRW_OPCODE_ENDIF) { + break; + } + + /* You can't read from an MRF, so if someone else reads our + * MRF's source GRF that we wanted to rewrite, that stops us. + */ + bool interfered = false; + for (int i = 0; i < 3; i++) { + if (scan_inst->src[i].file == GRF && + scan_inst->src[i].reg == inst->src[0].reg && + scan_inst->src[i].reg_offset == inst->src[0].reg_offset) { + interfered = true; + } + } + if (interfered) + break; + + if (scan_inst->dst.file == MRF && + scan_inst->dst.hw_reg == inst->dst.hw_reg) { + /* Somebody else wrote our MRF here, so we can't can't + * compute-to-MRF before that. + */ + break; + } + + if (scan_inst->mlen > 0) { + /* Found a SEND instruction, which means that there are + * live values in MRFs from base_mrf to base_mrf + + * scan_inst->mlen - 1. Don't go pushing our MRF write up + * above it. + */ + if (inst->dst.hw_reg >= scan_inst->base_mrf && + inst->dst.hw_reg < scan_inst->base_mrf + scan_inst->mlen) { break; } } } - if (found) { - scan_inst->dst.file = MRF; - scan_inst->dst.hw_reg = inst->dst.hw_reg; - scan_inst->saturate |= inst->saturate; - inst->remove(); - progress = true; - } } return progress; -- 2.30.2