diff options
author | Matt Turner <[email protected]> | 2013-08-22 13:31:18 -0700 |
---|---|---|
committer | Matt Turner <[email protected]> | 2013-09-17 16:59:05 -0700 |
commit | b2ab840130677bbe7b67de4727fcd91ee6506bb8 (patch) | |
tree | 5160561da43809a9c7df2b2c40c6e6cb73d6fa93 /src/glsl | |
parent | 4b0488ef4e3e4562c8e383282e0d2db183dfc5c1 (diff) |
glsl: Add support for ldexp.
v2: Drop frexp. Rebase on builtins rewrite.
Reviewed-by: Paul Berry <[email protected]>
Diffstat (limited to 'src/glsl')
-rw-r--r-- | src/glsl/builtin_functions.cpp | 14 | ||||
-rw-r--r-- | src/glsl/ir.cpp | 2 | ||||
-rw-r--r-- | src/glsl/ir.h | 7 | ||||
-rw-r--r-- | src/glsl/ir_constant_expression.cpp | 10 | ||||
-rw-r--r-- | src/glsl/ir_validate.cpp | 8 |
5 files changed, 41 insertions, 0 deletions
diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp index 528af0dc65d..ffabf8a8710 100644 --- a/src/glsl/builtin_functions.cpp +++ b/src/glsl/builtin_functions.cpp @@ -510,6 +510,7 @@ private: B1(findLSB) B1(findMSB) B1(fma) + B2(ldexp) #undef B0 #undef B1 #undef B2 @@ -1822,6 +1823,13 @@ builtin_builder::create_builtins() IU(findLSB) IU(findMSB) F(fma) + + add_function("ldexp", + _ldexp(glsl_type::float_type, glsl_type::int_type), + _ldexp(glsl_type::vec2_type, glsl_type::ivec2_type), + _ldexp(glsl_type::vec3_type, glsl_type::ivec3_type), + _ldexp(glsl_type::vec4_type, glsl_type::ivec4_type), + NULL); #undef F #undef FI #undef FIU @@ -3514,6 +3522,12 @@ builtin_builder::_fma(const glsl_type *type) return sig; } + +ir_function_signature * +builtin_builder::_ldexp(const glsl_type *x_type, const glsl_type *exp_type) +{ + return binop(ir_binop_ldexp, gpu_shader5, x_type, x_type, exp_type); +} /** @} */ /******************************************************************************/ diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index 1b1799958ea..a2dca457a95 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -401,6 +401,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) case ir_binop_lshift: case ir_binop_rshift: case ir_binop_bfm: + case ir_binop_ldexp: this->type = op0->type; break; @@ -551,6 +552,7 @@ static const char *const operator_strs[] = { "packHalf2x16_split", "bfm", "ubo_load", + "ldexp", "vector_extract", "fma", "lrp", diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 2637b40e28b..b0e77327711 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -1175,6 +1175,13 @@ enum ir_expression_operation { ir_binop_ubo_load, /** + * \name Multiplies a number by two to a power, part of ARB_gpu_shader5. + */ + /*@{*/ + ir_binop_ldexp, + /*@}*/ + + /** * Extract a scalar from a vector * * operand0 is the vector diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp index a67470bf366..4579ef209da 100644 --- a/src/glsl/ir_constant_expression.cpp +++ b/src/glsl/ir_constant_expression.cpp @@ -394,6 +394,7 @@ ir_expression::constant_expression_value(struct hash_table *variable_context) switch (this->operation) { case ir_binop_lshift: case ir_binop_rshift: + case ir_binop_ldexp: case ir_binop_vector_extract: case ir_triop_csel: case ir_triop_bitfield_extract: @@ -1376,6 +1377,15 @@ ir_expression::constant_expression_value(struct hash_table *variable_context) break; } + case ir_binop_ldexp: + for (unsigned c = 0; c < components; c++) { + data.f[c] = ldexp(op[0]->value.f[c], op[1]->value.i[c]); + /* Flush subnormal values to zero. */ + if (!isnormal(data.f[c])) + data.f[c] = copysign(0.0, op[0]->value.f[c]); + } + break; + case ir_triop_fma: assert(op[0]->type->base_type == GLSL_TYPE_FLOAT); assert(op[1]->type->base_type == GLSL_TYPE_FLOAT); diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp index ae3f09daf43..66a9800ce75 100644 --- a/src/glsl/ir_validate.cpp +++ b/src/glsl/ir_validate.cpp @@ -516,6 +516,14 @@ ir_validate::visit_leave(ir_expression *ir) assert(ir->operands[1]->type == glsl_type::uint_type); break; + case ir_binop_ldexp: + assert(ir->operands[0]->type == ir->type); + assert(ir->operands[0]->type->is_float()); + assert(ir->operands[1]->type->base_type == GLSL_TYPE_INT); + assert(ir->operands[0]->type->components() == + ir->operands[1]->type->components()); + break; + case ir_binop_vector_extract: assert(ir->operands[0]->type->is_vector()); assert(ir->operands[1]->type->is_scalar() |