aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl/opt_algebraic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl/opt_algebraic.cpp')
-rw-r--r--mesalib/src/glsl/opt_algebraic.cpp49
1 files changed, 28 insertions, 21 deletions
diff --git a/mesalib/src/glsl/opt_algebraic.cpp b/mesalib/src/glsl/opt_algebraic.cpp
index 0cdb8ecfc..430f5cb97 100644
--- a/mesalib/src/glsl/opt_algebraic.cpp
+++ b/mesalib/src/glsl/opt_algebraic.cpp
@@ -105,12 +105,6 @@ is_vec_negative_one(ir_constant *ir)
}
static inline bool
-is_vec_basis(ir_constant *ir)
-{
- return (ir == NULL) ? false : ir->is_basis();
-}
-
-static inline bool
is_valid_vec_const(ir_constant *ir)
{
if (ir == NULL)
@@ -537,21 +531,34 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1]))
return ir_constant::zero(mem_ctx, ir->type);
- if (is_vec_basis(op_const[0])) {
- 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])) {
- 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);
+ for (int i = 0; i < 2; i++) {
+ if (!op_const[i])
+ continue;
+
+ unsigned components[4] = { 0 }, count = 0;
+
+ for (unsigned c = 0; c < op_const[i]->type->vector_elements; c++) {
+ if (op_const[i]->value.f[c] == 0.0)
+ continue;
+
+ components[count] = c;
+ count++;
+ }
+
+ /* No channels had zero values; bail. */
+ if (count >= op_const[i]->type->vector_elements)
+ break;
+
+ ir_expression_operation op = count == 1 ?
+ ir_binop_mul : ir_binop_dot;
+
+ /* Swizzle both operands to remove the channels that were zero. */
+ return new(mem_ctx)
+ ir_expression(op, glsl_type::float_type,
+ new(mem_ctx) ir_swizzle(ir->operands[0],
+ components, count),
+ new(mem_ctx) ir_swizzle(ir->operands[1],
+ components, count));
}
break;