diff options
author | Eric Anholt <eric@anholt.net> | 2010-05-12 14:42:21 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-06-01 15:15:04 -0700 |
commit | 43ad37aa885dc185679dabd605752fe2d782d542 (patch) | |
tree | 514481815b58f895c1f793818c567131f5d6c668 /ir_constant_expression.cpp | |
parent | 65122e9e8038488e8c586eb609e434a90188de27 (diff) |
ir_constant_expression: Handle several floating point unops.
Cleans up a bunch of pointless operations in a GStreamer fragment shader.
Diffstat (limited to 'ir_constant_expression.cpp')
-rw-r--r-- | ir_constant_expression.cpp | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/ir_constant_expression.cpp b/ir_constant_expression.cpp index b1092de139..361a7a1630 100644 --- a/ir_constant_expression.cpp +++ b/ir_constant_expression.cpp @@ -34,6 +34,7 @@ */ #define NULL 0 +#include <math.h> #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; |