[Mesa-dev] [PATCH 1/2] i965/fs: Track dependencies in instruction scheduling per reg offset.

Matt Turner mattst88 at gmail.com
Mon Jul 7 13:39:16 PDT 2014


Previously instruction scheduling tracked dependencies on a per-register
basis. This meant that there was an artificial dependency between
interpolation instructions writing into the same virtual register.

Instruction scheduling would insert a number of instructions between the
two instructions in this example, when they are actually independent.

   linterp vgrf8+0.0:F, hw_reg2:F, hw_reg3:F, hw_reg6:F
   linterp vgrf8+1.0:F, hw_reg2:F, hw_reg3:F, hw_reg6+16:F

This lead to cases where the first texture coordinate is interpolated at
the beginning of the shader, but the second is done immediately before
the texture operation that uses it as a source.

After this change, the artificial dependency is removed and the
interpolation instructions are scheduled together.
---
FIXME: What's the maximum register offset?

 .../drivers/dri/i965/brw_schedule_instructions.cpp | 23 ++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp b/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp
index 245df2a..10a8f6d 100644
--- a/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp
+++ b/src/mesa/drivers/dri/i965/brw_schedule_instructions.cpp
@@ -742,12 +742,11 @@ fs_instruction_scheduler::is_compressed(fs_inst *inst)
 void
 fs_instruction_scheduler::calculate_deps()
 {
-   /* Pre-register-allocation, this tracks the last write per VGRF (so
-    * different reg_offsets within it can interfere when they shouldn't).
+   /* Pre-register-allocation, this tracks the last write per VGRF offset.
     * After register allocation, reg_offsets are gone and we track individual
     * GRF registers.
     */
-   schedule_node *last_grf_write[grf_count];
+   schedule_node *last_grf_write[grf_count * 16];
    schedule_node *last_mrf_write[BRW_MAX_MRF];
    schedule_node *last_conditional_mod[2] = { NULL, NULL };
    schedule_node *last_accumulator_write = NULL;
@@ -786,7 +785,9 @@ fs_instruction_scheduler::calculate_deps()
                for (int r = 0; r < reg_width * inst->regs_read(v, i); r++)
                   add_dep(last_grf_write[inst->src[i].reg + r], n);
             } else {
-               add_dep(last_grf_write[inst->src[i].reg], n);
+               for (int r = 0; r < inst->regs_read(v, i); r++) {
+                  add_dep(last_grf_write[inst->src[i].reg * 16 + inst->src[i].reg_offset + r], n);
+               }
             }
 	 } else if (inst->src[i].file == HW_REG &&
 		    (inst->src[i].fixed_hw_reg.file ==
@@ -838,8 +839,10 @@ fs_instruction_scheduler::calculate_deps()
                last_grf_write[inst->dst.reg + r] = n;
             }
          } else {
-            add_dep(last_grf_write[inst->dst.reg], n);
-            last_grf_write[inst->dst.reg] = n;
+            for (int r = 0; r < inst->regs_written; r++) {
+               add_dep(last_grf_write[inst->dst.reg * 16 + inst->dst.reg_offset + r], n);
+               last_grf_write[inst->dst.reg * 16 + inst->dst.reg_offset + r] = n;
+            }
          }
       } else if (inst->dst.file == MRF) {
 	 int reg = inst->dst.reg & ~BRW_MRF_COMPR4;
@@ -910,7 +913,9 @@ fs_instruction_scheduler::calculate_deps()
                for (int r = 0; r < reg_width * inst->regs_read(v, i); r++)
                   add_dep(n, last_grf_write[inst->src[i].reg + r]);
             } else {
-               add_dep(n, last_grf_write[inst->src[i].reg]);
+               for (int r = 0; r < inst->regs_read(v, i); r++) {
+                  add_dep(n, last_grf_write[inst->src[i].reg * 16 + inst->src[i].reg_offset + r]);
+               }
             }
 	 } else if (inst->src[i].file == HW_REG &&
 		    (inst->src[i].fixed_hw_reg.file ==
@@ -962,7 +967,9 @@ fs_instruction_scheduler::calculate_deps()
             for (int r = 0; r < inst->regs_written * reg_width; r++)
                last_grf_write[inst->dst.reg + r] = n;
          } else {
-            last_grf_write[inst->dst.reg] = n;
+            for (int r = 0; r < inst->regs_written; r++) {
+               last_grf_write[inst->dst.reg * 16 + inst->dst.reg_offset + r] = n;
+            }
          }
       } else if (inst->dst.file == MRF) {
 	 int reg = inst->dst.reg & ~BRW_MRF_COMPR4;
-- 
1.8.5.5



More information about the mesa-dev mailing list