mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
glsl: When doing algebraic simplification, make sure the type still matches.
When simplifying (vec4(1.0) / (float(x))) to rcp(float(x)), we forgot to produce a vec4, angering ir_validate when starting alien-arena. Fixes: glsl-algebraic-add-zero-2 glsl-algebraic-div-one-2 glsl-algebraic-mul-one-2 glsl-algebraic-sub-zero-3 glsl-algebraic-rcp-sqrt-2
This commit is contained in:
parent
f166d94fac
commit
0e6066df63
1 changed files with 34 additions and 12 deletions
|
|
@ -60,8 +60,11 @@ public:
|
|||
int op1,
|
||||
ir_expression *ir2,
|
||||
int op2);
|
||||
ir_rvalue *swizzle_if_required(ir_expression *expr,
|
||||
ir_rvalue *operand);
|
||||
|
||||
void *mem_ctx;
|
||||
|
||||
bool progress;
|
||||
};
|
||||
|
||||
|
|
@ -219,11 +222,27 @@ ir_algebraic_visitor::reassociate_constant(ir_expression *ir1, int const_index,
|
|||
return false;
|
||||
}
|
||||
|
||||
/* When eliminating an expression and just returning one of its operands,
|
||||
* we may need to swizzle that operand out to a vector if the expression was
|
||||
* vector type.
|
||||
*/
|
||||
ir_rvalue *
|
||||
ir_algebraic_visitor::swizzle_if_required(ir_expression *expr,
|
||||
ir_rvalue *operand)
|
||||
{
|
||||
if (expr->type->is_vector() && operand->type->is_scalar()) {
|
||||
return new(mem_ctx) ir_swizzle(operand, 0, 0, 0, 0,
|
||||
expr->type->vector_elements);
|
||||
} else
|
||||
return operand;
|
||||
}
|
||||
|
||||
ir_rvalue *
|
||||
ir_algebraic_visitor::handle_expression(ir_expression *ir)
|
||||
{
|
||||
ir_constant *op_const[2] = {NULL, NULL};
|
||||
ir_expression *op_expr[2] = {NULL, NULL};
|
||||
ir_expression *temp;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ir->get_num_operands(); i++) {
|
||||
|
|
@ -272,11 +291,11 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
|
|||
case ir_binop_add:
|
||||
if (is_vec_zero(op_const[0])) {
|
||||
this->progress = true;
|
||||
return ir->operands[1];
|
||||
return swizzle_if_required(ir, ir->operands[1]);
|
||||
}
|
||||
if (is_vec_zero(op_const[1])) {
|
||||
this->progress = true;
|
||||
return ir->operands[0];
|
||||
return swizzle_if_required(ir, ir->operands[0]);
|
||||
}
|
||||
|
||||
/* Reassociate addition of constants so that we can do constant
|
||||
|
|
@ -293,25 +312,26 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
|
|||
case ir_binop_sub:
|
||||
if (is_vec_zero(op_const[0])) {
|
||||
this->progress = true;
|
||||
return new(mem_ctx) ir_expression(ir_unop_neg,
|
||||
ir->type,
|
||||
temp = new(mem_ctx) ir_expression(ir_unop_neg,
|
||||
ir->operands[1]->type,
|
||||
ir->operands[1],
|
||||
NULL);
|
||||
return swizzle_if_required(ir, temp);
|
||||
}
|
||||
if (is_vec_zero(op_const[1])) {
|
||||
this->progress = true;
|
||||
return ir->operands[0];
|
||||
return swizzle_if_required(ir, ir->operands[0]);
|
||||
}
|
||||
break;
|
||||
|
||||
case ir_binop_mul:
|
||||
if (is_vec_one(op_const[0])) {
|
||||
this->progress = true;
|
||||
return ir->operands[1];
|
||||
return swizzle_if_required(ir, ir->operands[1]);
|
||||
}
|
||||
if (is_vec_one(op_const[1])) {
|
||||
this->progress = true;
|
||||
return ir->operands[0];
|
||||
return swizzle_if_required(ir, ir->operands[0]);
|
||||
}
|
||||
|
||||
if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1])) {
|
||||
|
|
@ -334,14 +354,15 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
|
|||
case ir_binop_div:
|
||||
if (is_vec_one(op_const[0]) && ir->type->base_type == GLSL_TYPE_FLOAT) {
|
||||
this->progress = true;
|
||||
return new(mem_ctx) ir_expression(ir_unop_rcp,
|
||||
ir->type,
|
||||
temp = new(mem_ctx) ir_expression(ir_unop_rcp,
|
||||
ir->operands[1]->type,
|
||||
ir->operands[1],
|
||||
NULL);
|
||||
return swizzle_if_required(ir, temp);
|
||||
}
|
||||
if (is_vec_one(op_const[1])) {
|
||||
this->progress = true;
|
||||
return ir->operands[0];
|
||||
return swizzle_if_required(ir, ir->operands[0]);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -359,10 +380,11 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
|
|||
/* As far as we know, all backends are OK with rsq. */
|
||||
if (op_expr[0] && op_expr[0]->operation == ir_unop_sqrt) {
|
||||
this->progress = true;
|
||||
return new(mem_ctx) ir_expression(ir_unop_rsq,
|
||||
ir->type,
|
||||
temp = new(mem_ctx) ir_expression(ir_unop_rsq,
|
||||
op_expr[0]->operands[0]->type,
|
||||
op_expr[0]->operands[0],
|
||||
NULL);
|
||||
return swizzle_if_required(ir, temp);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue