glsl/ir: Add builtin function support for doubles

v2: add d2b, more ir_constant stuff (Ilia)

Signed-off-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
Dave Airlie 2015-02-05 11:50:43 +02:00 committed by Ilia Mirkin
parent 53bf7c8fd2
commit 5a69bdb599
4 changed files with 206 additions and 10 deletions

View file

@ -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

View file

@ -1269,6 +1269,13 @@ enum ir_expression_operation {
ir_unop_u2f, /**< Unsigned-to-float conversion. */
ir_unop_i2u, /**< Integer-to-unsigned conversion. */
ir_unop_u2i, /**< Unsigned-to-integer conversion. */
ir_unop_d2f, /**< Double-to-float conversion. */
ir_unop_f2d, /**< Float-to-double conversion. */
ir_unop_d2i, /**< Double-to-integer conversion. */
ir_unop_i2d, /**< Integer-to-double conversion. */
ir_unop_d2u, /**< Double-to-unsigned conversion. */
ir_unop_u2d, /**< Unsigned-to-double conversion. */
ir_unop_d2b, /**< Double-to-boolean conversion. */
ir_unop_bitcast_i2f, /**< Bit-identical int-to-float "conversion" */
ir_unop_bitcast_f2i, /**< Bit-identical float-to-int "conversion" */
ir_unop_bitcast_u2f, /**< Bit-identical uint-to-float "conversion" */
@ -1345,6 +1352,18 @@ enum ir_expression_operation {
/*@}*/
ir_unop_saturate,
/**
* \name Double packing, part of ARB_gpu_shader_fp64.
*/
/*@{*/
ir_unop_pack_double_2x32,
ir_unop_unpack_double_2x32,
/*@}*/
ir_unop_frexp_sig,
ir_unop_frexp_exp,
ir_unop_noise,
/**
@ -2153,6 +2172,7 @@ union ir_constant_data {
int i[16];
float f[16];
bool b[16];
double d[16];
};
@ -2163,6 +2183,7 @@ public:
ir_constant(unsigned int u, unsigned vector_elements=1);
ir_constant(int i, unsigned vector_elements=1);
ir_constant(float f, unsigned vector_elements=1);
ir_constant(double d, unsigned vector_elements=1);
/**
* Construct an ir_constant from a list of ir_constant values
@ -2209,6 +2230,7 @@ public:
/*@{*/
bool get_bool_component(unsigned i) const;
float get_float_component(unsigned i) const;
double get_double_component(unsigned i) const;
int get_int_component(unsigned i) const;
unsigned get_uint_component(unsigned i) const;
/*@}*/

View file

@ -313,6 +313,10 @@ ir_validate::visit_leave(ir_expression *ir)
case ir_unop_ceil:
case ir_unop_floor:
case ir_unop_fract:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT ||
ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE);
assert(ir->operands[0]->type == ir->type);
break;
case ir_unop_sin:
case ir_unop_cos:
case ir_unop_sin_reduced:
@ -340,6 +344,11 @@ ir_validate::visit_leave(ir_expression *ir)
assert(ir->operands[0]->type == glsl_type::vec4_type);
break;
case ir_unop_pack_double_2x32:
assert(ir->type == glsl_type::double_type);
assert(ir->operands[0]->type == glsl_type::uvec2_type);
break;
case ir_unop_unpack_snorm_2x16:
case ir_unop_unpack_unorm_2x16:
case ir_unop_unpack_half_2x16:
@ -359,6 +368,11 @@ ir_validate::visit_leave(ir_expression *ir)
assert(ir->operands[0]->type == glsl_type::uint_type);
break;
case ir_unop_unpack_double_2x32:
assert(ir->type == glsl_type::uvec2_type);
assert(ir->operands[0]->type == glsl_type::double_type);
break;
case ir_unop_bitfield_reverse:
assert(ir->operands[0]->type == ir->type);
assert(ir->type->is_integer());
@ -381,6 +395,45 @@ ir_validate::visit_leave(ir_expression *ir)
assert(ir->operands[0]->type->is_float());
break;
case ir_unop_d2f:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE);
assert(ir->type->base_type == GLSL_TYPE_FLOAT);
break;
case ir_unop_f2d:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
assert(ir->type->base_type == GLSL_TYPE_DOUBLE);
break;
case ir_unop_d2i:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE);
assert(ir->type->base_type == GLSL_TYPE_INT);
break;
case ir_unop_i2d:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
assert(ir->type->base_type == GLSL_TYPE_DOUBLE);
break;
case ir_unop_d2u:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE);
assert(ir->type->base_type == GLSL_TYPE_UINT);
break;
case ir_unop_u2d:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
assert(ir->type->base_type == GLSL_TYPE_DOUBLE);
break;
case ir_unop_d2b:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE);
assert(ir->type->base_type == GLSL_TYPE_BOOL);
break;
case ir_unop_frexp_sig:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT ||
ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE);
assert(ir->type->base_type == GLSL_TYPE_DOUBLE);
break;
case ir_unop_frexp_exp:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT ||
ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE);
assert(ir->type->base_type == GLSL_TYPE_INT);
break;
case ir_binop_add:
case ir_binop_sub:
case ir_binop_mul:
@ -481,8 +534,10 @@ ir_validate::visit_leave(ir_expression *ir)
break;
case ir_binop_dot:
assert(ir->type == glsl_type::float_type);
assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
assert(ir->type == glsl_type::float_type ||
ir->type == glsl_type::double_type);
assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT ||
ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE);
assert(ir->operands[0]->type->is_vector());
assert(ir->operands[0]->type == ir->operands[1]->type);
break;
@ -507,7 +562,8 @@ ir_validate::visit_leave(ir_expression *ir)
case ir_binop_ldexp:
assert(ir->operands[0]->type == ir->type);
assert(ir->operands[0]->type->is_float());
assert(ir->operands[0]->type->is_float() ||
ir->operands[0]->type->is_double());
assert(ir->operands[1]->type->base_type == GLSL_TYPE_INT);
assert(ir->operands[0]->type->components() ==
ir->operands[1]->type->components());
@ -533,16 +589,20 @@ ir_validate::visit_leave(ir_expression *ir)
break;
case ir_triop_fma:
assert(ir->type->base_type == GLSL_TYPE_FLOAT);
assert(ir->type->base_type == GLSL_TYPE_FLOAT ||
ir->type->base_type == GLSL_TYPE_DOUBLE);
assert(ir->type == ir->operands[0]->type);
assert(ir->type == ir->operands[1]->type);
assert(ir->type == ir->operands[2]->type);
break;
case ir_triop_lrp:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT ||
ir->operands[0]->type->base_type == GLSL_TYPE_DOUBLE);
assert(ir->operands[0]->type == ir->operands[1]->type);
assert(ir->operands[2]->type == ir->operands[0]->type || ir->operands[2]->type == glsl_type::float_type);
assert(ir->operands[2]->type == ir->operands[0]->type ||
ir->operands[2]->type == glsl_type::float_type ||
ir->operands[2]->type == glsl_type::double_type);
break;
case ir_triop_csel:

View file

@ -1362,6 +1362,7 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
case ir_unop_pack_unorm_2x16:
case ir_unop_pack_unorm_4x8:
case ir_unop_pack_half_2x16:
case ir_unop_pack_double_2x32:
case ir_unop_unpack_snorm_2x16:
case ir_unop_unpack_snorm_4x8:
case ir_unop_unpack_unorm_2x16:
@ -1369,11 +1370,21 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
case ir_unop_unpack_half_2x16:
case ir_unop_unpack_half_2x16_split_x:
case ir_unop_unpack_half_2x16_split_y:
case ir_unop_unpack_double_2x32:
case ir_binop_pack_half_2x16_split:
case ir_unop_bitfield_reverse:
case ir_unop_bit_count:
case ir_unop_find_msb:
case ir_unop_find_lsb:
case ir_unop_d2f:
case ir_unop_f2d:
case ir_unop_d2i:
case ir_unop_i2d:
case ir_unop_d2u:
case ir_unop_u2d:
case ir_unop_d2b:
case ir_unop_frexp_sig:
case ir_unop_frexp_exp:
assert(!"not supported");
break;
case ir_binop_min: