summaryrefslogtreecommitdiffstats
path: root/src/glsl/ir.cpp
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2015-02-05 11:50:43 +0200
committerIlia Mirkin <[email protected]>2015-02-19 00:28:34 -0500
commit5a69bdb599ee4eb422cba6a47517c376e9dc5faf (patch)
tree6f2291f609a674c15bda4e09c22cfa39d55222a2 /src/glsl/ir.cpp
parent53bf7c8fd2e11a6c64d6ff3a98b56d64d2242505 (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.cpp111
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