i965/fs: Generalize is_uniform() to is_periodic().
authorFrancisco Jerez <currojerez@riseup.net>
Wed, 18 May 2016 00:45:41 +0000 (17:45 -0700)
committerFrancisco Jerez <currojerez@riseup.net>
Sat, 28 May 2016 06:19:20 +0000 (23:19 -0700)
This will be useful in the SIMD lowering pass.

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/mesa/drivers/dri/i965/brw_ir_fs.h

index e8f1d5353da1db6f814433d93f2ac803ccce8916..9c39a05f4ce13d68411cd985d10a77851856c6e6 100644 (file)
@@ -146,10 +146,39 @@ component(fs_reg reg, unsigned idx)
    return reg;
 }
 
+/**
+ * Return whether the given register region is n-periodic, i.e. whether the
+ * original region remains invariant after shifting it by \p n scalar
+ * channels.
+ */
+static inline bool
+is_periodic(const fs_reg &reg, unsigned n)
+{
+   if (reg.file == BAD_FILE || reg.is_null()) {
+      return true;
+
+   } else if (reg.file == IMM) {
+      const unsigned period = (reg.type == BRW_REGISTER_TYPE_UV ||
+                               reg.type == BRW_REGISTER_TYPE_V ? 8 :
+                               reg.type == BRW_REGISTER_TYPE_VF ? 4 :
+                               1);
+      return n % period == 0;
+
+   } else if (reg.file == ARF || reg.file == FIXED_GRF) {
+      const unsigned period = (reg.hstride == 0 && reg.vstride == 0 ? 1 :
+                               reg.vstride == 0 ? 1 << reg.width :
+                               ~0);
+      return n % period == 0;
+
+   } else {
+      return reg.stride == 0;
+   }
+}
+
 static inline bool
 is_uniform(const fs_reg &reg)
 {
-   return (reg.stride == 0 || reg.is_null());
+   return is_periodic(reg, 1);
 }
 
 /**