[Mesa-dev] [PATCH v2 09/28] glsl/ir: Add builtin function support for doubles
Ian Romanick
idr at freedesktop.org
Thu Feb 5 23:47:58 PST 2015
There's a bunch of tabs that should be replaced with spaces.
Other comments below...
On 02/06/2015 06:56 AM, Ilia Mirkin wrote:
> From: Dave Airlie <airlied at gmail.com>
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
> src/glsl/ir.cpp | 104 ++++++++++++++++++++++++++++++++++++++--
> src/glsl/ir.h | 21 ++++++++
> src/glsl/ir_validate.cpp | 68 +++++++++++++++++++++++---
> src/mesa/program/ir_to_mesa.cpp | 10 ++++
> 4 files changed, 193 insertions(+), 10 deletions(-)
>
> diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
> index fe5601a..055063a 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,
> @@ -280,8 +282,16 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
> 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 +303,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 +319,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 +334,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 +416,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:
> @@ -499,6 +525,12 @@ static const char *const operator_strs[] = {
> "bitcast_u2f",
> "bitcast_f2u",
> "any",
> + "d2f",
> + "f2d",
> + "d2i",
> + "i2d",
> + "d2u",
> + "u2d",
> "trunc",
> "ceil",
> "floor",
> @@ -531,6 +563,10 @@ static const char *const operator_strs[] = {
> "find_msb",
> "find_lsb",
> "sat",
> + "packDouble2x32",
> + "unpackDouble2x32",
> + "frexp_sig",
> + "frexp_exp",
> "noise",
> "interpolate_at_centroid",
> "+",
> @@ -646,6 +682,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)
> {
> @@ -746,9 +795,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 +817,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 +879,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.
> */
> @@ -895,6 +958,24 @@ ir_constant::get_float_component(unsigned i) const
> 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;
> + }
> +
> + /* Must return something to make the compiler happy. This is clearly an
> + * error case.
> + */
> + return 0.0;
> +}
> +
> int
> ir_constant::get_int_component(unsigned i) const
> {
> @@ -984,6 +1065,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 +1083,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 +1142,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 +1205,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 +1246,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(i))
> + return false;
> + break;
> default:
> /* The only other base types are structures, arrays, and samplers.
> * Samplers cannot be constants, and the others should have been
> diff --git a/src/glsl/ir.h b/src/glsl/ir.h
> index a0f48b2..6e7c654 100644
> --- a/src/glsl/ir.h
> +++ b/src/glsl/ir.h
> @@ -1275,6 +1275,13 @@ enum ir_expression_operation {
> ir_unop_bitcast_f2u, /**< Bit-identical float-to-uint "conversion" */
> ir_unop_any,
>
> + 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. */
> +
These should be properly ordered with the other cast operations. Also,
ir_unop_d2b is missing.
> /**
> * \name Unary floating-point rounding operations.
> */
> @@ -1345,6 +1352,17 @@ enum ir_expression_operation {
> /*@}*/
>
> ir_unop_saturate,
Blank line here.
> + /**
> + * \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,
I'm confused about these... what is it?
> +
> ir_unop_noise,
>
> /**
> @@ -2153,6 +2171,7 @@ union ir_constant_data {
> int i[16];
> float f[16];
> bool b[16];
> + double d[16];
> };
>
>
> @@ -2163,6 +2182,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 +2229,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;
> /*@}*/
> diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp
> index 6d56339..25211ee 100644
> --- a/src/glsl/ir_validate.cpp
> +++ b/src/glsl/ir_validate.cpp
> @@ -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,41 @@ 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_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 +530,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 +558,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 +585,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:
> diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
> index f917681..3ae5c0d 100644
> --- a/src/mesa/program/ir_to_mesa.cpp
> +++ b/src/mesa/program/ir_to_mesa.cpp
> @@ -1356,6 +1356,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:
> @@ -1363,11 +1364,20 @@ 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_frexp_sig:
> + case ir_unop_frexp_exp:
> assert(!"not supported");
> break;
> case ir_binop_min:
>
More information about the mesa-dev
mailing list