[Mesa-dev] [PATCH 1/2] i965/vec4: Reswizzle sources when necessary.

Matt Turner mattst88 at gmail.com
Sun Aug 31 11:33:58 PDT 2014


Despite the comment above the function claiming otherwise, the function
did not reswizzle sources, which would lead to bad code generation.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82932
---
 src/mesa/drivers/dri/i965/brw_vec4.cpp | 32 +++++++++++++++++++++++---------
 src/mesa/drivers/dri/i965/brw_vec4.h   |  4 ++--
 2 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index acf0b63..cbea437 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -933,9 +933,9 @@ vec4_visitor::opt_set_dependency_control()
 }
 
 bool
-vec4_instruction::can_reswizzle_dst(int dst_writemask,
-                                    int swizzle,
-                                    int swizzle_mask)
+vec4_instruction::can_reswizzle(int dst_writemask,
+                                int swizzle,
+                                int swizzle_mask)
 {
    /* If this instruction sets anything not referenced by swizzle, then we'd
     * totally break it when we reswizzle.
@@ -977,9 +977,10 @@ vec4_instruction::can_reswizzle_dst(int dst_writemask,
  * e.g. for swizzle=yywx, MUL a.xy b c -> MUL a.yy_x b.yy z.yy_x
  */
 void
-vec4_instruction::reswizzle_dst(int dst_writemask, int swizzle)
+vec4_instruction::reswizzle(int dst_writemask, int swizzle)
 {
    int new_writemask = 0;
+   int new_swizzle[4] = { 0 };
 
    switch (opcode) {
    default:
@@ -996,6 +997,19 @@ vec4_instruction::reswizzle_dst(int dst_writemask, int swizzle)
          }
          break;
       }
+
+      for (int i = 0; i < 3; i++) {
+         if (src[i].file == BAD_FILE || src[i].file == IMM)
+            continue;
+
+         for (int c = 0; c < 4; c++) {
+            new_swizzle[c] = BRW_GET_SWZ(src[i].swizzle, BRW_GET_SWZ(swizzle, c));
+         }
+
+         src[i].swizzle = BRW_SWIZZLE4(new_swizzle[0], new_swizzle[1],
+                                       new_swizzle[2], new_swizzle[3]);
+      }
+
       /* fallthrough */
    case BRW_OPCODE_DP4:
    case BRW_OPCODE_DP3:
@@ -1102,9 +1116,9 @@ vec4_visitor::opt_register_coalesce()
             }
 
             /* If we can't handle the swizzle, bail. */
-            if (!scan_inst->can_reswizzle_dst(inst->dst.writemask,
-                                              inst->src[0].swizzle,
-                                              swizzle_mask)) {
+            if (!scan_inst->can_reswizzle(inst->dst.writemask,
+                                          inst->src[0].swizzle,
+                                          swizzle_mask)) {
                break;
             }
 
@@ -1190,8 +1204,8 @@ vec4_visitor::opt_register_coalesce()
 	    if (scan_inst->dst.file == GRF &&
 		scan_inst->dst.reg == inst->src[0].reg &&
 		scan_inst->dst.reg_offset == inst->src[0].reg_offset) {
-               scan_inst->reswizzle_dst(inst->dst.writemask,
-                                        inst->src[0].swizzle);
+               scan_inst->reswizzle(inst->dst.writemask,
+                                    inst->src[0].swizzle);
 	       scan_inst->dst.file = inst->dst.file;
 	       scan_inst->dst.reg = inst->dst.reg;
 	       scan_inst->dst.reg_offset = inst->dst.reg_offset;
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index f8313c1..74d1241 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -220,8 +220,8 @@ public:
    bool header_present;
 
    bool is_send_from_grf();
-   bool can_reswizzle_dst(int dst_writemask, int swizzle, int swizzle_mask);
-   void reswizzle_dst(int dst_writemask, int swizzle);
+   bool can_reswizzle(int dst_writemask, int swizzle, int swizzle_mask);
+   void reswizzle(int dst_writemask, int swizzle);
    bool can_do_source_mods(struct brw_context *brw);
 
    bool reads_flag()
-- 
1.8.5.5



More information about the mesa-dev mailing list