glsl: Transform dot product by a basis vector into a swizzle
authorMatt Turner <mattst88@gmail.com>
Tue, 5 Jun 2012 01:59:34 +0000 (21:59 -0400)
committerMatt Turner <mattst88@gmail.com>
Tue, 12 Jun 2012 22:51:25 +0000 (18:51 -0400)
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/glsl/TODO
src/glsl/opt_algebraic.cpp

index eb73fc2e8132871b1ca7abb07b4f9b8568ef8c6f..bd077a85678ba75fbe37c927b49875980abc9ab5 100644 (file)
@@ -6,9 +6,6 @@
   constant index values.  For others it is more complicated.  Perhaps these
   cases should be silently converted to uniforms?
 
-- Implement support for ir_binop_dot in opt_algebraic.cpp.  Perform
-  transformations such as "dot(v, vec3(0.0, 1.0, 0.0))" -> v.y.
-
 - Track source locations throughout the IR.  There are currently several
   places where we cannot emit line numbers for errors (and currently emit 0:0)
   because we've "lost" the line number information.  This is particularly
index 5a9881dbebe7d118d51d28933bc59cc79dd6c4e8..75948db16fa6680bcf6a9623937efcb5436a0eb7 100644 (file)
@@ -84,6 +84,12 @@ is_vec_one(ir_constant *ir)
    return (ir == NULL) ? false : ir->is_one();
 }
 
+static inline bool
+is_vec_basis(ir_constant *ir)
+{
+   return (ir == NULL) ? false : ir->is_basis();
+}
+
 static void
 update_type(ir_expression *ir)
 {
@@ -314,6 +320,24 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
         this->progress = true;
         return ir_constant::zero(mem_ctx, ir->type);
       }
+      if (is_vec_basis(op_const[0])) {
+        this->progress = true;
+        unsigned component = 0;
+        for (unsigned c = 0; c < op_const[0]->type->vector_elements; c++) {
+           if (op_const[0]->value.f[c] == 1.0)
+              component = c;
+        }
+        return new(mem_ctx) ir_swizzle(ir->operands[1], component, 0, 0, 0, 1);
+      }
+      if (is_vec_basis(op_const[1])) {
+        this->progress = true;
+        unsigned component = 0;
+        for (unsigned c = 0; c < op_const[1]->type->vector_elements; c++) {
+           if (op_const[1]->value.f[c] == 1.0)
+              component = c;
+        }
+        return new(mem_ctx) ir_swizzle(ir->operands[0], component, 0, 0, 0, 1);
+      }
       break;
 
    case ir_binop_logic_and: