glsl: Transform dot product by a basis vector into a swizzle

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
Matt Turner 2012-06-04 21:59:34 -04:00
parent 9aa3fbcc2e
commit ae419a0159
2 changed files with 24 additions and 3 deletions

View File

@ -6,9 +6,6 @@
constant index values. For others it is more complicated. Perhaps these constant index values. For others it is more complicated. Perhaps these
cases should be silently converted to uniforms? 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 - Track source locations throughout the IR. There are currently several
places where we cannot emit line numbers for errors (and currently emit 0:0) 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 because we've "lost" the line number information. This is particularly

View File

@ -84,6 +84,12 @@ is_vec_one(ir_constant *ir)
return (ir == NULL) ? false : ir->is_one(); 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 static void
update_type(ir_expression *ir) update_type(ir_expression *ir)
{ {
@ -314,6 +320,24 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
this->progress = true; this->progress = true;
return ir_constant::zero(mem_ctx, ir->type); 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; break;
case ir_binop_logic_and: case ir_binop_logic_and: