Mesa (master): i965/fs: Also do the gen4 SEND dependency workaround against other SENDs.

Eric Anholt anholt at kemper.freedesktop.org
Mon Mar 11 19:28:31 UTC 2013


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

Author: Eric Anholt <eric at anholt.net>
Date:   Wed Mar  6 17:50:50 2013 -0800

i965/fs: Also do the gen4 SEND dependency workaround against other SENDs.

We were handling the the dependency workaround for the first written reg
of a send preceding the one we're fixing up, but didn't consider the other
regs.  Thus if you had two sampler calls that got allocated to the same
set of regs, one might, rarely, ovewrite the other.  This was occurring in
XBMC's GLSL shaders.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=44567
NOTE: This is a candidate for the stable branches.
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

---

 src/mesa/drivers/dri/i965/brw_fs.cpp |   24 +++++++++++++++---------
 1 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 5380abf..8ce3954 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -2300,7 +2300,8 @@ clear_deps_for_inst_src(fs_inst *inst, int dispatch_width, bool *deps,
 void
 fs_visitor::insert_gen4_pre_send_dependency_workarounds(fs_inst *inst)
 {
-   int write_len = inst->regs_written() * dispatch_width / 8;
+   int reg_size = dispatch_width / 8;
+   int write_len = inst->regs_written() * reg_size;
    int first_write_grf = inst->dst.reg;
    bool needs_dep[BRW_MAX_MRF];
    assert(write_len < (int)sizeof(needs_dep) - 1);
@@ -2339,14 +2340,19 @@ fs_visitor::insert_gen4_pre_send_dependency_workarounds(fs_inst *inst)
        * instruction but a MOV that might have left us an outstanding
        * dependency has more latency than a MOV.
        */
-      if (scan_inst->dst.file == GRF &&
-          scan_inst->dst.reg >= first_write_grf &&
-          scan_inst->dst.reg < first_write_grf + write_len &&
-          needs_dep[scan_inst->dst.reg - first_write_grf]) {
-         inst->insert_before(DEP_RESOLVE_MOV(scan_inst->dst.reg));
-         needs_dep[scan_inst->dst.reg - first_write_grf] = false;
-         if (scan_inst_16wide)
-            needs_dep[scan_inst->dst.reg - first_write_grf + 1] = false;
+      if (scan_inst->dst.file == GRF) {
+         for (int i = 0; i < scan_inst->regs_written(); i++) {
+            int reg = scan_inst->dst.reg + i * reg_size;
+
+            if (reg >= first_write_grf &&
+                reg < first_write_grf + write_len &&
+                needs_dep[reg - first_write_grf]) {
+               inst->insert_before(DEP_RESOLVE_MOV(reg));
+               needs_dep[reg - first_write_grf] = false;
+               if (scan_inst_16wide)
+                  needs_dep[reg - first_write_grf + 1] = false;
+            }
+         }
       }
 
       /* Clear the flag for registers that actually got read (as expected). */




More information about the mesa-commit mailing list