Mesa (master): i965: Improve compute-to-mrf.

Eric Anholt anholt at kemper.freedesktop.org
Sat Nov 20 04:06:54 UTC 2010


Module: Mesa
Branch: master
Commit: 47b1aac1cf0aefae4df58a60bb7eb26d21e25913
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=47b1aac1cf0aefae4df58a60bb7eb26d21e25913

Author: Eric Anholt <eric at anholt.net>
Date:   Thu Nov 18 15:03:50 2010 +0800

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 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 1b2989f..76794fa 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;




More information about the mesa-commit mailing list