summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2010-11-18 15:03:50 +0800
committerEric Anholt <[email protected]>2010-11-19 19:54:11 -0800
commit47b1aac1cf0aefae4df58a60bb7eb26d21e25913 (patch)
tree44998e9401173a986c3ea266fa566ab780a43cde
parentac89a90401f08df945248fcc96da59ba0e2bbfa9 (diff)
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).
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp102
1 files 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;