[Mesa-dev] [PATCH] nir: Fix per-component negation in prog_to_nir's SWZ handling.

Kenneth Graunke kenneth at whitecape.org
Fri Apr 17 14:32:36 PDT 2015


I missed the fact that the ARB_fragment_program SWZ instruction allows
per-component negation.  To fix this, move Abs/Negate handling into both
the simple case and the SWZ case's per-component loop.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90000
Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/mesa/program/prog_to_nir.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/src/mesa/program/prog_to_nir.c b/src/mesa/program/prog_to_nir.c
index c738f50..ff3d9f3 100644
--- a/src/mesa/program/prog_to_nir.c
+++ b/src/mesa/program/prog_to_nir.c
@@ -222,12 +222,23 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
    }
 
    nir_ssa_def *def;
-   if (!HAS_EXTENDED_SWIZZLE(prog_src->Swizzle)) {
+   if (!HAS_EXTENDED_SWIZZLE(prog_src->Swizzle) &&
+       (prog_src->Negate == NEGATE_NONE || prog_src->Negate == NEGATE_XYZW)) {
+      /* The simple non-SWZ case. */
       for (int i = 0; i < 4; i++)
          src.swizzle[i] = GET_SWZ(prog_src->Swizzle, i);
 
       def = nir_fmov_alu(b, src, 4);
+
+      if (prog_src->Abs)
+         def = nir_fabs(b, def);
+
+      if (prog_src->Negate)
+         def = nir_fneg(b, def);
    } else {
+      /* The SWZ instruction allows per-component zero/one swizzles, and also
+       * per-component negation.
+       */
       nir_ssa_def *chans[4];
       for (int i = 0; i < 4; i++) {
          int swizzle = GET_SWZ(prog_src->Swizzle, i);
@@ -246,16 +257,16 @@ ptn_get_src(struct ptn_compile *c, const struct prog_src_register *prog_src)
 
             chans[i] = &mov->dest.dest.ssa;
          }
+
+         if (prog_src->Abs)
+            chans[i] = nir_fabs(b, chans[i]);
+
+         if (prog_src->Negate & (1 << i))
+            chans[i] = nir_fneg(b, chans[i]);
       }
       def = nir_vec4(b, chans[0], chans[1], chans[2], chans[3]);
    }
 
-   if (prog_src->Abs)
-      def = nir_fabs(b, def);
-
-   if (prog_src->Negate)
-      def = nir_fneg(b, def);
-
    return def;
 }
 
-- 
2.3.5



More information about the mesa-dev mailing list