nir/algebraic: allow swizzle in nir_algebraic replace expression
authorJonathan Marek <jonathan@marek.ca>
Fri, 21 Jun 2019 01:23:53 +0000 (21:23 -0400)
committerJonathan Marek <jonathan@marek.ca>
Wed, 24 Jul 2019 21:36:21 +0000 (17:36 -0400)
This is to allow optimizations in nir_opt_algebraic not otherwise possible

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Acked-by: Matt Turner <mattst88@gmail.com>
src/compiler/nir/nir_algebraic.py
src/compiler/nir/nir_opt_algebraic.py
src/compiler/nir/nir_search.c
src/compiler/nir/nir_search.h

index 9b8af1a7470ce7ec7626d56528fb9e22fc669913..3b136f800d443aef1bd02774a531c85146d9c972 100644 (file)
@@ -198,6 +198,7 @@ class Value(object):
    ${'true' if val.is_constant else 'false'},
    ${val.type() or 'nir_type_invalid' },
    ${val.cond if val.cond else 'NULL'},
+   ${val.swizzle()},
 % elif isinstance(val, Expression):
    ${'true' if val.inexact else 'false'},
    ${val.comm_expr_idx}, ${val.comm_exprs},
@@ -284,7 +285,8 @@ class Constant(Value):
 
 _var_name_re = re.compile(r"(?P<const>#)?(?P<name>\w+)"
                           r"(?:@(?P<type>int|uint|bool|float)?(?P<bits>\d+)?)?"
-                          r"(?P<cond>\([^\)]+\))?")
+                          r"(?P<cond>\([^\)]+\))?"
+                          r"(?P<swiz>\.[xyzw]+)?")
 
 class Variable(Value):
    def __init__(self, val, name, varset):
@@ -306,6 +308,7 @@ class Variable(Value):
       self.cond = m.group('cond')
       self.required_type = m.group('type')
       self._bit_size = int(m.group('bits')) if m.group('bits') else None
+      self.swiz = m.group('swiz')
 
       if self.required_type == 'bool':
          if self._bit_size is not None:
@@ -339,6 +342,12 @@ class Variable(Value):
 
       return self.index == other.index
 
+   def swizzle(self):
+      if self.swiz is not None:
+         swizzles = {'x' : 0, 'y' : 1, 'z' : 2, 'w': 3}
+         return '{' + ', '.join([str(swizzles[c]) for c in self.swiz[1:]]) + '}'
+      return '{0, 1, 2, 3}'
+
 _opcode_re = re.compile(r"(?P<inexact>~)?(?P<opcode>\w+)(?:@(?P<bits>\d+))?"
                         r"(?P<cond>\([^\)]+\))?")
 
index 3ffa061c01e7aa24092a04383b5c486d00d23b60..00145fc80f54b4885f4ceb0782f605eb45ead774 100644 (file)
@@ -50,11 +50,12 @@ e = 'e'
 # however, be used for backend-requested lowering operations as those need to
 # happen regardless of precision.
 #
-# Variable names are specified as "[#]name[@type][(cond)]" where "#" inicates
-# that the given variable will only match constants and the type indicates that
-# the given variable will only match values from ALU instructions with the
-# given output type, and (cond) specifies an additional condition function
-# (see nir_search_helpers.h).
+# Variable names are specified as "[#]name[@type][(cond)][.swiz]" where:
+# "#" indicates that the given variable will only match constants,
+# type indicates that the given variable will only match values from ALU
+#    instructions with the given output type,
+# (cond) specifies an additional condition function (see nir_search_helpers.h),
+# swiz is a swizzle applied to the variable (only in the <replace> expression)
 #
 # For constants, you have to be careful to make sure that it is the right
 # type because python is unaware of the source and destination types of the
index 8e3c3529a7413c905d6e31b52f742954c44cb8c7..c62de4ad7febc6b36e4d435845b8ca6dd38d2c57 100644 (file)
@@ -506,6 +506,9 @@ construct_value(nir_builder *build,
                        (void *)build->shader);
       assert(!var->is_constant);
 
+      for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
+         val.swizzle[i] = state->variables[var->variable].swizzle[var->swizzle[i]];
+
       return val;
    }
 
index 526a498cd47e1a814a1f8196e3af9b1f11e9e872..ac37f1ac6534bb6ff31e249aaff0f27c0f6710a0 100644 (file)
@@ -95,6 +95,9 @@ typedef struct {
     */
    bool (*cond)(nir_alu_instr *instr, unsigned src,
                 unsigned num_components, const uint8_t *swizzle);
+
+       /** Swizzle (for replace only) */
+       uint8_t swizzle[NIR_MAX_VEC_COMPONENTS];
 } nir_search_variable;
 
 typedef struct {