summaryrefslogtreecommitdiff
path: root/ir_constant_expression.cpp
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-05-12 14:42:21 -0700
committerEric Anholt <eric@anholt.net>2010-06-01 15:15:04 -0700
commit43ad37aa885dc185679dabd605752fe2d782d542 (patch)
tree514481815b58f895c1f793818c567131f5d6c668 /ir_constant_expression.cpp
parent65122e9e8038488e8c586eb609e434a90188de27 (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.cpp97
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;