diff options
author | Dave Airlie <[email protected]> | 2015-02-05 11:50:43 +0200 |
---|---|---|
committer | Ilia Mirkin <[email protected]> | 2015-02-19 00:28:34 -0500 |
commit | 5a69bdb599ee4eb422cba6a47517c376e9dc5faf (patch) | |
tree | 6f2291f609a674c15bda4e09c22cfa39d55222a2 /src/glsl/ir.cpp | |
parent | 53bf7c8fd2e11a6c64d6ff3a98b56d64d2242505 (diff) |
glsl/ir: Add builtin function support for doubles
v2: add d2b, more ir_constant stuff (Ilia)
Signed-off-by: Dave Airlie <[email protected]>
Reviewed-by: Ilia Mirkin <[email protected]>
Diffstat (limited to 'src/glsl/ir.cpp')
-rw-r--r-- | src/glsl/ir.cpp | 111 |
1 files changed, 107 insertions, 4 deletions
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index fe5601a16c7..f4f92e9df95 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -257,6 +257,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) case ir_unop_f2i: case ir_unop_b2i: case ir_unop_u2i: + case ir_unop_d2i: case ir_unop_bitcast_f2i: case ir_unop_bit_count: case ir_unop_find_msb: @@ -268,6 +269,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) case ir_unop_b2f: case ir_unop_i2f: case ir_unop_u2f: + case ir_unop_d2f: case ir_unop_bitcast_i2f: case ir_unop_bitcast_u2f: this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT, @@ -276,12 +278,21 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) case ir_unop_f2b: case ir_unop_i2b: + case ir_unop_d2b: this->type = glsl_type::get_instance(GLSL_TYPE_BOOL, op0->type->vector_elements, 1); break; + case ir_unop_f2d: + case ir_unop_i2d: + case ir_unop_u2d: + this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE, + op0->type->vector_elements, 1); + break; + case ir_unop_i2u: case ir_unop_f2u: + case ir_unop_d2u: case ir_unop_bitcast_f2u: this->type = glsl_type::get_instance(GLSL_TYPE_UINT, op0->type->vector_elements, 1); @@ -293,6 +304,10 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) this->type = glsl_type::float_type; break; + case ir_unop_unpack_double_2x32: + this->type = glsl_type::uvec2_type; + break; + case ir_unop_any: this->type = glsl_type::bool_type; break; @@ -305,6 +320,10 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) this->type = glsl_type::uint_type; break; + case ir_unop_pack_double_2x32: + this->type = glsl_type::double_type; + break; + case ir_unop_unpack_snorm_2x16: case ir_unop_unpack_unorm_2x16: case ir_unop_unpack_half_2x16: @@ -316,6 +335,14 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) this->type = glsl_type::vec4_type; break; + case ir_unop_frexp_sig: + this->type = op0->type; + break; + case ir_unop_frexp_exp: + this->type = glsl_type::get_instance(GLSL_TYPE_INT, + op0->type->vector_elements, 1); + break; + default: assert(!"not reached: missing automatic type setup for ir_expression"); this->type = op0->type; @@ -390,7 +417,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) break; case ir_binop_dot: - this->type = glsl_type::float_type; + this->type = op0->type->get_base_type(); break; case ir_binop_pack_half_2x16_split: @@ -494,6 +521,13 @@ static const char *const operator_strs[] = { "u2f", "i2u", "u2i", + "d2f", + "f2d", + "d2i", + "i2d", + "d2u", + "u2d", + "d2b", "bitcast_i2f", "bitcast_f2i", "bitcast_u2f", @@ -531,6 +565,10 @@ static const char *const operator_strs[] = { "find_msb", "find_lsb", "sat", + "packDouble2x32", + "unpackDouble2x32", + "frexp_sig", + "frexp_exp", "noise", "interpolate_at_centroid", "+", @@ -646,6 +684,19 @@ ir_constant::ir_constant(float f, unsigned vector_elements) } } +ir_constant::ir_constant(double d, unsigned vector_elements) + : ir_rvalue(ir_type_constant) +{ + assert(vector_elements <= 4); + this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE, vector_elements, 1); + for (unsigned i = 0; i < vector_elements; i++) { + this->value.d[i] = d; + } + for (unsigned i = vector_elements; i < 16; i++) { + this->value.d[i] = 0.0; + } +} + ir_constant::ir_constant(unsigned int u, unsigned vector_elements) : ir_rvalue(ir_type_constant) { @@ -695,6 +746,7 @@ ir_constant::ir_constant(const ir_constant *c, unsigned i) case GLSL_TYPE_INT: this->value.i[0] = c->value.i[i]; break; case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break; case GLSL_TYPE_BOOL: this->value.b[0] = c->value.b[i]; break; + case GLSL_TYPE_DOUBLE: this->value.d[0] = c->value.d[i]; break; default: assert(!"Should not get here."); break; } } @@ -746,9 +798,16 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) if (value->type->is_scalar() && value->next->is_tail_sentinel()) { if (type->is_matrix()) { /* Matrix - fill diagonal (rest is already set to 0) */ - assert(type->base_type == GLSL_TYPE_FLOAT); - for (unsigned i = 0; i < type->matrix_columns; i++) - this->value.f[i * type->vector_elements + i] = value->value.f[0]; + assert(type->base_type == GLSL_TYPE_FLOAT || + type->base_type == GLSL_TYPE_DOUBLE); + for (unsigned i = 0; i < type->matrix_columns; i++) { + if (type->base_type == GLSL_TYPE_FLOAT) + this->value.f[i * type->vector_elements + i] = + value->value.f[0]; + else + this->value.d[i * type->vector_elements + i] = + value->value.d[0]; + } } else { /* Vector or scalar - fill all components */ switch (type->base_type) { @@ -761,6 +820,10 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) for (unsigned i = 0; i < type->components(); i++) this->value.f[i] = value->value.f[0]; break; + case GLSL_TYPE_DOUBLE: + for (unsigned i = 0; i < type->components(); i++) + this->value.d[i] = value->value.d[0]; + break; case GLSL_TYPE_BOOL: for (unsigned i = 0; i < type->components(); i++) this->value.b[i] = value->value.b[0]; @@ -819,6 +882,9 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) case GLSL_TYPE_BOOL: this->value.b[i] = value->get_bool_component(j); break; + case GLSL_TYPE_DOUBLE: + this->value.d[i] = value->get_double_component(j); + break; default: /* FINISHME: What to do? Exceptions are not the answer. */ @@ -869,6 +935,7 @@ ir_constant::get_bool_component(unsigned i) const case GLSL_TYPE_INT: return this->value.i[i] != 0; case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0; case GLSL_TYPE_BOOL: return this->value.b[i]; + case GLSL_TYPE_DOUBLE: return this->value.d[i] != 0.0; default: assert(!"Should not get here."); break; } @@ -886,6 +953,25 @@ ir_constant::get_float_component(unsigned i) const case GLSL_TYPE_INT: return (float) this->value.i[i]; case GLSL_TYPE_FLOAT: return this->value.f[i]; case GLSL_TYPE_BOOL: return this->value.b[i] ? 1.0f : 0.0f; + case GLSL_TYPE_DOUBLE: return (float) this->value.d[i]; + default: assert(!"Should not get here."); break; + } + + /* Must return something to make the compiler happy. This is clearly an + * error case. + */ + return 0.0; +} + +double +ir_constant::get_double_component(unsigned i) const +{ + switch (this->type->base_type) { + case GLSL_TYPE_UINT: return (double) this->value.u[i]; + case GLSL_TYPE_INT: return (double) this->value.i[i]; + case GLSL_TYPE_FLOAT: return (double) this->value.f[i]; + case GLSL_TYPE_BOOL: return this->value.b[i] ? 1.0 : 0.0; + case GLSL_TYPE_DOUBLE: return this->value.d[i]; default: assert(!"Should not get here."); break; } @@ -903,6 +989,7 @@ ir_constant::get_int_component(unsigned i) const case GLSL_TYPE_INT: return this->value.i[i]; case GLSL_TYPE_FLOAT: return (int) this->value.f[i]; case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; + case GLSL_TYPE_DOUBLE: return (int) this->value.d[i]; default: assert(!"Should not get here."); break; } @@ -920,6 +1007,7 @@ ir_constant::get_uint_component(unsigned i) const case GLSL_TYPE_INT: return this->value.i[i]; case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i]; case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; + case GLSL_TYPE_DOUBLE: return (unsigned) this->value.d[i]; default: assert(!"Should not get here."); break; } @@ -984,6 +1072,7 @@ ir_constant::copy_offset(ir_constant *src, int offset) case GLSL_TYPE_UINT: case GLSL_TYPE_INT: case GLSL_TYPE_FLOAT: + case GLSL_TYPE_DOUBLE: case GLSL_TYPE_BOOL: { unsigned int size = src->type->components(); assert (size <= this->type->components() - offset); @@ -1001,6 +1090,9 @@ ir_constant::copy_offset(ir_constant *src, int offset) case GLSL_TYPE_BOOL: value.b[i+offset] = src->get_bool_component(i); break; + case GLSL_TYPE_DOUBLE: + value.d[i+offset] = src->get_double_component(i); + break; default: // Shut up the compiler break; } @@ -1057,6 +1149,9 @@ ir_constant::copy_masked_offset(ir_constant *src, int offset, unsigned int mask) case GLSL_TYPE_BOOL: value.b[i+offset] = src->get_bool_component(id++); break; + case GLSL_TYPE_DOUBLE: + value.d[i+offset] = src->get_double_component(id++); + break; default: assert(!"Should not get here."); return; @@ -1117,6 +1212,10 @@ ir_constant::has_value(const ir_constant *c) const if (this->value.b[i] != c->value.b[i]) return false; break; + case GLSL_TYPE_DOUBLE: + if (this->value.d[i] != c->value.d[i]) + return false; + break; default: assert(!"Should not get here."); return false; @@ -1154,6 +1253,10 @@ ir_constant::is_value(float f, int i) const if (this->value.b[c] != bool(i)) return false; break; + case GLSL_TYPE_DOUBLE: + if (this->value.d[c] != double(f)) + return false; + break; default: /* The only other base types are structures, arrays, and samplers. * Samplers cannot be constants, and the others should have been |