nir: add nir_ssa_for_alu_src()
authorRob Clark <robclark@freedesktop.org>
Thu, 5 Nov 2015 15:23:48 +0000 (10:23 -0500)
committerRob Clark <robclark@freedesktop.org>
Fri, 20 Nov 2015 01:03:32 +0000 (20:03 -0500)
Using something like:

   numer = nir_ssa_for_src(bld, alu->src[0].src,
                           nir_ssa_alu_instr_src_components(alu, 0));

for alu src's with swizzle, like:

   vec1 ssa_10 = intrinsic load_uniform () () (0, 0)
   vec2 ssa_11 = intrinsic load_uniform () () (1, 0)
   vec2 ssa_2 = udiv ssa_10.xx, ssa_11

ends up turning into something like:

   vec1 ssa_10 = intrinsic load_uniform () () (0, 0)
   vec2 ssa_11 = intrinsic load_uniform () () (1, 0)
   vec2 ssa_13 = imov ssa_10
   ...

because nir_ssa_for_src() ignore's the original nir_alu_src's swizzle.
Instead for alu instructions, nir_src_for_alu_src() should be used to
ensure the original alu src's swizzle doesn't get lost in translation:

   vec1 ssa_10 = intrinsic load_uniform () () (0, 0)
   vec2 ssa_11 = intrinsic load_uniform () () (1, 0)
   vec2 ssa_13 = imov ssa_10.xx
   ...

v2: check for abs/neg, and re-use existing nir_alu_src

Signed-off-by: Rob Clark <robclark@freedesktop.org>
Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
src/glsl/nir/nir_builder.h
src/glsl/nir/nir_lower_idiv.c

index 624329d0a8a6fe244e2af18eb190853f48dd351a..d09f929405b0f09d1211fc246c1cf844afdee25b 100644 (file)
@@ -259,6 +259,8 @@ nir_channel(nir_builder *b, nir_ssa_def *def, unsigned c)
 /**
  * Turns a nir_src into a nir_ssa_def * so it can be passed to
  * nir_build_alu()-based builder calls.
+ *
+ * See nir_ssa_for_alu_src() for alu instructions.
  */
 static inline nir_ssa_def *
 nir_ssa_for_src(nir_builder *build, nir_src src, int num_components)
@@ -274,6 +276,25 @@ nir_ssa_for_src(nir_builder *build, nir_src src, int num_components)
    return nir_imov_alu(build, alu, num_components);
 }
 
+/**
+ * Similar to nir_ssa_for_src(), but for alu src's, respecting the
+ * nir_alu_src's swizzle.
+ */
+static inline nir_ssa_def *
+nir_ssa_for_alu_src(nir_builder *build, nir_alu_instr *instr, unsigned srcn)
+{
+   static uint8_t trivial_swizzle[4] = { 0, 1, 2, 3 };
+   nir_alu_src *src = &instr->src[srcn];
+   unsigned num_components = nir_ssa_alu_instr_src_components(instr, srcn);
+
+   if (src->src.is_ssa && (src->src.ssa->num_components == num_components) &&
+       !src->abs && !src->negate &&
+       (memcmp(src->swizzle, trivial_swizzle, num_components) == 0))
+      return src->src.ssa;
+
+   return nir_imov_alu(build, *src, num_components);
+}
+
 static inline nir_ssa_def *
 nir_load_var(nir_builder *build, nir_variable *var)
 {
index 3580ced0ac060d6a84eec95b6bd2ff8fac08d014..f64b3eac8a07e90384c48f072e7060ae749d5fe5 100644 (file)
@@ -52,10 +52,8 @@ convert_instr(nir_builder *bld, nir_alu_instr *alu)
 
    bld->cursor = nir_before_instr(&alu->instr);
 
-   numer = nir_ssa_for_src(bld, alu->src[0].src,
-                           nir_ssa_alu_instr_src_components(alu, 0));
-   denom = nir_ssa_for_src(bld, alu->src[1].src,
-                           nir_ssa_alu_instr_src_components(alu, 1));
+   numer = nir_ssa_for_alu_src(bld, alu, 0);
+   denom = nir_ssa_for_alu_src(bld, alu, 1);
 
    if (is_signed) {
       af = nir_i2f(bld, numer);