Mesa (master): i965/vec4: Add ability to reswizzle arbitrary swizzles.

Matt Turner mattst88 at kemper.freedesktop.org
Fri Sep 5 17:22:46 UTC 2014


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

Author: Matt Turner <mattst88 at gmail.com>
Date:   Sun Aug 31 11:27:40 2014 -0700

i965/vec4: Add ability to reswizzle arbitrary swizzles.

Before commit 04895f5c we would only reswizzle dot product instructions
(since they wrote the same value into all channels, and we didn't have
to think about anything else). That commit extended reswizzling to cases
when the swizzle was single valued -- i.e., writing the same result into
all channels.

But allowing reswizzling of arbitrary things is actually really easy and
is even less code. (Why didn't we do this in the first place?!)

total instructions in shared programs: 4266079 -> 4261000 (-0.12%)
instructions in affected programs:     351933 -> 346854 (-1.44%)

Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

---

 src/mesa/drivers/dri/i965/brw_vec4.cpp |   74 ++++++++------------------------
 1 file changed, 18 insertions(+), 56 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index dcfa594..3ace1bd 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -943,30 +943,10 @@ vec4_instruction::can_reswizzle(int dst_writemask,
    if (dst.writemask & ~swizzle_mask)
       return false;
 
-   switch (opcode) {
-   default:
-      if (!brw_is_single_value_swizzle(swizzle)) {
-         /* Check if there happens to be no reswizzling required. */
-         for (int c = 0; c < 4; c++) {
-            int bit = 1 << BRW_GET_SWZ(swizzle, c);
-            /* Skip components of the swizzle not used by the dst. */
-            if (!(dst_writemask & (1 << c)))
-               continue;
+   if (inst->mlen > 0)
+      return false;
 
-            /* We don't do the reswizzling yet, so just sanity check that we
-             * don't have to.
-             */
-            if (bit != (1 << c))
-               return false;
-         }
-         return true;
-      }
-      /* fallthrough */
-   case BRW_OPCODE_DP4:
-   case BRW_OPCODE_DP3:
-   case BRW_OPCODE_DP2:
-      return true;
-   }
+   return true;
 }
 
 /**
@@ -982,22 +962,9 @@ vec4_instruction::reswizzle(int dst_writemask, int swizzle)
    int new_writemask = 0;
    int new_swizzle[4] = { 0 };
 
-   switch (opcode) {
-   default:
-      if (!brw_is_single_value_swizzle(swizzle)) {
-         for (int c = 0; c < 4; c++) {
-            /* Skip components of the swizzle not used by the dst. */
-            if (!(dst_writemask & (1 << c)))
-               continue;
-
-            /* We don't do the reswizzling yet, so just sanity check that we
-             * don't have to.
-             */
-            assert((1 << BRW_GET_SWZ(swizzle, c)) == (1 << c));
-         }
-         break;
-      }
-
+   /* Dot product instructions write a single result into all channels. */
+   if (opcode != BRW_OPCODE_DP4 && opcode != BRW_OPCODE_DPH &&
+       opcode != BRW_OPCODE_DP3 && opcode != BRW_OPCODE_DP2) {
       for (int i = 0; i < 3; i++) {
          if (src[i].file == BAD_FILE || src[i].file == IMM)
             continue;
@@ -1009,25 +976,20 @@ vec4_instruction::reswizzle(int dst_writemask, int swizzle)
          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:
-   case BRW_OPCODE_DP2:
-      for (int c = 0; c < 4; c++) {
-         int bit = 1 << BRW_GET_SWZ(swizzle, c);
-         /* Skip components of the swizzle not used by the dst. */
-         if (!(dst_writemask & (1 << c)))
-            continue;
-         /* If we were populating this component, then populate the
-          * corresponding channel of the new dst.
-          */
-         if (dst.writemask & bit)
-            new_writemask |= (1 << c);
-      }
-      dst.writemask = new_writemask;
-      break;
+   for (int c = 0; c < 4; c++) {
+      int bit = 1 << BRW_GET_SWZ(swizzle, c);
+      /* Skip components of the swizzle not used by the dst. */
+      if (!(dst_writemask & (1 << c)))
+         continue;
+      /* If we were populating this component, then populate the
+       * corresponding channel of the new dst.
+       */
+      if (dst.writemask & bit)
+         new_writemask |= (1 << c);
    }
+   dst.writemask = new_writemask;
 }
 
 /*




More information about the mesa-commit mailing list