From: Eric Anholt Date: Wed, 12 May 2010 21:42:21 +0000 (-0700) Subject: ir_constant_expression: Handle several floating point unops. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=43ad37aa885dc185679dabd605752fe2d782d542;p=mesa.git ir_constant_expression: Handle several floating point unops. Cleans up a bunch of pointless operations in a GStreamer fragment shader. --- diff --git a/ir_constant_expression.cpp b/ir_constant_expression.cpp index b1092de1393..361a7a1630a 100644 --- a/ir_constant_expression.cpp +++ b/ir_constant_expression.cpp @@ -34,6 +34,7 @@ */ #define NULL 0 +#include #include "ir.h" #include "ir_visitor.h" #include "glsl_types.h" @@ -168,6 +169,102 @@ ir_constant_visitor::visit(ir_expression *ir) } break; + case ir_unop_neg: + type = ir->type; + for (c = 0; c < ir->operands[0]->type->components(); c++) { + switch (type->base_type) { + case GLSL_TYPE_UINT: + u[c] = -op[0]->value.u[c]; + break; + case GLSL_TYPE_INT: + i[c] = -op[0]->value.i[c]; + break; + case GLSL_TYPE_FLOAT: + f[c] = -op[0]->value.f[c]; + break; + default: + assert(0); + } + } + break; + + case ir_unop_abs: + assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); + type = ir->type; + for (c = 0; c < ir->operands[0]->type->components(); c++) { + switch (type->base_type) { + case GLSL_TYPE_UINT: + u[c] = op[0]->value.u[c]; + break; + case GLSL_TYPE_INT: + i[c] = op[0]->value.i[c]; + if (i[c] < 0) + i[c] = -i[c]; + break; + case GLSL_TYPE_FLOAT: + f[c] = fabs(op[0]->value.f[c]); + break; + default: + assert(0); + } + } + break; + + case ir_unop_rcp: + assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); + type = ir->type; + for (c = 0; c < ir->operands[0]->type->components(); c++) { + switch (type->base_type) { + case GLSL_TYPE_UINT: + if (op[0]->value.u[c] != 0.0) + u[c] = 1 / op[0]->value.u[c]; + break; + case GLSL_TYPE_INT: + if (op[0]->value.i[c] != 0.0) + i[c] = 1 / op[0]->value.i[c]; + break; + case GLSL_TYPE_FLOAT: + if (op[0]->value.f[c] != 0.0) + f[c] = 1.0 / op[0]->value.f[c]; + break; + default: + assert(0); + } + } + break; + + case ir_unop_rsq: + assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); + type = ir->type; + for (c = 0; c < ir->operands[0]->type->components(); c++) { + f[c] = 1.0 / sqrtf(op[0]->value.f[c]); + } + break; + + case ir_unop_sqrt: + assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); + type = ir->type; + for (c = 0; c < ir->operands[0]->type->components(); c++) { + f[c] = sqrtf(op[0]->value.f[c]); + } + break; + + case ir_unop_exp: + assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); + type = ir->type; + for (c = 0; c < ir->operands[0]->type->components(); c++) { + f[c] = expf(op[0]->value.f[c]); + } + break; + + case ir_unop_log: + assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); + type = ir->type; + for (c = 0; c < ir->operands[0]->type->components(); c++) { + f[c] = logf(op[0]->value.f[c]); + } + break; + case ir_binop_add: if (ir->operands[0]->type == ir->operands[1]->type) { type = ir->operands[0]->type;